refactor star

This commit is contained in:
austinried
2022-03-20 09:33:15 +09:00
parent 1803e9dc7c
commit a15159014c
10 changed files with 122 additions and 146 deletions

View File

@@ -15,6 +15,7 @@ import {
GetArtistsResponse,
GetPlaylistResponse,
GetPlaylistsResponse,
GetSongResponse,
GetTopSongsResponse,
Search3Response,
SubsonicResponse,
@@ -184,6 +185,8 @@ export type LibrarySlice = {
fetchLibraryPlaylists: () => Promise<void>
fetchLibraryPlaylist: (id: string) => Promise<void>
fetchLibrarySong: (id: string) => Promise<void>
fetchLibraryAlbumList: (params: GetAlbumList2Params) => Promise<string[]>
fetchLibrarySearchResults: (params: Search3Params) => Promise<SearchResults>
star: (params: StarParams) => Promise<void>
@@ -405,6 +408,28 @@ export const createLibrarySlice = (set: SetState<Store>, get: GetState<Store>):
)
},
fetchLibrarySong: async id => {
const client = get().client
if (!client) {
return
}
let response: SubsonicResponse<GetSongResponse>
try {
response = await client.getSong({ id })
} catch {
return
}
const song = mapSong(response.data.song)
set(
produce<LibrarySlice>(state => {
state.entities.songs[id] = song
}),
)
},
fetchLibraryAlbumList: async params => {
const client = get().client
if (!client) {

View File

@@ -1,102 +1,15 @@
import { StarrableItemType } from '@app/models/music'
import { Store } from '@app/state/store'
import { StarParams } from '@app/subsonic/params'
import produce from 'immer'
import { GetState, SetState } from 'zustand'
export type MusicSlice = {
//
// actions, etc.
//
starredSongs: { [id: string]: boolean }
starredAlbums: { [id: string]: boolean }
starredArtists: { [id: string]: boolean }
starItem: (id: string, type: StarrableItemType, unstar?: boolean) => Promise<void>
albumIdCoverArt: { [id: string]: string | undefined }
albumIdCoverArtRequests: { [id: string]: Promise<void> }
fetchAlbumCoverArt: (id: string) => Promise<void>
getAlbumCoverArt: (id: string | undefined) => Promise<string | undefined>
}
export const selectMusic = {
starItem: (store: MusicSlice) => store.starItem,
}
function reduceStarred(
starredType: { [id: string]: boolean },
items: { id: string; starred?: Date | boolean }[],
): { [id: string]: boolean } {
return {
...starredType,
...items.reduce((acc, val) => {
acc[val.id] = !!val.starred
return acc
}, {} as { [id: string]: boolean }),
}
}
export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): MusicSlice => ({
starredSongs: {},
starredAlbums: {},
starredArtists: {},
starItem: async (id, type, unstar = false) => {
const client = get().client
if (!client) {
return
}
let params: StarParams
let setStarred: (starred: boolean) => void
switch (type) {
case 'song':
params = { id }
setStarred = starred => {
set(
produce<MusicSlice>(state => {
state.starredSongs = reduceStarred(state.starredSongs, [{ id, starred }])
}),
)
}
break
case 'album':
params = { albumId: id }
setStarred = starred => {
set(
produce<MusicSlice>(state => {
state.starredAlbums = reduceStarred(state.starredAlbums, [{ id, starred }])
}),
)
}
break
case 'artist':
params = { artistId: id }
setStarred = starred => {
set(
produce<MusicSlice>(state => {
state.starredArtists = reduceStarred(state.starredArtists, [{ id, starred }])
}),
)
}
break
default:
return
}
try {
setStarred(!unstar)
if (unstar) {
await client.unstar(params)
} else {
await client.star(params)
}
} catch {
setStarred(unstar)
}
},
albumIdCoverArt: {},
albumIdCoverArtRequests: {},