mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 23:02:43 +01:00
switched to new playlist w/songs
removed more unused stuff
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { selectMusic } from '@app/state/music'
|
||||
import { Store, useStore, useStoreDeep } from '@app/state/store'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
|
||||
@@ -15,32 +14,6 @@ export const useArtistInfo = (id: string) => {
|
||||
return artistInfo
|
||||
}
|
||||
|
||||
export const useAlbumWithSongs = (id: string) => {
|
||||
const album = useStore(useCallback((state: Store) => state.albumsWithSongs[id], [id]))
|
||||
const fetchAlbum = useStore(selectMusic.fetchAlbumWithSongs)
|
||||
|
||||
useEffect(() => {
|
||||
if (!album) {
|
||||
fetchAlbum(id)
|
||||
}
|
||||
}, [album, fetchAlbum, id])
|
||||
|
||||
return album
|
||||
}
|
||||
|
||||
export const usePlaylistWithSongs = (id: string) => {
|
||||
const playlist = useStore(useCallback((state: Store) => state.playlistsWithSongs[id], [id]))
|
||||
const fetchPlaylist = useStore(selectMusic.fetchPlaylistWithSongs)
|
||||
|
||||
useEffect(() => {
|
||||
if (!playlist) {
|
||||
fetchPlaylist(id)
|
||||
}
|
||||
}, [fetchPlaylist, id, playlist])
|
||||
|
||||
return playlist
|
||||
}
|
||||
|
||||
export const useStarred = (id: string, type: string) => {
|
||||
return useStore(
|
||||
useCallback(
|
||||
|
||||
@@ -21,10 +21,6 @@ export interface Album extends AlbumListItem {
|
||||
year?: number
|
||||
}
|
||||
|
||||
export interface AlbumWithSongs extends Album {
|
||||
songs: Song[]
|
||||
}
|
||||
|
||||
export interface SearchResults {
|
||||
artists: Artist[]
|
||||
albums: AlbumListItem[]
|
||||
@@ -39,10 +35,6 @@ export interface PlaylistListItem {
|
||||
coverArt?: string
|
||||
}
|
||||
|
||||
export interface PlaylistWithSongs extends PlaylistListItem {
|
||||
songs: Song[]
|
||||
}
|
||||
|
||||
export interface Song {
|
||||
itemType: 'song'
|
||||
id: string
|
||||
@@ -62,6 +54,4 @@ export interface Song {
|
||||
|
||||
export type ListableItem = Song | AlbumListItem | Artist | PlaylistListItem
|
||||
|
||||
export type HomeLists = { [key: string]: AlbumListItem[] }
|
||||
|
||||
export type StarrableItemType = 'song' | 'album' | 'artist'
|
||||
|
||||
@@ -5,7 +5,6 @@ import ImageGradientFlatList from '@app/components/ImageGradientFlatList'
|
||||
import ListItem from '@app/components/ListItem'
|
||||
import ListPlayerControls from '@app/components/ListPlayerControls'
|
||||
import { useCoverArtFile } from '@app/hooks/cache'
|
||||
import { usePlaylistWithSongs } from '@app/hooks/music'
|
||||
import { Album, PlaylistListItem, Song } from '@app/models/music'
|
||||
import { useStore, useStoreDeep } from '@app/state/store'
|
||||
import { selectTrackPlayer } from '@app/state/trackplayer'
|
||||
@@ -128,16 +127,34 @@ const PlaylistView = React.memo<{
|
||||
id: string
|
||||
title: string
|
||||
}>(({ id, title }) => {
|
||||
const playlist = usePlaylistWithSongs(id)
|
||||
return <SongListDetails title={title} songList={playlist} subtitle={playlist?.comment} type="playlist" />
|
||||
const playlist = useStoreDeep(useCallback(store => store.entities.playlists[id], [id]))
|
||||
const songs = useStoreDeep(
|
||||
useCallback(
|
||||
store => {
|
||||
const ids = store.entities.playlistSongs[id]
|
||||
return ids ? ids.map(i => store.entities.songs[i]) : undefined
|
||||
},
|
||||
[id],
|
||||
),
|
||||
)
|
||||
|
||||
const fetchPlaylist = useStore(store => store.fetchLibraryPlaylist)
|
||||
|
||||
useEffect(() => {
|
||||
if (!playlist || !songs) {
|
||||
fetchPlaylist(id)
|
||||
}
|
||||
}, [playlist, fetchPlaylist, id, songs])
|
||||
|
||||
return (
|
||||
<SongListDetails title={title} songList={playlist} songs={songs} subtitle={playlist?.comment} type="playlist" />
|
||||
)
|
||||
})
|
||||
|
||||
const AlbumView = React.memo<{
|
||||
id: string
|
||||
title: string
|
||||
}>(({ id, title }) => {
|
||||
// const album = useAlbumWithSongs(id)
|
||||
|
||||
const album = useStoreDeep(useCallback(store => store.entities.albums[id], [id]))
|
||||
const songs = useStoreDeep(
|
||||
useCallback(
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
import {
|
||||
AlbumListItem,
|
||||
AlbumWithSongs,
|
||||
Artist,
|
||||
HomeLists,
|
||||
PlaylistListItem,
|
||||
PlaylistWithSongs,
|
||||
SearchResults,
|
||||
StarrableItemType,
|
||||
} from '@app/models/music'
|
||||
import { AlbumListItem, Artist, PlaylistListItem, SearchResults, StarrableItemType } from '@app/models/music'
|
||||
import { Store } from '@app/state/store'
|
||||
import { GetAlbumList2Params, GetAlbumList2TypeBase, Search3Params, StarParams } from '@app/subsonic/params'
|
||||
import { GetAlbumList2Params, Search3Params, StarParams } from '@app/subsonic/params'
|
||||
import produce from 'immer'
|
||||
import { GetState, SetState } from 'zustand'
|
||||
|
||||
export type MusicSlice = {
|
||||
//
|
||||
// family-style state
|
||||
//
|
||||
albumsWithSongs: { [id: string]: AlbumWithSongs }
|
||||
fetchAlbumWithSongs: (id: string) => Promise<AlbumWithSongs | undefined>
|
||||
|
||||
playlistsWithSongs: { [id: string]: PlaylistWithSongs }
|
||||
fetchPlaylistWithSongs: (id: string) => Promise<PlaylistWithSongs | undefined>
|
||||
|
||||
//
|
||||
// lists-style state
|
||||
//
|
||||
@@ -36,11 +18,6 @@ export type MusicSlice = {
|
||||
offset?: number,
|
||||
) => Promise<SearchResults>
|
||||
|
||||
homeLists: HomeLists
|
||||
homeListsUpdating: boolean
|
||||
fetchHomeLists: () => Promise<void>
|
||||
clearHomeLists: () => void
|
||||
|
||||
//
|
||||
// actions, etc.
|
||||
//
|
||||
@@ -56,19 +33,11 @@ export type MusicSlice = {
|
||||
}
|
||||
|
||||
export const selectMusic = {
|
||||
fetchAlbumWithSongs: (state: Store) => state.fetchAlbumWithSongs,
|
||||
fetchPlaylistWithSongs: (state: Store) => state.fetchPlaylistWithSongs,
|
||||
|
||||
fetchArtists: (store: MusicSlice) => store.fetchArtists,
|
||||
fetchPlaylists: (store: MusicSlice) => store.fetchPlaylists,
|
||||
fetchAlbums: (store: MusicSlice) => store.fetchAlbums,
|
||||
fetchSearchResults: (store: MusicSlice) => store.fetchSearchResults,
|
||||
|
||||
homeLists: (store: MusicSlice) => store.homeLists,
|
||||
homeListsUpdating: (store: MusicSlice) => store.homeListsUpdating,
|
||||
fetchHomeLists: (store: MusicSlice) => store.fetchHomeLists,
|
||||
clearHomeLists: (store: MusicSlice) => store.clearHomeLists,
|
||||
|
||||
starItem: (store: MusicSlice) => store.starItem,
|
||||
}
|
||||
|
||||
@@ -86,55 +55,6 @@ function reduceStarred(
|
||||
}
|
||||
|
||||
export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): MusicSlice => ({
|
||||
albumsWithSongs: {},
|
||||
|
||||
fetchAlbumWithSongs: async id => {
|
||||
const client = get().client
|
||||
if (!client) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.getAlbum({ id })
|
||||
const album = await get().mapAlbumID3WithSongstoAlbumWithSongs(response.data.album, response.data.songs)
|
||||
|
||||
set(
|
||||
produce<MusicSlice>(state => {
|
||||
state.albumsWithSongs[id] = album
|
||||
state.starredSongs = reduceStarred(state.starredSongs, album.songs)
|
||||
state.starredAlbums = reduceStarred(state.starredAlbums, [album])
|
||||
}),
|
||||
)
|
||||
return album
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
|
||||
playlistsWithSongs: {},
|
||||
|
||||
fetchPlaylistWithSongs: async id => {
|
||||
const client = get().client
|
||||
if (!client) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.getPlaylist({ id })
|
||||
const playlist = await get().mapPlaylistWithSongs(response.data.playlist)
|
||||
|
||||
set(
|
||||
produce<MusicSlice>(state => {
|
||||
state.playlistsWithSongs[id] = playlist
|
||||
state.starredSongs = reduceStarred(state.starredSongs, playlist.songs)
|
||||
}),
|
||||
)
|
||||
return playlist
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
|
||||
fetchArtists: async () => {
|
||||
const client = get().client
|
||||
if (!client) {
|
||||
@@ -270,50 +190,6 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
||||
}
|
||||
},
|
||||
|
||||
homeLists: {},
|
||||
homeListsUpdating: false,
|
||||
|
||||
fetchHomeLists: async () => {
|
||||
const client = get().client
|
||||
if (!client) {
|
||||
return
|
||||
}
|
||||
|
||||
if (get().homeListsUpdating) {
|
||||
return
|
||||
}
|
||||
set({ homeListsUpdating: true })
|
||||
|
||||
const types = get().settings.screens.home.lists
|
||||
|
||||
try {
|
||||
const promises: Promise<any>[] = []
|
||||
for (const type of types) {
|
||||
promises.push(
|
||||
client
|
||||
.getAlbumList2({ type: type as GetAlbumList2TypeBase, size: 20 })
|
||||
.then(response => {
|
||||
const list = response.data.albums.map(get().mapAlbumID3toAlbumListItem)
|
||||
set(
|
||||
produce<MusicSlice>(state => {
|
||||
state.homeLists[type] = list
|
||||
state.starredAlbums = reduceStarred(state.starredAlbums, state.homeLists[type])
|
||||
}),
|
||||
)
|
||||
})
|
||||
.catch(() => {}),
|
||||
)
|
||||
}
|
||||
await Promise.all(promises)
|
||||
} finally {
|
||||
set({ homeListsUpdating: false })
|
||||
}
|
||||
},
|
||||
|
||||
clearHomeLists: () => {
|
||||
set({ homeLists: {} })
|
||||
},
|
||||
|
||||
starredSongs: {},
|
||||
starredAlbums: {},
|
||||
starredArtists: {},
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { AlbumListItem, AlbumWithSongs, Artist, PlaylistListItem, PlaylistWithSongs, Song } from '@app/models/music'
|
||||
import {
|
||||
AlbumID3Element,
|
||||
ArtistID3Element,
|
||||
ChildElement,
|
||||
PlaylistElement,
|
||||
PlaylistWithSongsElement,
|
||||
} from '@app/subsonic/elements'
|
||||
import { AlbumListItem, Artist, PlaylistListItem, Song } from '@app/models/music'
|
||||
import { AlbumID3Element, ArtistID3Element, ChildElement, PlaylistElement } from '@app/subsonic/elements'
|
||||
import { GetState, SetState } from 'zustand'
|
||||
import { Store } from './store'
|
||||
|
||||
@@ -15,9 +9,7 @@ export type MusicMapSlice = {
|
||||
mapArtistID3toArtist: (artist: ArtistID3Element) => Artist
|
||||
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 => ({
|
||||
@@ -86,13 +78,6 @@ export const createMusicMapSlice = (set: SetState<Store>, get: GetState<Store>):
|
||||
}
|
||||
},
|
||||
|
||||
mapAlbumID3WithSongstoAlbumWithSongs: async (album, songs) => {
|
||||
return {
|
||||
...get().mapAlbumID3toAlbum(album),
|
||||
songs: await get().mapChildrenToSongs(songs),
|
||||
}
|
||||
},
|
||||
|
||||
mapPlaylistListItem: playlist => {
|
||||
return {
|
||||
itemType: 'playlist',
|
||||
@@ -102,12 +87,4 @@ export const createMusicMapSlice = (set: SetState<Store>, get: GetState<Store>):
|
||||
coverArt: playlist.coverArt,
|
||||
}
|
||||
},
|
||||
|
||||
mapPlaylistWithSongs: async playlist => {
|
||||
return {
|
||||
...get().mapPlaylistListItem(playlist),
|
||||
songs: await get().mapChildrenToSongs(playlist.songs),
|
||||
coverArt: playlist.coverArt,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user