From 661b17f232ac070bae3ef8f314444ba7865bf911 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Fri, 30 Jul 2021 13:02:45 +0900 Subject: [PATCH] fixed changing activeServer --- app/screens/Home.tsx | 3 +- app/screens/LibraryAlbums.tsx | 12 +--- app/screens/LibraryArtists.tsx | 9 +-- app/screens/LibraryPlaylists.tsx | 9 +-- app/screens/Settings.tsx | 10 ++-- app/state/music.ts | 100 ++++++++++++++++++++----------- app/state/server.ts | 54 +++++++++++++++++ app/state/settings.ts | 13 ---- 8 files changed, 133 insertions(+), 77 deletions(-) create mode 100644 app/state/server.ts diff --git a/app/screens/Home.tsx b/app/screens/Home.tsx index a36727a..8a044f3 100644 --- a/app/screens/Home.tsx +++ b/app/screens/Home.tsx @@ -5,7 +5,8 @@ import NothingHere from '@app/components/NothingHere' import PressableOpacity from '@app/components/PressableOpacity' import { AlbumListItem } from '@app/models/music' import { homeListsAtom, homeListsUpdatingAtom, useUpdateHomeLists } from '@app/state/music' -import { homeListTypesAtom, useActiveServerRefresh } from '@app/state/settings' +import { useActiveServerRefresh } from '@app/state/server' +import { homeListTypesAtom } from '@app/state/settings' import colors from '@app/styles/colors' import font from '@app/styles/font' import { GetAlbumListType } from '@app/subsonic/params' diff --git a/app/screens/LibraryAlbums.tsx b/app/screens/LibraryAlbums.tsx index ada2402..da38b4d 100644 --- a/app/screens/LibraryAlbums.tsx +++ b/app/screens/LibraryAlbums.tsx @@ -3,12 +3,12 @@ import GradientFlatList from '@app/components/GradientFlatList' import PressableOpacity from '@app/components/PressableOpacity' import { Album } from '@app/models/music' import { albumListAtom, albumListUpdatingAtom, useUpdateAlbumList } from '@app/state/music' -import { useActiveServerRefresh } from '@app/state/settings' +import { useActiveListRefresh } from '@app/state/server' import colors from '@app/styles/colors' import font from '@app/styles/font' import { useNavigation } from '@react-navigation/native' import { useAtomValue } from 'jotai/utils' -import React, { useEffect } from 'react' +import React from 'react' import { StyleSheet, Text, useWindowDimensions, View } from 'react-native' const AlbumItem = React.memo<{ @@ -56,7 +56,7 @@ const AlbumsList = () => { const updating = useAtomValue(albumListUpdatingAtom) const updateList = useUpdateAlbumList() - useActiveServerRefresh(updateList) + useActiveListRefresh(list, updateList) const layout = useWindowDimensions() @@ -65,12 +65,6 @@ const AlbumsList = () => { const albumsList = list.map(album => ({ album, size, height })) - useEffect(() => { - if (albumsList.length === 0) { - updateList() - } - }) - return ( = ({ item }) => ( @@ -15,11 +16,7 @@ const ArtistsList = () => { const updating = useAtomValue(artistsUpdatingAtom) const updateArtists = useUpdateArtists() - useEffect(() => { - if (artists.length === 0) { - updateArtists() - } - }) + useActiveListRefresh(artists, updateArtists) return ( = ({ item }) => ( @@ -15,11 +16,7 @@ const PlaylistsList = () => { const updating = useAtomValue(playlistsUpdatingAtom) const updatePlaylists = useUpdatePlaylists() - useEffect(() => { - if (playlists.length === 0) { - updatePlaylists() - } - }) + useActiveListRefresh(playlists, updatePlaylists) return ( (({ server }) => { - const [activeServer, setActiveServer] = useAtom(activeServerAtom) + const activeServer = useAtomValue(activeServerAtom) + const setActiveServer = useSetActiveServer() const navigation = useNavigation() const setActive = useCallback(() => { - if (activeServer?.id === server.id) { - return - } setActiveServer(server.id) - }, [activeServer?.id, server.id, setActiveServer]) + }, [server.id, setActiveServer]) return ( { setUpdating(true) const client = new SubsonicApiClient(server) - const response = await client.getArtists() - setArtists(response.data.artists.map(mapArtistID3toArtist)) - setUpdating(false) + try { + const response = await client.getArtists() + setArtists(response.data.artists.map(mapArtistID3toArtist)) + } finally { + setUpdating(false) + } } } @@ -83,17 +86,19 @@ export const useUpdateHomeLists = () => { const client = new SubsonicApiClient(server) - const promises: Promise[] = [] - for (const type of types) { - promises.push( - client.getAlbumList2({ type: type as GetAlbumList2Type, size: 20 }).then(response => { - updateHomeList({ type, albums: response.data.albums.map(mapAlbumID3toAlbumListItem) }) - }), - ) + try { + const promises: Promise[] = [] + for (const type of types) { + promises.push( + client.getAlbumList2({ type: type as GetAlbumList2Type, size: 20 }).then(response => { + updateHomeList({ type, albums: response.data.albums.map(mapAlbumID3toAlbumListItem) }) + }), + ) + } + await Promise.all(promises) + } finally { + setUpdating(false) } - await Promise.all(promises) - - setUpdating(false) } } @@ -120,14 +125,17 @@ export const useUpdateSearchResults = () => { setUpdating(true) const client = new SubsonicApiClient(server) - const response = await client.search3({ query }) - updateList({ - artists: response.data.artists.map(mapArtistID3toArtist), - albums: response.data.albums.map(mapAlbumID3toAlbumListItem), - songs: response.data.songs.map(a => mapChildToSong(a, client)), - }) - setUpdating(false) + try { + const response = await client.search3({ query }) + updateList({ + artists: response.data.artists.map(mapArtistID3toArtist), + albums: response.data.albums.map(mapAlbumID3toAlbumListItem), + songs: response.data.songs.map(a => mapChildToSong(a, client)), + }) + } finally { + setUpdating(false) + } } } @@ -150,10 +158,13 @@ export const useUpdatePlaylists = () => { setUpdating(true) const client = new SubsonicApiClient(server) - const response = await client.getPlaylists() - updateList(response.data.playlists.map(mapPlaylistListItem)) - setUpdating(false) + try { + const response = await client.getPlaylists() + updateList(response.data.playlists.map(mapPlaylistListItem)) + } finally { + setUpdating(false) + } } } @@ -165,8 +176,13 @@ export const playlistAtomFamily = atomFamily((id: string) => } const client = new SubsonicApiClient(server) - const response = await client.getPlaylist({ id }) - return mapPlaylistWithSongs(response.data.playlist, client) + + try { + const response = await client.getPlaylist({ id }) + return mapPlaylistWithSongs(response.data.playlist, client) + } catch { + return undefined + } }), ) @@ -189,10 +205,13 @@ export const useUpdateAlbumList = () => { setUpdating(true) const client = new SubsonicApiClient(server) - const response = await client.getAlbumList2({ type: 'alphabeticalByArtist', size: 500 }) - updateList(response.data.albums.map(mapAlbumID3toAlbumListItem)) - setUpdating(false) + try { + const response = await client.getAlbumList2({ type: 'alphabeticalByArtist', size: 500 }) + updateList(response.data.albums.map(mapAlbumID3toAlbumListItem)) + } finally { + setUpdating(false) + } } } @@ -204,8 +223,13 @@ export const albumAtomFamily = atomFamily((id: string) => } const client = new SubsonicApiClient(server) - const response = await client.getAlbum({ id }) - return mapAlbumID3WithSongstoAlbunWithSongs(response.data.album, response.data.songs, client) + + try { + const response = await client.getAlbum({ id }) + return mapAlbumID3WithSongstoAlbunWithSongs(response.data.album, response.data.songs, client) + } catch { + return undefined + } }), ) @@ -217,13 +241,17 @@ export const artistInfoAtomFamily = atomFamily((id: string) => } const client = new SubsonicApiClient(server) - const [artistResponse, artistInfoResponse] = await Promise.all([ - client.getArtist({ id }), - client.getArtistInfo2({ id }), - ]) - const topSongsResponse = await client.getTopSongs({ artist: artistResponse.data.artist.name, count: 50 }) - return mapArtistInfo(artistResponse.data, artistInfoResponse.data.artistInfo, topSongsResponse.data.songs, client) + try { + const [artistResponse, artistInfoResponse] = await Promise.all([ + client.getArtist({ id }), + client.getArtistInfo2({ id }), + ]) + const topSongsResponse = await client.getTopSongs({ artist: artistResponse.data.artist.name, count: 50 }) + return mapArtistInfo(artistResponse.data, artistInfoResponse.data.artistInfo, topSongsResponse.data.songs, client) + } catch { + return undefined + } }), ) diff --git a/app/state/server.ts b/app/state/server.ts new file mode 100644 index 0000000..e6a5af7 --- /dev/null +++ b/app/state/server.ts @@ -0,0 +1,54 @@ +import { useAtom } from 'jotai' +import { useAtomValue, useUpdateAtom } from 'jotai/utils' +import { useEffect } from 'react' +import { albumListAtom, artistsAtom, homeListsAtom, playlistsAtom, searchResultsAtom } from './music' +import { activeServerAtom } from './settings' +import { useReset } from './trackplayer' + +export const useSetActiveServer = () => { + const [activeServer, setActiveServer] = useAtom(activeServerAtom) + const setArtists = useUpdateAtom(artistsAtom) + const setHomeLists = useUpdateAtom(homeListsAtom) + const setSearchResults = useUpdateAtom(searchResultsAtom) + const setPlaylists = useUpdateAtom(playlistsAtom) + const setAlbumLists = useUpdateAtom(albumListAtom) + const resetPlayer = useReset() + + return async (id: string) => { + if (id === activeServer?.id) { + return + } + + await resetPlayer() + + setArtists([]) + setHomeLists({}) + setSearchResults({ artists: [], albums: [], songs: [] }) + setPlaylists([]) + setAlbumLists([]) + + setActiveServer(id) + } +} + +export const useActiveListRefresh = (list: unknown[], update: () => void) => { + const activeServer = useAtomValue(activeServerAtom) + + useEffect(() => { + if (list.length === 0) { + update() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeServer]) +} + +export const useActiveServerRefresh = (update: () => void) => { + const activeServer = useAtomValue(activeServerAtom) + + useEffect(() => { + if (activeServer) { + update() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeServer]) +} diff --git a/app/state/settings.ts b/app/state/settings.ts index 40e2b80..6d40231 100644 --- a/app/state/settings.ts +++ b/app/state/settings.ts @@ -1,8 +1,6 @@ import { atom } from 'jotai' import { AppSettings, Server } from '@app/models/settings' import atomWithAsyncStorage from '@app/storage/atomWithAsyncStorage' -import { useEffect } from 'react' -import { useAtomValue } from 'jotai/utils' import equal from 'fast-deep-equal' export const appSettingsAtom = atomWithAsyncStorage('@appSettings', { @@ -45,15 +43,4 @@ export const serversAtom = atom( }, ) -export const useActiveServerRefresh = (update: () => any) => { - const activeServer = useAtomValue(activeServerAtom) - - useEffect(() => { - if (activeServer) { - update() - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [activeServer]) -} - export const homeListTypesAtom = atom(get => get(appSettingsAtom).home.lists)