normalize responses and add types
This commit is contained in:
parent
b8db546f64
commit
8fb1f8db78
@ -14,6 +14,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import AlbumList from '@/library/album/AlbumList.vue'
|
||||
import { Album } from '@/shared/api'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -22,10 +23,10 @@
|
||||
data() {
|
||||
return {
|
||||
loading: true as boolean,
|
||||
recent: [],
|
||||
newest: [],
|
||||
frequent: [],
|
||||
random: [],
|
||||
recent: [] as Album[],
|
||||
newest: [] as Album[],
|
||||
frequent: [] as Album[],
|
||||
random: [] as Album[],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<TrackList :tracks="album.song" />
|
||||
<TrackList :tracks="album.tracks" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -29,6 +29,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import TrackList from '@/library/TrackList.vue'
|
||||
import { Album } from '@/shared/api'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -39,7 +40,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
album: null,
|
||||
album: null as null | Album,
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -8,7 +8,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import AlbumList from './AlbumList.vue'
|
||||
import { AlbumSort } from '@/shared/api'
|
||||
import { AlbumSort, Album } from '@/shared/api'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -17,7 +17,7 @@
|
||||
data() {
|
||||
return {
|
||||
sort: 'newest',
|
||||
albums: null,
|
||||
albums: null as null | Album[],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -4,6 +4,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import ArtistList from './ArtistList.vue'
|
||||
import { Artist } from '@/shared/api'
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -11,7 +12,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
items: [] as Artist[]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -3,6 +3,50 @@ import { AuthService } from '@/auth/service'
|
||||
|
||||
export type AlbumSort = 'alphabeticalByName' | 'newest' | 'recent' | 'frequent' | 'random'
|
||||
|
||||
export interface Album {
|
||||
id: string
|
||||
name: string
|
||||
artist: string
|
||||
artistId: string
|
||||
year: number
|
||||
starred: boolean
|
||||
image?: string
|
||||
tracks?: Track[]
|
||||
}
|
||||
|
||||
export interface Artist {
|
||||
id: string
|
||||
name: string
|
||||
albumCount: number
|
||||
description?: string
|
||||
starred: boolean
|
||||
image?: string
|
||||
lastFmUrl?: string
|
||||
musicBrainzUrl?: string
|
||||
similarArtist?: Artist[]
|
||||
albums?: Album[]
|
||||
}
|
||||
|
||||
export interface Track {
|
||||
id: string
|
||||
title: string
|
||||
duration: number
|
||||
starred: boolean
|
||||
image?: string
|
||||
url?: string
|
||||
track?: number
|
||||
album?: string
|
||||
albumId?: string
|
||||
artist?: string
|
||||
artistId?: string
|
||||
}
|
||||
|
||||
export interface SearchResult {
|
||||
artists: Artist[]
|
||||
albums: Album[]
|
||||
tracks: Track[]
|
||||
}
|
||||
|
||||
export class API {
|
||||
readonly http: AxiosInstance;
|
||||
readonly get: (path: string, params?: any) => Promise<any>;
|
||||
@ -67,70 +111,41 @@ export class API {
|
||||
const response = await this.get('rest/getSongsByGenre', params)
|
||||
return {
|
||||
name: id,
|
||||
tracks: this.normalizeTrackList(response.songsByGenre?.song || []),
|
||||
tracks: (response.songsByGenre?.song || []).map(this.normalizeTrack, this),
|
||||
}
|
||||
}
|
||||
|
||||
async getArtists() {
|
||||
async getArtists(): Promise<Artist[]> {
|
||||
const response = await this.get('rest/getArtists')
|
||||
return (response.artists?.index || []).flatMap((index: any) => index.artist.map((artist: any) => ({
|
||||
id: artist.id,
|
||||
name: artist.name,
|
||||
...artist
|
||||
})))
|
||||
return (response.artists?.index || [])
|
||||
.flatMap((index: any) => index.artist)
|
||||
.map(this.normalizeArtist, this)
|
||||
}
|
||||
|
||||
async getAlbums(sort: AlbumSort, size = 500) {
|
||||
async getAlbums(sort: AlbumSort, size = 500): Promise<Album[]> {
|
||||
const params = {
|
||||
type: sort,
|
||||
offset: '0',
|
||||
size: size,
|
||||
}
|
||||
const response = await this.get('rest/getAlbumList2', params)
|
||||
return (response.albumList2?.album || []).map((item: any) => ({
|
||||
...item,
|
||||
image: item.coverArt ? this.getCoverArtUrl(item) : undefined,
|
||||
}))
|
||||
const albums = response.albumList2?.album || []
|
||||
return albums.map(this.normalizeAlbum, this)
|
||||
}
|
||||
|
||||
async getArtistDetails(id: string) {
|
||||
async getArtistDetails(id: string): Promise<Artist> {
|
||||
const params = { id }
|
||||
const [info1, info2] = await Promise.all([
|
||||
this.get('rest/getArtist', params).then(r => r.artist),
|
||||
this.get('rest/getArtistInfo2', params).then(r => r.artistInfo2),
|
||||
])
|
||||
return {
|
||||
id: info1.id,
|
||||
name: info1.name,
|
||||
description: (info2.biography || '').replace(/<a[^>]*>.*?<\/a>/gm, ''),
|
||||
image: info2.largeImageUrl || info2.mediumImageUrl || info2.smallImageUrl,
|
||||
lastFmUrl: info2.lastFmUrl,
|
||||
musicBrainzUrl: info2.musicBrainzId
|
||||
? `https://musicbrainz.org/artist/${info2.musicBrainzId}` : null,
|
||||
albums: info1.album.map((album: any) => this.normalizeAlbum(album)),
|
||||
similarArtist: (info2.similarArtist || []).map((artist: any) => ({
|
||||
id: artist.id,
|
||||
name: artist.name,
|
||||
...artist
|
||||
}))
|
||||
}
|
||||
return this.normalizeArtist({ ...info1, ...info2 })
|
||||
}
|
||||
|
||||
async getAlbumDetails(id: string) {
|
||||
async getAlbumDetails(id: string): Promise<Album> {
|
||||
const params = { id }
|
||||
const data = await this.get('rest/getAlbum', params)
|
||||
const item = data.album
|
||||
const image = this.getCoverArtUrl(item)
|
||||
const trackList = item.song.map((s: any) => ({
|
||||
...s,
|
||||
image,
|
||||
url: this.getStreamUrl(s.id),
|
||||
}))
|
||||
return {
|
||||
...item,
|
||||
image,
|
||||
song: trackList,
|
||||
}
|
||||
return this.normalizeAlbum(data.album)
|
||||
}
|
||||
|
||||
async getPlaylists() {
|
||||
@ -154,7 +169,7 @@ export class API {
|
||||
return {
|
||||
...response.playlist,
|
||||
name: response.playlist.name || '(Unnamed)',
|
||||
tracks: this.normalizeTrackList(response.playlist.entry || []),
|
||||
tracks: (response.playlist.entry || []).map(this.normalizeTrack, this),
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,12 +198,12 @@ export class API {
|
||||
await this.get('rest/updatePlaylist', params)
|
||||
}
|
||||
|
||||
async getRandomSongs() {
|
||||
async getRandomSongs(): Promise<Track[]> {
|
||||
const params = {
|
||||
size: 200,
|
||||
}
|
||||
const response = await this.get('rest/getRandomSongs', params)
|
||||
return this.normalizeTrackList(response.randomSongs?.song || [])
|
||||
return (response.randomSongs?.song || []).map(this.normalizeTrack, this)
|
||||
}
|
||||
|
||||
async getStarred() {
|
||||
@ -196,7 +211,7 @@ export class API {
|
||||
return {
|
||||
albums: (response.starred2?.album || []).map(this.normalizeAlbum, this),
|
||||
artists: (response.starred2?.artist || []).map(this.normalizeArtist, this),
|
||||
tracks: this.normalizeTrackList(response.starred2?.song || [])
|
||||
tracks: (response.starred2?.song || []).map(this.normalizeTrack, this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,37 +233,61 @@ export class API {
|
||||
await this.get('rest/unstar', params)
|
||||
}
|
||||
|
||||
async search(query: string) {
|
||||
async search(query: string): Promise<SearchResult> {
|
||||
const params = {
|
||||
query,
|
||||
}
|
||||
const data = await this.get('rest/search3', params)
|
||||
return {
|
||||
tracks: this.normalizeTrackList(data.searchResult3.song || []),
|
||||
albums: (data.searchResult3.album || []).map((x: any) => this.normalizeAlbum(x)),
|
||||
artists: (data.searchResult3.artist || []).map((x: any) => this.normalizeArtist(x)),
|
||||
tracks: (data.searchResult3.song || []).map(this.normalizeTrack, this),
|
||||
albums: (data.searchResult3.album || []).map(this.normalizeAlbum, this),
|
||||
artists: (data.searchResult3.artist || []).map(this.normalizeArtist, this),
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeTrackList(items: any[]) {
|
||||
return items.map(item => ({
|
||||
...item,
|
||||
private normalizeTrack(item: any): Track {
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
duration: item.duration,
|
||||
starred: !!item.starred,
|
||||
track: item.track,
|
||||
album: item.album,
|
||||
albumId: item.albumId,
|
||||
artist: item.artist,
|
||||
artistId: item.artistId,
|
||||
url: this.getStreamUrl(item.id),
|
||||
image: this.getCoverArtUrl(item),
|
||||
}))
|
||||
}
|
||||
|
||||
private normalizeAlbum(item: any) {
|
||||
return {
|
||||
...item,
|
||||
image: this.getCoverArtUrl(item)
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeArtist(item: any) {
|
||||
private normalizeAlbum(item: any): Album {
|
||||
return {
|
||||
...item,
|
||||
image: this.getCoverArtUrl(item)
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
artist: item.artist,
|
||||
artistId: item.artistId,
|
||||
image: this.getCoverArtUrl(item),
|
||||
year: item.year || 0,
|
||||
starred: !!item.starred,
|
||||
tracks: (item.song || []).map(this.normalizeTrack, this)
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeArtist(item: any): Artist {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
description: (item.biography || '').replace(/<a[^>]*>.*?<\/a>/gm, ''),
|
||||
starred: !!item.starred,
|
||||
image: item.largeImageUrl || item.mediumImageUrl || item.smallImageUrl,
|
||||
albumCount: item.albumCount,
|
||||
lastFmUrl: item.lastFmUrl,
|
||||
musicBrainzUrl: item.musicBrainzId
|
||||
? `https://musicbrainz.org/artist/${item.musicBrainzId}`
|
||||
: undefined,
|
||||
albums: item.album?.map(this.normalizeAlbum, this),
|
||||
similarArtist: (item.similarArtist || []).map(this.normalizeArtist, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user