import { ref, computed, watch } from 'vue' import { groupBy, orderBy } from 'lodash-es' import type { Artist, Album, Track } from '../types' import { useSubsonicApi } from '../subsonicApi' import { useMainStore } from '../store/main' import { useFavouriteStore } from '../store/favourite' import { useRadioStore } from '../store/radio' import { usePlayerStore } from '../store/player' import { ArtistList } from '../components/ArtistList.vine' import { AlbumList } from '../components/AlbumList.vine' import { TrackList } from '../components/TrackList.vine' export const ArtistView = ({ id = null, tracksView = false }: { id?: string | null, tracksView?: boolean }) => { let generator: AsyncGenerator | null = null const subsonicApi = useSubsonicApi(), mainStore = useMainStore(), favouriteStore = useFavouriteStore(), playerStore = usePlayerStore(), radioStore = useRadioStore(), hasMore = ref(false), isFavourite = ref(false), sort = ref('albums'), artists = ref([]), artist = ref(), albums = ref<{ releaseType: string, albums: Album[] }[]>(), tracks = ref([]), toggleAlbumSortOrder = () => mainStore.toggleArtistAlbumSortOrder(), toggleFavourite = () => { if (!id) return favouriteStore.toggle('artist', id) isFavourite.value = favouriteStore.get('artist', id) }, playNow = () => (!!artist.value?.topTracks && playerStore.playNow(artist.value.topTracks)), shuffleNow = () => (!!id && radioStore.shuffleArtist(id)), radioNow = () => (!!id && radioStore.radioArtist(id)), formatReleaseType = (value: string) => { switch (value.toUpperCase()) { case 'ALBUM': return 'Albums' case 'EP': return 'EPs' case 'SINGLE': return 'Singles' case 'COMPILATION': return 'Compilations' default: return value } }, fetchArtists = async () => { try { mainStore.isLoading = true artists.value = [] const response = await subsonicApi.getArtists() if (sort.value === 'a-z') { artists.value = orderBy(response, 'name') } else { artists.value = orderBy(response, 'albumCount', 'desc') } } finally { mainStore.isLoading = false } }, fetchArtist = async() => { if (!id) return try { mainStore.isLoading = true const artistResponse = await subsonicApi.getArtistDetails(id), groupOrder = ['ALBUM', 'EP', 'SINGLE'] artist.value = artistResponse, isFavourite.value = favouriteStore.get('artist', id), albums.value = ( Object.entries( groupBy( orderBy( artistResponse?.albums ?? [], [ 'year', 'name' ], [ mainStore.artistAlbumSortOrder, mainStore.artistAlbumSortOrder ] ), 'releaseType' ) ).sort( ([aType], [bType]) => { const [a, b] = [ groupOrder.indexOf(aType), groupOrder.indexOf(bType) ] return ( (a === -1 && b === -1) ? 0 : ( (a === -1) ? 1 : ( (b === -1) ? -1 : a - b ) ) ) } ).map( ([releaseType, albums]) => ({ releaseType, albums: albums || [], } as { releaseType: string, albums: Album[] }) ) ) } catch (error) { console.log(error) } finally { mainStore.isLoading = false } }, loadMoreTracks = async () => { if (!id) return try { if (generator === null) { const subsonicApi = useSubsonicApi() generator = await subsonicApi.getTracksByArtist(id) } mainStore.isLoading = true const { value, done } = await generator.next() if (value !== undefined) tracks.value.push(...value) hasMore.value = !done } finally { mainStore.isLoading = false } } watch( () => [ id, sort.value ], () => ( (!id) ? fetchArtists() : fetchArtist() ), { immediate: true } ) return vine` ` }