import { ref, watch } from 'vue' import { useRoute } from 'vue-router' import { orderBy } from 'lodash-es' import type { Album, Genre } from '../types' import { useSubsonicApi } from '../subsonicApi' import { useMainStore } from '../store/main' import { usePlayerStore } from '../store/player' import { useRadioStore } from '../store/radio' import { AlbumList } from '../components/AlbumList.vine' interface GenreWithAlbums { id: string name: string albumCount: number albums: Album[] } export const GenreView = ({ id }: { id: string }) => { const route = useRoute(), subsonicApi = useSubsonicApi(), mainStore = useMainStore(), playerStore = usePlayerStore(), radioStore = useRadioStore(), sort = ref('a-z'), plainGenres = ref([]), genres = ref([]), albums = ref([]), hasMore = ref(true), shuffleNow = () => (!!id && radioStore.shuffleGenre(id)), fetchGenres = async () => { mainStore.isLoading = true genres.value = [] try { const response = await subsonicApi.getGenres() plainGenres.value = ( (sort.value !== 'a-z') ? orderBy(response, 'albumCount', 'desc') : orderBy(response, 'name') ) fetchGenreAlbums() } catch (error) { console.error('Failed to load genres or albums:', error) } finally { mainStore.isLoading = false } }, fetchGenreAlbums = async () => { try { const numCurrentItems = genres.value.length mainStore.isLoading = true Promise.all( plainGenres.value.slice( numCurrentItems, numCurrentItems + 5 ) .map(async (genre: Genre) => { return { id: genre.id, name: genre.name, albumCount: genre.albumCount, albums: await subsonicApi.getAlbumsByGenre(genre.id, 20, 0, true), } as GenreWithAlbums }) ).then( result => genres.value.push(...result) ) hasMore.value = genres.value.length < plainGenres.value.length } finally { mainStore.isLoading = false } }, fetchAlbums = async() => { try { mainStore.isLoading = true const newAlbums = await subsonicApi.getAlbumsByGenre(id, 30, albums.value.length) albums.value.push(...newAlbums) hasMore.value = !!newAlbums.length } catch (error) { console.log(error) } finally { mainStore.isLoading = false } } watch( () => [ id, sort.value ], async () => { if (!id) { fetchGenres() } else { albums.value = [] fetchAlbums() } }, { immediate: true } ) return vine` ` }