mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-27 09:09:29 +01:00
143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import {
|
|
AlbumListItem,
|
|
AlbumWithSongs,
|
|
Artist,
|
|
ArtistInfo,
|
|
PlaylistListItem,
|
|
PlaylistWithSongs,
|
|
Song,
|
|
} from '@app/models/music'
|
|
import {
|
|
AlbumID3Element,
|
|
ArtistID3Element,
|
|
ArtistInfo2Element,
|
|
ChildElement,
|
|
PlaylistElement,
|
|
PlaylistWithSongsElement,
|
|
} from '@app/subsonic/elements'
|
|
import { GetArtistResponse } from '@app/subsonic/responses'
|
|
import { GetState, SetState } from 'zustand'
|
|
import { Store } from './store'
|
|
|
|
export type MusicMapSlice = {
|
|
mapChildToSong: (child: ChildElement, coverArt?: string) => Promise<Song>
|
|
mapChildrenToSongs: (children: ChildElement[], coverArt?: string) => Promise<Song[]>
|
|
mapArtistID3toArtist: (artist: ArtistID3Element) => Artist
|
|
mapArtistInfo: (
|
|
artistResponse: GetArtistResponse,
|
|
info: ArtistInfo2Element,
|
|
topSongs: ChildElement[],
|
|
) => Promise<ArtistInfo>
|
|
mapAlbumID3toAlbumListItem: (album: AlbumID3Element) => AlbumListItem
|
|
mapAlbumID3toAlbum: (album: AlbumID3Element) => AlbumListItem
|
|
mapAlbumID3WithSongstoAlbumWithSongs: (album: AlbumID3Element, songs: ChildElement[]) => Promise<AlbumWithSongs>
|
|
mapPlaylistListItem: (playlist: PlaylistElement) => PlaylistListItem
|
|
mapPlaylistWithSongs: (playlist: PlaylistWithSongsElement) => Promise<PlaylistWithSongs>
|
|
}
|
|
|
|
export const createMusicMapSlice = (set: SetState<Store>, get: GetState<Store>): MusicMapSlice => ({
|
|
mapChildToSong: async (child, coverArt) => {
|
|
return {
|
|
itemType: 'song',
|
|
id: child.id,
|
|
album: child.album,
|
|
albumId: child.albumId,
|
|
artist: child.artist,
|
|
artistId: child.artistId,
|
|
title: child.title,
|
|
track: child.track,
|
|
discNumber: child.discNumber,
|
|
duration: child.duration,
|
|
starred: child.starred,
|
|
coverArt: coverArt || (await get().getAlbumCoverArt(child.albumId)),
|
|
streamUri: get().buildStreamUri(child.id),
|
|
}
|
|
},
|
|
|
|
mapChildrenToSongs: async (children, coverArt) => {
|
|
const albumIds = children.reduce((acc, val) => {
|
|
if (val.albumId && !(val.albumId in acc)) {
|
|
acc[val.albumId] = get().getAlbumCoverArt(val.albumId)
|
|
}
|
|
return acc
|
|
}, {} as Record<string, Promise<string | undefined>>)
|
|
|
|
await Promise.all(Object.values(albumIds))
|
|
|
|
const songs: Song[] = []
|
|
for (const child of children) {
|
|
songs.push(await get().mapChildToSong(child, coverArt || (await get().getAlbumCoverArt(child.albumId))))
|
|
}
|
|
return songs
|
|
},
|
|
|
|
mapArtistID3toArtist: artist => {
|
|
return {
|
|
itemType: 'artist',
|
|
id: artist.id,
|
|
name: artist.name,
|
|
starred: artist.starred,
|
|
coverArt: artist.coverArt,
|
|
}
|
|
},
|
|
|
|
mapArtistInfo: async (artistResponse, info, topSongs) => {
|
|
const { artist, albums } = artistResponse
|
|
|
|
const mappedAlbums = albums.map(get().mapAlbumID3toAlbum)
|
|
|
|
return {
|
|
...get().mapArtistID3toArtist(artist),
|
|
albums: mappedAlbums,
|
|
smallImageUrl: info.smallImageUrl,
|
|
largeImageUrl: info.largeImageUrl,
|
|
topSongs: (await get().mapChildrenToSongs(topSongs)).slice(0, 5),
|
|
}
|
|
},
|
|
|
|
mapAlbumID3toAlbumListItem: album => {
|
|
return {
|
|
itemType: 'album',
|
|
id: album.id,
|
|
name: album.name,
|
|
artist: album.artist,
|
|
artistId: album.artistId,
|
|
starred: album.starred,
|
|
coverArt: album.coverArt,
|
|
}
|
|
},
|
|
|
|
mapAlbumID3toAlbum: album => {
|
|
return {
|
|
...get().mapAlbumID3toAlbumListItem(album),
|
|
coverArt: album.coverArt,
|
|
year: album.year,
|
|
}
|
|
},
|
|
|
|
mapAlbumID3WithSongstoAlbumWithSongs: async (album, songs) => {
|
|
return {
|
|
...get().mapAlbumID3toAlbum(album),
|
|
songs: await get().mapChildrenToSongs(songs),
|
|
}
|
|
},
|
|
|
|
mapPlaylistListItem: playlist => {
|
|
return {
|
|
itemType: 'playlist',
|
|
id: playlist.id,
|
|
name: playlist.name,
|
|
comment: playlist.comment,
|
|
coverArt: playlist.coverArt,
|
|
}
|
|
},
|
|
|
|
mapPlaylistWithSongs: async playlist => {
|
|
return {
|
|
...get().mapPlaylistListItem(playlist),
|
|
songs: await get().mapChildrenToSongs(playlist.songs),
|
|
coverArt: playlist.coverArt,
|
|
}
|
|
},
|
|
})
|