2022-04-15 14:24:30 +00:00
|
|
|
/* eslint camelcase: ["error", {properties: "never"}] */
|
|
|
|
import { union, difference, take, orderBy } from 'lodash'
|
|
|
|
|
|
|
|
import stub from '@/stubs/album'
|
|
|
|
import { artistStore } from '.'
|
|
|
|
import { http } from '@/services'
|
2022-04-20 09:37:22 +00:00
|
|
|
import { arrayify, use } from '@/utils'
|
2022-04-15 14:24:30 +00:00
|
|
|
|
|
|
|
const UNKNOWN_ALBUM_ID = 1
|
|
|
|
|
|
|
|
export const albumStore = {
|
|
|
|
stub,
|
|
|
|
cache: {} as { [key: string]: Album },
|
|
|
|
|
|
|
|
state: {
|
|
|
|
albums: [stub]
|
|
|
|
},
|
|
|
|
|
|
|
|
init (albums: Album[]) {
|
|
|
|
// Traverse through the artists array and add their albums into our master album list.
|
|
|
|
this.all = albums
|
|
|
|
this.all.forEach(album => this.setupAlbum(album))
|
|
|
|
},
|
|
|
|
|
|
|
|
setupAlbum (album: Album): void {
|
|
|
|
const artist = artistStore.byId(album.artist_id)!
|
|
|
|
artist.albums = union(artist.albums, [album])
|
|
|
|
|
|
|
|
album.artist = artist
|
|
|
|
album.info = null
|
|
|
|
album.songs = []
|
|
|
|
album.playCount = 0
|
|
|
|
|
|
|
|
this.cache[album.id] = album
|
|
|
|
},
|
|
|
|
|
|
|
|
get all () {
|
|
|
|
return this.state.albums
|
|
|
|
},
|
|
|
|
|
|
|
|
set all (value) {
|
|
|
|
this.state.albums = value
|
|
|
|
},
|
|
|
|
|
|
|
|
byId (id: number): Album | undefined {
|
|
|
|
return this.cache[id]
|
|
|
|
},
|
|
|
|
|
|
|
|
byIds (ids: number[]): Album[] {
|
|
|
|
const albums = [] as Album[]
|
|
|
|
ids.forEach(id => use(this.byId(id), album => albums.push(album!)))
|
|
|
|
return albums
|
|
|
|
},
|
|
|
|
|
|
|
|
add (albums: Album | Album[]): void {
|
2022-04-20 09:37:22 +00:00
|
|
|
arrayify(albums).forEach(album => {
|
2022-04-15 14:24:30 +00:00
|
|
|
this.setupAlbum(album)
|
|
|
|
album.playCount = album.songs.reduce((count, song) => count + song.playCount, 0)
|
|
|
|
this.all.push(album)
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
purify (): void {
|
|
|
|
this.compact()
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove empty albums from the store.
|
|
|
|
*/
|
|
|
|
compact (): void {
|
|
|
|
const emptyAlbums = this.all.filter(album => album.songs.length === 0)
|
|
|
|
if (!emptyAlbums.length) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
this.all = difference(this.all, emptyAlbums)
|
|
|
|
emptyAlbums.forEach(album => delete this.cache[album.id])
|
|
|
|
},
|
|
|
|
|
|
|
|
getMostPlayed (n: number = 6): Album[] {
|
|
|
|
// Only non-unknown albums with actual play count are applicable.
|
|
|
|
const applicable = this.all.filter(album => album.playCount && album.id !== 1)
|
|
|
|
return take(orderBy(applicable, 'playCount', 'desc'), n)
|
|
|
|
},
|
|
|
|
|
|
|
|
getRecentlyAdded (n: number = 6): Album[] {
|
|
|
|
const applicable = this.all.filter(album => album.id !== 1)
|
|
|
|
return take(orderBy(applicable, 'created_at', 'desc'), n)
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Upload a cover for an album.
|
|
|
|
*
|
|
|
|
* @param {Album} album The album object
|
|
|
|
* @param {string} cover The content data string of the cover
|
|
|
|
*/
|
|
|
|
uploadCover: async (album: Album, cover: string): Promise<string> => {
|
|
|
|
const { coverUrl } = await http.put<{ coverUrl: string }>(`album/${album.id}/cover`, { cover })
|
|
|
|
album.cover = coverUrl
|
|
|
|
return album.cover
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the (blurry) thumbnail-sized version of an album's cover.
|
|
|
|
*/
|
|
|
|
getThumbnail: async (album: Album): Promise<string | null> => {
|
|
|
|
if (album.thumbnail === undefined) {
|
|
|
|
const { thumbnailUrl } = await http.get<{ thumbnailUrl: string }>(`album/${album.id}/thumbnail`)
|
|
|
|
|
|
|
|
album.thumbnail = thumbnailUrl
|
|
|
|
}
|
|
|
|
|
|
|
|
return album.thumbnail
|
|
|
|
},
|
|
|
|
|
|
|
|
isUnknownAlbum: (album: Album) => album.id === UNKNOWN_ALBUM_ID
|
|
|
|
}
|