From 8c91f1c52df84b41c046af30839df6ff85cc2ee1 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sat, 3 Jan 2026 03:23:58 -0800 Subject: [PATCH] remove scroll shadows from fullscreen player --- .../item-table-list/item-table-list.tsx | 16 +- .../now-playing/components/play-queue.tsx | 322 +++++++++--------- .../components/full-screen-player-queue.tsx | 6 +- .../components/similar-songs-list.tsx | 1 + 4 files changed, 182 insertions(+), 163 deletions(-) diff --git a/src/renderer/components/item-list/item-table-list/item-table-list.tsx b/src/renderer/components/item-list/item-table-list/item-table-list.tsx index 727884395..aa8dc4a28 100644 --- a/src/renderer/components/item-list/item-table-list/item-table-list.tsx +++ b/src/renderer/components/item-list/item-table-list/item-table-list.tsx @@ -103,6 +103,7 @@ interface VirtualizedTableGridProps { enableHeader: boolean; enableHorizontalBorders: boolean; enableRowHoverHighlight: boolean; + enableScrollShadow: boolean; enableSelection: boolean; enableVerticalBorders: boolean; getRowHeight: (index: number, cellProps: TableItemProps) => number; @@ -146,6 +147,7 @@ const VirtualizedTableGrid = ({ enableHeader, enableHorizontalBorders, enableRowHoverHighlight, + enableScrollShadow, enableSelection, enableVerticalBorders, getRowHeight, @@ -429,7 +431,7 @@ const VirtualizedTableGrid = ({ /> )} - {enableHeader && showTopShadow && ( + {enableHeader && enableScrollShadow && showTopShadow && (
)} {!!pinnedLeftColumnCount && ( @@ -489,7 +491,7 @@ const VirtualizedTableGrid = ({ />
)} - {enableHeader && showTopShadow && ( + {enableHeader && enableScrollShadow && showTopShadow && (
)}
@@ -507,10 +509,10 @@ const VirtualizedTableGrid = ({ return getRowHeight(index + pinnedRowCount, cellProps); }} /> - {pinnedLeftColumnCount > 0 && showLeftShadow && ( + {pinnedLeftColumnCount > 0 && enableScrollShadow && showLeftShadow && (
)} - {pinnedRightColumnCount > 0 && showRightShadow && ( + {pinnedRightColumnCount > 0 && enableScrollShadow && showRightShadow && (
)}
@@ -560,7 +562,7 @@ const VirtualizedTableGrid = ({ />
)} - {enableHeader && showTopShadow && ( + {enableHeader && enableScrollShadow && showTopShadow && (
)}
(({ listKey, searchTerm }, ref) => { - const { table } = useListSettings(listKey) || {}; +export const PlayQueue = forwardRef( + ({ enableScrollShadow = true, listKey, searchTerm }, ref) => { + const { table } = useListSettings(listKey) || {}; - const isFetching = useIsPlayerFetching(); - const tableRef = useRef(null); - const mergedRef = useMergedRef(ref, tableRef); - const { getQueue } = usePlayerActions(); - const queueType = usePlayerQueueType(); - const followCurrentSong = useFollowCurrentSong(); + const isFetching = useIsPlayerFetching(); + const tableRef = useRef(null); + const mergedRef = useMergedRef(ref, tableRef); + const { getQueue } = usePlayerActions(); + const queueType = usePlayerQueueType(); + const followCurrentSong = useFollowCurrentSong(); - const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 200); + const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 200); - const [data, setData] = useState([]); - const [groups, setGroups] = useState([]); + const [data, setData] = useState([]); + const [groups, setGroups] = useState([]); - useEffect(() => { - const setQueue = () => { - const queue = getQueue() || { groups: [], items: [] }; + useEffect(() => { + const setQueue = () => { + const queue = getQueue() || { groups: [], items: [] }; - setData(queue.items); + setData(queue.items); - if (queueType === PlayerQueueType.PRIORITY && queue.groups && queue.groups.length > 0) { - const transformedGroups: TableGroupHeader[] = queue.groups.map((group) => ({ - itemCount: group.count, - render: (): ReactElement => { - return ( -
- - {group.name} - -
- ); - }, - rowHeight: 40, - })); - setGroups(transformedGroups); - } else { - setGroups([]); - } - }; - - const unsub = subscribePlayerQueue(() => { - setQueue(); - }); - - const unsubCurrentTrack = subscribeCurrentTrack((e) => { - if (followCurrentSong && e.index !== -1) { - tableRef.current?.scrollToIndex(e.index, { - align: 'center', - behavior: 'auto', - }); - } - }); - - const handleAutoDJQueueAdded = () => { - if (followCurrentSong) { - const state = usePlayerStore.getState(); - let index = state.player.index; - - if (isShuffleEnabled(state)) { - index = mapShuffledToQueueIndex(index, state.queue.shuffled); + if ( + queueType === PlayerQueueType.PRIORITY && + queue.groups && + queue.groups.length > 0 + ) { + const transformedGroups: TableGroupHeader[] = queue.groups.map((group) => ({ + itemCount: group.count, + render: (): ReactElement => { + return ( +
+ + {group.name} + +
+ ); + }, + rowHeight: 40, + })); + setGroups(transformedGroups); + } else { + setGroups([]); } + }; - if (index !== -1) { - // Use setTimeout to ensure the DOM has updated with the new queue items - setTimeout(() => { - tableRef.current?.scrollToIndex(index, { - align: 'center', - behavior: 'auto', - }); - }, 0); + const unsub = subscribePlayerQueue(() => { + setQueue(); + }); + + const unsubCurrentTrack = subscribeCurrentTrack((e) => { + if (followCurrentSong && e.index !== -1) { + tableRef.current?.scrollToIndex(e.index, { + align: 'center', + behavior: 'auto', + }); } - } - }; + }); - eventEmitter.on('AUTODJ_QUEUE_ADDED', handleAutoDJQueueAdded); + const handleAutoDJQueueAdded = () => { + if (followCurrentSong) { + const state = usePlayerStore.getState(); + let index = state.player.index; - setQueue(); - - return () => { - unsub(); - unsubCurrentTrack(); - eventEmitter.off('AUTODJ_QUEUE_ADDED', handleAutoDJQueueAdded); - }; - }, [getQueue, queueType, tableRef, followCurrentSong]); - - const filteredData: QueueSong[] = useMemo(() => { - if (debouncedSearchTerm) { - const searched = searchLibraryItems(data, debouncedSearchTerm, LibraryItem.SONG); - return searched; - } - - return data; - }, [data, debouncedSearchTerm]); - - const isEmpty = filteredData.length === 0; - - const { handleColumnReordered } = useItemListColumnReorder({ - itemListKey: listKey, - }); - - const { handleColumnResized } = useItemListColumnResize({ - itemListKey: listKey, - }); - - const currentSong = usePlayerSong(); - - const currentSongUniqueId = currentSong?._uniqueId; - - const { focused, ref: containerFocusRef } = useFocusWithin(); - const player = usePlayer(); - - useHotkeys([ - [ - 'delete', - () => { - if (focused) { - const selectedItems = - tableRef.current?.internalState.getSelected() as QueueSong[]; - - if (!selectedItems || selectedItems.length === 0) { - return; + if (isShuffleEnabled(state)) { + index = mapShuffledToQueueIndex(index, state.queue.shuffled); } - player.clearSelected(selectedItems); + if (index !== -1) { + // Use setTimeout to ensure the DOM has updated with the new queue items + setTimeout(() => { + tableRef.current?.scrollToIndex(index, { + align: 'center', + behavior: 'auto', + }); + }, 0); + } } - }, - ], - ]); + }; - return ( -
- - 0 ? groups : undefined} - initialTop={{ - to: 0, - type: 'offset', - }} - itemType={LibraryItem.QUEUE_SONG} - onColumnReordered={handleColumnReordered} - onColumnResized={handleColumnResized} - ref={mergedRef} - size={table.size} - /> - {isEmpty && } -
- ); -}); + eventEmitter.on('AUTODJ_QUEUE_ADDED', handleAutoDJQueueAdded); + + setQueue(); + + return () => { + unsub(); + unsubCurrentTrack(); + eventEmitter.off('AUTODJ_QUEUE_ADDED', handleAutoDJQueueAdded); + }; + }, [getQueue, queueType, tableRef, followCurrentSong]); + + const filteredData: QueueSong[] = useMemo(() => { + if (debouncedSearchTerm) { + const searched = searchLibraryItems(data, debouncedSearchTerm, LibraryItem.SONG); + return searched; + } + + return data; + }, [data, debouncedSearchTerm]); + + const isEmpty = filteredData.length === 0; + + const { handleColumnReordered } = useItemListColumnReorder({ + itemListKey: listKey, + }); + + const { handleColumnResized } = useItemListColumnResize({ + itemListKey: listKey, + }); + + const currentSong = usePlayerSong(); + + const currentSongUniqueId = currentSong?._uniqueId; + + const { focused, ref: containerFocusRef } = useFocusWithin(); + const player = usePlayer(); + + useHotkeys([ + [ + 'delete', + () => { + if (focused) { + const selectedItems = + tableRef.current?.internalState.getSelected() as QueueSong[]; + + if (!selectedItems || selectedItems.length === 0) { + return; + } + + player.clearSelected(selectedItems); + } + }, + ], + ]); + + return ( +
+ + 0 ? groups : undefined} + initialTop={{ + to: 0, + type: 'offset', + }} + itemType={LibraryItem.QUEUE_SONG} + onColumnReordered={handleColumnReordered} + onColumnResized={handleColumnResized} + ref={mergedRef} + size={table.size} + /> + {isEmpty && } +
+ ); + }, +); const EmptyQueueDropZone = () => { const playerContext = usePlayer(); diff --git a/src/renderer/features/player/components/full-screen-player-queue.tsx b/src/renderer/features/player/components/full-screen-player-queue.tsx index e65e26b33..2f46fed68 100644 --- a/src/renderer/features/player/components/full-screen-player-queue.tsx +++ b/src/renderer/features/player/components/full-screen-player-queue.tsx @@ -106,7 +106,11 @@ export const FullScreenPlayerQueue = () => { {activeTab === 'queue' ? (
- +
) : activeTab === 'related' ? (
diff --git a/src/renderer/features/similar-songs/components/similar-songs-list.tsx b/src/renderer/features/similar-songs/components/similar-songs-list.tsx index 048351988..41350e9ae 100644 --- a/src/renderer/features/similar-songs/components/similar-songs-list.tsx +++ b/src/renderer/features/similar-songs/components/similar-songs-list.tsx @@ -64,6 +64,7 @@ export const SimilarSongsList = ({ count, song }: SimilarSongsListProps) => { enableHeader enableHorizontalBorders={fullScreenTable?.enableHorizontalBorders} enableRowHoverHighlight={fullScreenTable?.enableRowHoverHighlight} + enableScrollShadow={false} enableSelection enableSelectionDialog={false} enableVerticalBorders={fullScreenTable?.enableVerticalBorders}