koel/resources/assets/js/stores/artistStore.ts

109 lines
2.7 KiB
TypeScript
Raw Normal View History

2022-04-21 09:38:24 +00:00
import { difference, orderBy, take } from 'lodash'
2022-04-15 14:24:30 +00:00
2022-04-24 08:50:45 +00:00
import { httpService } from '@/services'
2022-04-15 14:24:30 +00:00
import stub from '@/stubs/artist'
2022-04-20 09:37:22 +00:00
import { arrayify, use } from '@/utils'
2022-04-21 09:38:24 +00:00
import { reactive } from 'vue'
interface ArtistStoreState {
artists: Artist[]
}
2022-04-15 14:24:30 +00:00
const UNKNOWN_ARTIST_ID = 1
const VARIOUS_ARTISTS_ID = 2
export const artistStore = {
stub,
2022-04-21 09:38:24 +00:00
cache: {} as Record<number, Artist>,
2022-04-15 14:24:30 +00:00
2022-04-21 09:38:24 +00:00
state: reactive<ArtistStoreState>({
artists: []
}),
2022-04-15 14:24:30 +00:00
2022-04-21 09:38:24 +00:00
init (artists: Artist[]) {
2022-04-15 14:24:30 +00:00
this.all = artists
// Traverse through artists array to get the cover and number of songs for each.
this.all.forEach(artist => this.setupArtist(artist))
},
2022-04-21 09:38:24 +00:00
setupArtist (artist: Artist) {
2022-04-28 09:00:20 +00:00
artist.info = artist.info || null
artist.albums = artist.albums || []
artist.songs = artist.songs || []
artist.playCount = artist.songs.reduce((count, song) => count + song.playCount, 0)
2022-04-15 14:24:30 +00:00
this.cache[artist.id] = artist
2022-04-28 09:00:20 +00:00
return artist
2022-04-15 14:24:30 +00:00
},
2022-04-28 09:00:20 +00:00
get all () {
2022-04-15 14:24:30 +00:00
return this.state.artists
},
set all (value: Artist[]) {
this.state.artists = value
},
byId (id: number): Artist | undefined {
return this.cache[id]
},
2022-04-21 09:38:24 +00:00
byIds (ids: number[]) {
2022-04-15 14:24:30 +00:00
const artists = [] as Artist[]
ids.forEach(id => use(this.byId(id), artist => artists.push(artist!)))
return artists
},
add (artists: Artist | Artist[]) {
2022-04-28 09:00:20 +00:00
arrayify(artists).forEach(artist => this.all.push(this.setupArtist(artist)))
},
prepend (artists: Artist | Artist[]) {
arrayify(artists).forEach(artist => this.all.unshift(this.setupArtist(artist)))
2022-04-15 14:24:30 +00:00
},
/**
* Remove empty artists from the store.
*/
2022-04-21 09:38:24 +00:00
compact () {
2022-04-15 14:24:30 +00:00
const emptyArtists = this.all.filter(artist => artist.songs.length === 0)
if (!emptyArtists.length) {
return
}
this.all = difference(this.all, emptyArtists)
emptyArtists.forEach(artist => delete this.cache[artist.id])
},
isVariousArtists: (artist: Artist) => artist.id === VARIOUS_ARTISTS_ID,
isUnknownArtist: (artist: Artist) => artist.id === UNKNOWN_ARTIST_ID,
2022-04-21 09:38:24 +00:00
getMostPlayed (count = 6): Artist[] {
2022-04-15 14:24:30 +00:00
// Only non-unknown artists with actual play count are applicable.
// Also, "Various Artists" doesn't count.
const applicable = this.all.filter(artist => {
return artist.playCount &&
!this.isUnknownArtist(artist) &&
!this.isVariousArtists(artist)
})
2022-04-21 09:38:24 +00:00
return take(orderBy(applicable, 'playCount', 'desc'), count)
2022-04-15 14:24:30 +00:00
},
/**
* Upload an image for an artist.
*
* @param {Artist} artist The artist object
* @param {string} image The content data string of the image
*/
2022-04-21 09:38:24 +00:00
uploadImage: async (artist: Artist, image: string) => {
2022-04-24 08:50:45 +00:00
const { imageUrl } = await httpService.put<{ imageUrl: string }>(`artist/${artist.id}/image`, { image })
2022-04-15 14:24:30 +00:00
artist.image = imageUrl
return artist.image
}
}