From d59a7f6e758c9882392c66f225a343a630935fc8 Mon Sep 17 00:00:00 2001 From: Genar Trias Ortiz Date: Fri, 27 Dec 2024 03:30:55 +0100 Subject: [PATCH] use sets for better performance --- src/components/AlbumView/index.tsx | 6 +- src/components/ArtistView/Album.tsx | 27 +-- src/components/ArtistView/index.tsx | 2 +- src/components/ArtistsTable/ArtistTable.tsx | 8 +- src/components/Collection.tsx | 23 ++- src/components/Collection/FilterPanel.tsx | 20 +-- src/components/Dashboard/index.tsx | 11 +- .../MusicTable/SongRow/index.spec.tsx | 4 +- src/components/Player/ContextualMenu.tsx | 7 +- src/components/Player/Controls.tsx | 16 +- .../Player/CustomPlayers/PeerStreamPlayer.tsx | 164 ++++++++++++----- src/components/Player/PlayerControls.tsx | 22 +-- src/components/Playlists/Playlist.tsx | 24 +-- src/components/Queue.tsx | 15 +- src/components/RelatedAlbums/index.tsx | 4 +- src/components/Sidebar/SidebarContents.tsx | 4 +- src/components/SongView/index.tsx | 18 +- src/containers/ArtistContainer.tsx | 12 +- src/containers/PlayerContainer.tsx | 2 +- src/containers/RouteSelectors.ts | 30 ++-- src/containers/TopbarContainer.tsx | 46 +++-- src/reducers/collection.spec.ts | 96 +++++----- src/reducers/collection.ts | 136 +++++++------- src/reducers/queue.spec.ts | 141 +++++++-------- src/reducers/queue.ts | 166 +++++++++--------- src/reducers/utils/queues.ts | 57 +++--- src/sagas/selectors.ts | 68 ++++--- src/services/PeerService.ts | 10 +- src/utils/apply-filters.ts | 96 +++++----- 29 files changed, 681 insertions(+), 554 deletions(-) diff --git a/src/components/AlbumView/index.tsx b/src/components/AlbumView/index.tsx index 1de29097..9c18d343 100644 --- a/src/components/AlbumView/index.tsx +++ b/src/components/AlbumView/index.tsx @@ -34,8 +34,8 @@ export default function AlbumView(props: Props) { return null } - const relatedAlbums = collection.albumsByArtist && collection.albumsByArtist[album.artist.id] && collection.albumsByArtist[album.artist.id].map((albumId: string) => { - return collection.albums[albumId] + const relatedAlbums = collection.albumsByArtist && collection.albumsByArtist.get(album.artist.id) && collection.albumsByArtist.get(album.artist.id).map((albumId: string) => { + return collection.albums.get(albumId) }) return ( @@ -47,7 +47,7 @@ export default function AlbumView(props: Props) { album={album} dispatch={props.dispatch} collection={props.collection} - songs={props.songsByAlbum[album.id]} + songs={props.songsByAlbum.get(album.id) ?? []} />
diff --git a/src/components/ArtistView/Album.tsx b/src/components/ArtistView/Album.tsx index e07d068e..4ed507ac 100644 --- a/src/components/ArtistView/Album.tsx +++ b/src/components/ArtistView/Album.tsx @@ -4,19 +4,17 @@ import { Translate } from 'react-redux-i18n' import Icon from '../common/Icon' import SongRow from '../MusicTable/SongRow' import CoverImage from '../MusicTable/CoverImage' - -interface Album { - id: string - name: string - year?: number -} +import { IAlbum } from '../../entities/Album' +import { State as QueueState } from '../../reducers/queue' +import { State as CollectionState } from '../../reducers/collection' +import { Dispatch } from 'redux' type AlbumProps = { - album: Album, - queue: any, + album: IAlbum, + queue: QueueState, songs: Array, - collection: any, - dispatch: any + collection: CollectionState, + dispatch: Dispatch } const Album = (props: AlbumProps) => { @@ -28,7 +26,12 @@ const Album = (props: AlbumProps) => { } return props.songs.map((songId) => { - const songRow = props.collection.rows[songId] + const songRow = props.collection.rows.get(songId) + + if (!songRow) { + return null + } + return ( { > { const rowRenderer = (props: any): any => { const artistId = tableIds[props.index] - const artist = artists[artistId] + const artist = artists.get(artistId) + + if (!artist) { + return null + } return ( ) diff --git a/src/components/Collection.tsx b/src/components/Collection.tsx index 81771362..eb726f51 100644 --- a/src/components/Collection.tsx +++ b/src/components/Collection.tsx @@ -6,13 +6,18 @@ import MusicTable from './MusicTable/MusicTable' import Spinner from './Spinner' import { useLocation } from 'react-router' import { Location } from 'react-router' +import { State as AppState } from '../reducers/app' +import { State as PlaylistState } from '../reducers/playlist' +import { State as QueueState } from '../reducers/queue' +import { State as PlayerState } from '../reducers/player' +import { State as CollectionState } from '../reducers/collection' type Props = { - app: any, - playlist: any, - queue: any, - player: any, - collection: any, + app: AppState, + playlist: PlaylistState, + queue: QueueState, + player: PlayerState, + collection: CollectionState, filteredSongs: Array, dispatch: Dispatch } @@ -20,9 +25,9 @@ type Props = { const mediaForPath = (location: Location, props: Props) => { switch (location.pathname) { case '/collection/audio': - return props.collection.mediaByType['audio'] + return Array.from(props.collection.mediaByType.get('audio') ?? []) case '/collection/video': - return props.collection.mediaByType['video'] + return Array.from(props.collection.mediaByType.get('video') ?? []) case '/search-results': return props.collection.searchResults default: @@ -41,7 +46,7 @@ const Collection = (props: Props) => { return (
- {!mediaItems.length ? ( + {!!mediaItems && Array.from(mediaItems).length === 0 ? ( @@ -50,7 +55,7 @@ const Collection = (props: Props) => { } /> ) : ( diff --git a/src/components/Collection/FilterPanel.tsx b/src/components/Collection/FilterPanel.tsx index 10ca8fad..045d6507 100644 --- a/src/components/Collection/FilterPanel.tsx +++ b/src/components/Collection/FilterPanel.tsx @@ -99,14 +99,14 @@ const FilterPanel = ({ collection, activeFilters, onFilterChange, dispatch }: Pr // Format currently selected values const selectedValues = [ - ...activeFilters.genres.map(g => ({ value: `genre:${g}`, label: g, color: '#ff9999' })), - ...activeFilters.types.map(t => ({ value: `type:${t}`, label: t, color: '#99ff99' })), - ...activeFilters.artists.map(a => ({ + ...Array.from(activeFilters.genres).map(g => ({ value: `genre:${g}`, label: g, color: '#ff9999' })), + ...Array.from(activeFilters.types).map(t => ({ value: `type:${t}`, label: t, color: '#99ff99' })), + ...Array.from(activeFilters.artists).map(a => ({ value: `artist:${a}`, label: collection.artists[a].name, color: '#9999ff' })), - ...activeFilters.providers.map(p => ({ + ...Array.from(activeFilters.providers).map(p => ({ value: `provider:${p}`, label: p, color: '#99ccff' @@ -229,11 +229,11 @@ const FilterPanel = ({ collection, activeFilters, onFilterChange, dispatch }: Pr menuPosition="fixed" menuPlacement="auto" /> - {Object.values(activeFilters).some(arr => arr.length > 0) && ( + {Object.values(activeFilters).some(arr => arr.size > 0) && ( @@ -290,12 +290,12 @@ const FilterPanel = ({ collection, activeFilters, onFilterChange, dispatch }: Pr menuPlacement="auto" />
- {Object.values(activeFilters).some(arr => arr.length > 0) && ( + {Object.values(activeFilters).some(arr => arr.size > 0) && (
- {trackIds.length && ( + {[...trackIds].length && ( <> @@ -125,7 +125,7 @@ const Playlist = (props: Props) => { replace: true }) - dispatch({ type: types.SET_CURRENT_PLAYING, songId: songIds[0] }) + dispatch({ type: types.SET_CURRENT_PLAYING, songId: Array.from(songIds)[0] }) dispatch({ type: types.START_PLAYING }) }} > diff --git a/src/components/Queue.tsx b/src/components/Queue.tsx index c131e704..351f400d 100644 --- a/src/components/Queue.tsx +++ b/src/components/Queue.tsx @@ -5,15 +5,18 @@ import { State as CollectionState } from '../reducers/collection' import BodyMessage from './BodyMessage' import MusicTable from './MusicTable/MusicTable' import Spinner from './Spinner' +import { State as QueueState } from '../reducers/queue' +import { State as PlayerState } from '../reducers/player' +import { State as AppState } from '../reducers/app' type Props = { - queue: any, - player: any, + queue: QueueState, + player: PlayerState, collection: CollectionState, dispatch: Dispatch, slim?: boolean, className?: string, - app: any, + app: AppState, } const Queue = (props: Props) => { @@ -24,7 +27,7 @@ const Queue = (props: Props) => { } // Disabled if theres no songs on queue - if (props.slim && !trackIds.length) { + if (props.slim && trackIds.size === 0) { return null } @@ -42,7 +45,7 @@ const Queue = (props: Props) => { ) } - if (!trackIds.length) { + if (trackIds.size === 0) { const message = (
Add songs from the collection or search for new ones @@ -67,7 +70,7 @@ const Queue = (props: Props) => { return (
+ albums?: Set } const RelatedAlbums = (props: Props) => { @@ -37,7 +37,7 @@ const RelatedAlbums = (props: Props) => { if (!props.albums) return null; - const Albums = props.albums + const Albums = Array.from(props.albums.values()) ?.filter((album) => { return album.name !== "" // We don't want empty titles }) diff --git a/src/components/Sidebar/SidebarContents.tsx b/src/components/Sidebar/SidebarContents.tsx index 9b20af3b..12d64fc8 100644 --- a/src/components/Sidebar/SidebarContents.tsx +++ b/src/components/Sidebar/SidebarContents.tsx @@ -68,11 +68,11 @@ const SidebarContents = (props: ContentProps) => { , currentPlaying?: string }, songId: string, dispatch: Dispatch, loading: boolean, @@ -60,7 +62,7 @@ const SongView = ({ songId, loading, className = '', dispatch, playerPortal, pla const isSongPinned = songObj?.hasAnyProviderOf(['opfs']) || false const [pinned, setPinnedSong] = React.useState(isSongPinned) - const [downloadUrls, setDownloadUrls] = React.useState([]) + const [downloadUrls, setDownloadUrls] = React.useState([]) const [showLyrics, setShowLyrics] = React.useState(false) React.useEffect(() => { @@ -172,7 +174,7 @@ const SongView = ({ songId, loading, className = '', dispatch, playerPortal, pla } - {!trackIds.includes(song.id) && + {!trackIds.has(song.id) &&