diff --git a/src/renderer/features/playlists/components/playlist-detail-content.tsx b/src/renderer/features/playlists/components/playlist-detail-content.tsx index 31038a63..9f51c987 100644 --- a/src/renderer/features/playlists/components/playlist-detail-content.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-content.tsx @@ -1,5 +1,5 @@ -import { MutableRefObject, useCallback, useMemo, useRef } from 'react'; -import { ColDef, GetRowIdParams, RowDoubleClickedEvent } from '@ag-grid-community/core'; +import { MutableRefObject, useMemo, useRef } from 'react'; +import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { Box, Group } from '@mantine/core'; import { closeAllModals, openModal } from '@mantine/modals'; @@ -9,7 +9,7 @@ import { generatePath, useNavigate, useParams } from 'react-router'; import { Link } from 'react-router-dom'; import styled from 'styled-components'; import { useListStoreByKey } from '../../../store/list.store'; -import { LibraryItem, QueueSong, ServerType } from '/@/renderer/api/types'; +import { LibraryItem, QueueSong } from '/@/renderer/api/types'; import { Button, ConfirmModal, DropdownMenu, MotionGroup, toast } from '/@/renderer/components'; import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table'; import { useCurrentSongRowStyles } from '/@/renderer/components/virtual-table/hooks/use-current-song-row-styles'; @@ -28,7 +28,6 @@ import { AppRoute } from '/@/renderer/router/routes'; import { useCurrentServer } from '/@/renderer/store'; import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { Play } from '/@/renderer/types'; -import { useScanUpdate } from '/@/renderer/features/playlists/hooks/use-scan-update'; const ContentContainer = styled.div` position: relative; @@ -157,18 +156,6 @@ export const PlaylistDetailContent = ({ tableRef }: PlaylistDetailContentProps) const loadMoreRef = useRef(null); - // Duplicates are only present if on Navidrome - const getId = useCallback( - (data: GetRowIdParams): string => { - return server?.type === ServerType.JELLYFIN - ? data.data.id - : `${data.data.id}-${data.data.pageIndex}`; - }, - [server?.type], - ); - - useScanUpdate(server, tableRef); - return ( `${data.data.id}-${data.data.pageIndex}`} rowClassRules={rowClassRules} rowData={playlistSongData} rowHeight={60} rowSelection="multiple" - shouldUpdateSong={server?.type === ServerType.JELLYFIN} onCellContextMenu={handleContextMenu} onRowDoubleClicked={handleRowDoubleClick} /> diff --git a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx index b2637bc8..c2b6d2d4 100644 --- a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx @@ -1,7 +1,6 @@ import type { BodyScrollEvent, ColDef, - GetRowIdParams, GridReadyEvent, IDatasource, PaginationChangedEvent, @@ -20,7 +19,6 @@ import { LibraryItem, PlaylistSongListQuery, QueueSong, - ServerType, Song, SongListSort, SortOrder, @@ -49,7 +47,6 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { ListDisplayType } from '/@/renderer/types'; import { useAppFocus } from '/@/renderer/hooks'; import { toast } from '/@/renderer/components'; -import { useScanUpdate } from '/@/renderer/features/playlists/hooks/use-scan-update'; interface PlaylistDetailContentProps { tableRef: MutableRefObject; @@ -273,16 +270,6 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten const { rowClassRules } = useCurrentSongRowStyles({ tableRef }); - // Duplicates are only present if on Navidrome - const getId = useCallback( - (data: GetRowIdParams): string => { - return server?.type === ServerType.JELLYFIN ? data.data.id : data.data.uniqueId; - }, - [server?.type], - ); - - useScanUpdate(server, tableRef); - return ( <> @@ -292,6 +279,7 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} ref={tableRef} alwaysShowHorizontalScroll + shouldUpdateSong autoFitColumns={page.table.autoFit} columnDefs={columnDefs} context={{ @@ -300,7 +288,7 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten onCellContextMenu: handleContextMenu, status, }} - getRowId={getId} + getRowId={(data) => data.data.uniqueId} infiniteInitialRowCount={checkPlaylistList.data?.totalRecordCount || 100} pagination={isPaginationEnabled} paginationAutoPageSize={isPaginationEnabled} @@ -311,7 +299,6 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten } rowHeight={page.table.rowHeight || 40} rowModelType="infinite" - shouldUpdateSong={server?.type === ServerType.JELLYFIN} onBodyScrollEnd={handleScroll} onCellContextMenu={handleContextMenu} onColumnMoved={handleColumnChange} diff --git a/src/renderer/features/playlists/hooks/use-scan-update.ts b/src/renderer/features/playlists/hooks/use-scan-update.ts deleted file mode 100644 index 3d4574f7..00000000 --- a/src/renderer/features/playlists/hooks/use-scan-update.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { MutableRefObject, useCallback } from 'react'; -import { ServerListItem, ServerType, Song } from '/@/renderer/api/types'; -import { RowNode } from '@ag-grid-community/core'; -import { AgGridReact } from '@ag-grid-community/react'; -import { useSongChange } from '/@/renderer/hooks/use-song-change'; -import { UserEvent } from '/@/renderer/store/event.store'; - -export const useScanUpdate = ( - server: ServerListItem | null, - tableRef: MutableRefObject, -) => { - const handler = useCallback( - (ids: string[], event: UserEvent) => { - const api = tableRef.current?.api; - if (!api) return; - - const idSet = new Set(ids); - const rowNodes: RowNode[] = []; - - api.forEachNode((node: RowNode) => { - if (node.data) { - if (idSet.has(node.data.id)) { - switch (event.event) { - case 'favorite': { - if (node.data.userFavorite !== event.favorite) { - node.setDataValue('userFavorite', event.favorite); - } - break; - } - case 'play': - if (node.data.lastPlayedAt !== event.timestamp) { - node.setData({ - ...node.data, - lastPlayedAt: event.timestamp, - playCount: node.data.playCount + 1, - }); - } - node.data.lastPlayedAt = event.timestamp; - break; - case 'rating': { - if (node.data.userRating !== event.rating) { - node.setDataValue('userRating', event.rating); - rowNodes.push(node); - } - break; - } - } - } - } - }); - - if (rowNodes.length > 0) { - api.redrawRows({ rowNodes }); - } - }, - [tableRef], - ); - - useSongChange(handler, server?.type === ServerType.NAVIDROME); -}; diff --git a/src/renderer/hooks/use-song-change.ts b/src/renderer/hooks/use-song-change.ts index 3e25a330..a6c008bb 100644 --- a/src/renderer/hooks/use-song-change.ts +++ b/src/renderer/hooks/use-song-change.ts @@ -33,36 +33,37 @@ export const useTableChange = ( if (!api) return; const rowNodes: RowNode[] = []; - for (const id of ids) { - const node: RowNode | undefined = api.getRowNode(id); - if (node && node.data) { - switch (event.event) { - case 'favorite': { - if (node.data.userFavorite !== event.favorite) { - node.setDataValue('userFavorite', event.favorite); - } - break; + const idSet = new Set(ids); + + api.forEachNode((node: RowNode) => { + if (!node.data || !idSet.has(node.data.id)) return; + + switch (event.event) { + case 'favorite': { + if (node.data.userFavorite !== event.favorite) { + node.setDataValue('userFavorite', event.favorite); } - case 'play': - if (node.data.lastPlayedAt !== event.timestamp) { - node.setData({ - ...node.data, - lastPlayedAt: event.timestamp, - playCount: node.data.playCount + 1, - }); - } - node.data.lastPlayedAt = event.timestamp; - break; - case 'rating': { - if (node.data.userRating !== event.rating) { - node.setDataValue('userRating', event.rating); - rowNodes.push(node); - } - break; + break; + } + case 'play': + if (node.data.lastPlayedAt !== event.timestamp) { + node.setData({ + ...node.data, + lastPlayedAt: event.timestamp, + playCount: node.data.playCount + 1, + }); } + node.data.lastPlayedAt = event.timestamp; + break; + case 'rating': { + if (node.data.userRating !== event.rating) { + node.setDataValue('userRating', event.rating); + rowNodes.push(node); + } + break; } } - } + }); // This is required to redraw star rows if (rowNodes.length > 0) {