fix queue scroll follow with album group

This commit is contained in:
jeffvli
2026-07-10 02:13:52 -07:00
parent 67a2be1559
commit 5804eb3215
5 changed files with 212 additions and 214 deletions
@@ -4,11 +4,15 @@ import { ItemListStateActions } from '/@/renderer/components/item-list/helpers/i
import { ItemListHandle } from '/@/renderer/components/item-list/types'; import { ItemListHandle } from '/@/renderer/components/item-list/types';
interface UseTableImperativeHandleProps { interface UseTableImperativeHandleProps {
autoScrollToActiveRow: boolean;
enableHeader: boolean; enableHeader: boolean;
handleRef: React.RefObject<ItemListHandle | null>; handleRef: React.RefObject<ItemListHandle | null>;
internalState: ItemListStateActions; internalState: ItemListStateActions;
ref?: React.Ref<ItemListHandle>; ref?: React.Ref<ItemListHandle>;
scrollToTableIndex: (index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => void; scrollToTableIndex: (
index: number,
options?: { align?: 'bottom' | 'center' | 'top'; followActiveRow?: boolean },
) => void;
scrollToTableOffset: (offset: number) => void; scrollToTableOffset: (offset: number) => void;
} }
@@ -16,6 +20,7 @@ interface UseTableImperativeHandleProps {
* Hook to set up the imperative handle for ItemTableList, providing scroll methods and internal state. * Hook to set up the imperative handle for ItemTableList, providing scroll methods and internal state.
*/ */
export const useTableImperativeHandle = ({ export const useTableImperativeHandle = ({
autoScrollToActiveRow,
enableHeader, enableHeader,
handleRef, handleRef,
internalState, internalState,
@@ -27,13 +32,22 @@ export const useTableImperativeHandle = ({
() => ({ () => ({
internalState, internalState,
scrollToIndex: (index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => { scrollToIndex: (index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => {
scrollToTableIndex(enableHeader ? index + 1 : index, options); scrollToTableIndex(enableHeader ? index + 1 : index, {
...options,
followActiveRow: autoScrollToActiveRow,
});
}, },
scrollToOffset: (offset: number) => { scrollToOffset: (offset: number) => {
scrollToTableOffset(offset); scrollToTableOffset(offset);
}, },
}), }),
[enableHeader, internalState, scrollToTableIndex, scrollToTableOffset], [
autoScrollToActiveRow,
enableHeader,
internalState,
scrollToTableIndex,
scrollToTableOffset,
],
); );
useImperativeHandle(ref, () => imperativeHandle); useImperativeHandle(ref, () => imperativeHandle);
@@ -4,21 +4,17 @@ import {
ItemListStateActions, ItemListStateActions,
ItemListStateItemWithRequiredProperties, ItemListStateItemWithRequiredProperties,
} from '/@/renderer/components/item-list/helpers/item-list-state'; } from '/@/renderer/components/item-list/helpers/item-list-state';
import { TableItemProps } from '/@/renderer/components/item-list/item-table-list/item-table-list';
import { ItemControls } from '/@/renderer/components/item-list/types';
import { PlayerContext } from '/@/renderer/features/player/context/player-context';
import { LibraryItem } from '/@/shared/types/domain-types'; import { LibraryItem } from '/@/shared/types/domain-types';
interface UseTableKeyboardNavigationProps { interface UseTableKeyboardNavigationProps {
calculateScrollTopForIndex: (index: number) => number; calculateScrollTopForIndex: (index: number) => number;
cellPadding: TableItemProps['cellPadding'];
data: unknown[]; data: unknown[];
DEFAULT_ROW_HEIGHT: number;
enableHeader: boolean; enableHeader: boolean;
enableSelection: boolean; enableSelection: boolean;
extractRowId: (item: unknown) => string | undefined; extractRowId: (item: unknown) => string | undefined;
getItem?: (index: number) => undefined | unknown; getItem?: (index: number) => undefined | unknown;
getItemIndex?: (rowId: string) => number | undefined; getItemIndex?: (rowId: string) => number | undefined;
getRowHeightAtIndex: (index: number) => number;
getStateItem: (item: any) => ItemListStateItemWithRequiredProperties | null; getStateItem: (item: any) => ItemListStateItemWithRequiredProperties | null;
hasRequiredStateItemProperties: ( hasRequiredStateItemProperties: (
item: unknown, item: unknown,
@@ -26,15 +22,10 @@ interface UseTableKeyboardNavigationProps {
internalState: ItemListStateActions; internalState: ItemListStateActions;
itemCount?: number; itemCount?: number;
itemType: LibraryItem; itemType: LibraryItem;
parsedColumns: TableItemProps['columns'];
pinnedRightColumnCount: number; pinnedRightColumnCount: number;
pinnedRightColumnRef: React.RefObject<HTMLDivElement | null>; pinnedRightColumnRef: React.RefObject<HTMLDivElement | null>;
playerContext: PlayerContext;
rowHeight: ((index: number, cellProps: TableItemProps) => number) | number | undefined;
rowRef: React.RefObject<HTMLDivElement | null>; rowRef: React.RefObject<HTMLDivElement | null>;
scrollToTableIndex: (index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => void; scrollToTableIndex: (index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => void;
size: TableItemProps['size'];
tableId: string;
} }
/** /**
@@ -42,28 +33,21 @@ interface UseTableKeyboardNavigationProps {
*/ */
export const useTableKeyboardNavigation = ({ export const useTableKeyboardNavigation = ({
calculateScrollTopForIndex, calculateScrollTopForIndex,
cellPadding,
data, data,
DEFAULT_ROW_HEIGHT,
enableHeader, enableHeader,
enableSelection, enableSelection,
extractRowId, extractRowId,
getItem, getItem,
getItemIndex, getItemIndex,
getRowHeightAtIndex,
getStateItem, getStateItem,
hasRequiredStateItemProperties, hasRequiredStateItemProperties,
internalState, internalState,
itemCount, itemCount,
itemType,
parsedColumns,
pinnedRightColumnCount, pinnedRightColumnCount,
pinnedRightColumnRef, pinnedRightColumnRef,
playerContext,
rowHeight,
rowRef, rowRef,
scrollToTableIndex, scrollToTableIndex,
size,
tableId,
}: UseTableKeyboardNavigationProps) => { }: UseTableKeyboardNavigationProps) => {
const handleKeyDown = useCallback( const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLDivElement>) => { (e: React.KeyboardEvent<HTMLDivElement>) => {
@@ -122,42 +106,7 @@ export const useTableKeyboardNavigation = ({
const viewportBottom = viewportTop + viewportHeight; const viewportBottom = viewportTop + viewportHeight;
const rowTop = calculateScrollTopForIndex(gridIndex); const rowTop = calculateScrollTopForIndex(gridIndex);
const adjustedIndex = enableHeader ? Math.max(0, newIndex - 1) : newIndex; const calculatedRowHeight = getRowHeightAtIndex(gridIndex);
const mockCellProps: TableItemProps = {
cellPadding,
columns: parsedColumns,
controls: {} as ItemControls,
data: enableHeader ? [null] : [],
enableAlternateRowColors: false,
enableExpansion: false,
enableHeader,
enableHorizontalBorders: false,
enableRowHoverHighlight: false,
enableSelection,
enableVerticalBorders: false,
getRowHeight: () => DEFAULT_ROW_HEIGHT,
getRowItem: (rowIndex: number) => {
if (!getItem) return undefined;
if (enableHeader && rowIndex === 0) return null;
const dataIndex = enableHeader ? rowIndex - 1 : rowIndex;
return getItem(dataIndex);
},
internalState: {} as ItemListStateActions,
itemType,
playerContext,
size,
tableId,
};
let calculatedRowHeight: number;
if (typeof rowHeight === 'number') {
calculatedRowHeight = rowHeight;
} else if (typeof rowHeight === 'function') {
calculatedRowHeight = rowHeight(adjustedIndex, mockCellProps);
} else {
calculatedRowHeight = DEFAULT_ROW_HEIGHT;
}
const rowBottom = rowTop + calculatedRowHeight; const rowBottom = rowTop + calculatedRowHeight;
// Check if row is fully visible within viewport // Check if row is fully visible within viewport
@@ -187,28 +136,21 @@ export const useTableKeyboardNavigation = ({
}, },
[ [
calculateScrollTopForIndex, calculateScrollTopForIndex,
cellPadding,
data, data,
getItem, getItem,
getItemIndex, getItemIndex,
DEFAULT_ROW_HEIGHT,
enableHeader, enableHeader,
enableSelection, enableSelection,
extractRowId, extractRowId,
getRowHeightAtIndex,
getStateItem, getStateItem,
hasRequiredStateItemProperties, hasRequiredStateItemProperties,
internalState, internalState,
itemCount, itemCount,
itemType,
parsedColumns,
pinnedRightColumnCount, pinnedRightColumnCount,
pinnedRightColumnRef, pinnedRightColumnRef,
playerContext,
rowHeight,
rowRef, rowRef,
scrollToTableIndex, scrollToTableIndex,
size,
tableId,
], ],
); );
@@ -1,101 +1,45 @@
import { useCallback, useMemo } from 'react'; import { useCallback, useEffect, useMemo, useRef } from 'react';
import { TableItemProps } from '../item-table-list'; import { TableItemProps } from '../item-table-list';
import { ItemListStateActions } from '/@/renderer/components/item-list/helpers/item-list-state'; export type TableScrollToIndexOptions = {
import { ItemControls } from '/@/renderer/components/item-list/types'; align?: 'bottom' | 'center' | 'top';
import { PlayerContext } from '/@/renderer/features/player/context/player-context'; followActiveRow?: boolean;
import { LibraryItem } from '/@/shared/types/domain-types'; };
export const useTableScrollToIndex = ({ export const useTableScrollToIndex = ({
cellPadding, albumGroupContentHeights,
columns, autoScrollToActiveRow,
data,
enableAlternateRowColors,
enableExpansion,
enableHeader, enableHeader,
enableHorizontalBorders, getRowHeight,
enableRowHoverHighlight, hasAlbumGroupColumn,
enableSelection,
enableVerticalBorders,
itemType,
pinnedLeftColumnRef, pinnedLeftColumnRef,
pinnedRightColumnRef, pinnedRightColumnRef,
playerContext, pinnedRowCount,
rowHeight,
rowRef, rowRef,
size, scrollCellProps,
tableId,
}: { }: {
cellPadding: 'lg' | 'md' | 'sm' | 'xl' | 'xs'; albumGroupContentHeights: Map<number, number>;
columns: TableItemProps['columns']; autoScrollToActiveRow: boolean;
data: unknown[];
enableAlternateRowColors: boolean;
enableExpansion: boolean;
enableHeader: boolean; enableHeader: boolean;
enableHorizontalBorders: boolean; getRowHeight: (index: number, cellProps: TableItemProps) => number;
enableRowHoverHighlight: boolean; hasAlbumGroupColumn: boolean;
enableSelection: boolean;
enableVerticalBorders: boolean;
itemType: LibraryItem;
pinnedLeftColumnRef: React.RefObject<HTMLDivElement | null>; pinnedLeftColumnRef: React.RefObject<HTMLDivElement | null>;
pinnedRightColumnRef: React.RefObject<HTMLDivElement | null>; pinnedRightColumnRef: React.RefObject<HTMLDivElement | null>;
playerContext: PlayerContext; pinnedRowCount: number;
rowHeight: ((index: number, cellProps: TableItemProps) => number) | number | undefined;
rowRef: React.RefObject<HTMLDivElement | null>; rowRef: React.RefObject<HTMLDivElement | null>;
size: 'compact' | 'default' | 'large'; scrollCellProps: TableItemProps;
tableId: string;
}) => { }) => {
const DEFAULT_ROW_HEIGHT = useMemo(() => { const isProgrammaticScrollRef = useRef(false);
return size === 'compact' ? 40 : size === 'large' ? 88 : 64; const userInterruptedFollowRef = useRef(false);
}, [size]); const pendingFollowScrollRef = useRef<null | {
index: number;
const mockCellPropsBase = useMemo<TableItemProps>( options?: TableScrollToIndexOptions;
() => ({ }>(null);
cellPadding,
columns,
controls: {} as ItemControls,
data: enableHeader ? [null, ...data] : data,
enableAlternateRowColors,
enableExpansion,
enableHeader,
enableHorizontalBorders,
enableRowHoverHighlight,
enableSelection,
enableVerticalBorders,
getRowHeight: () => DEFAULT_ROW_HEIGHT,
internalState: {} as ItemListStateActions,
itemType,
playerContext,
size,
tableId,
}),
[
DEFAULT_ROW_HEIGHT,
cellPadding,
columns,
data,
enableAlternateRowColors,
enableExpansion,
enableHeader,
enableHorizontalBorders,
enableRowHoverHighlight,
enableSelection,
enableVerticalBorders,
itemType,
playerContext,
size,
tableId,
],
);
const getRowHeightAtIndex = useCallback( const getRowHeightAtIndex = useCallback(
(index: number) => { (index: number) => getRowHeight(index, scrollCellProps),
if (typeof rowHeight === 'number') return rowHeight; [getRowHeight, scrollCellProps],
if (typeof rowHeight === 'function') return rowHeight(index, mockCellPropsBase);
return DEFAULT_ROW_HEIGHT;
},
[DEFAULT_ROW_HEIGHT, mockCellPropsBase, rowHeight],
); );
const scrollToTableOffset = useCallback( const scrollToTableOffset = useCallback(
@@ -110,6 +54,8 @@ export const useTableScrollToIndex = ({
const behavior = 'instant'; const behavior = 'instant';
isProgrammaticScrollRef.current = true;
if (mainContainer) { if (mainContainer) {
mainContainer.scrollTo({ behavior, top: offset }); mainContainer.scrollTo({ behavior, top: offset });
} }
@@ -119,37 +65,38 @@ export const useTableScrollToIndex = ({
if (pinnedRightContainer) { if (pinnedRightContainer) {
pinnedRightContainer.scrollTo({ behavior, top: offset }); pinnedRightContainer.scrollTo({ behavior, top: offset });
} }
requestAnimationFrame(() => {
isProgrammaticScrollRef.current = false;
});
}, },
[pinnedLeftColumnRef, pinnedRightColumnRef, rowRef], [pinnedLeftColumnRef, pinnedRightColumnRef, rowRef],
); );
const scrollRowOffset = enableHeader ? pinnedRowCount : 0;
const calculateScrollTopForIndex = useCallback( const calculateScrollTopForIndex = useCallback(
(index: number) => { (index: number) => {
const adjustedIndex = enableHeader ? Math.max(0, index - 1) : index;
let scrollTop = 0; let scrollTop = 0;
for (let i = 0; i < adjustedIndex; i++) { for (let i = scrollRowOffset; i < index; i++) {
scrollTop += getRowHeightAtIndex(i); scrollTop += getRowHeightAtIndex(i);
} }
return scrollTop; return scrollTop;
}, },
[enableHeader, getRowHeightAtIndex], [getRowHeightAtIndex, scrollRowOffset],
); );
const scrollToTableIndex = useCallback( const applyScrollToIndex = useCallback(
(index: number, options?: { align?: 'bottom' | 'center' | 'top' }) => { (index: number, options?: TableScrollToIndexOptions) => {
const mainContainer = rowRef.current?.childNodes[0] as HTMLDivElement | undefined; const mainContainer = rowRef.current?.childNodes[0] as HTMLDivElement | undefined;
if (!mainContainer) return; if (!mainContainer) return;
const viewportHeight = mainContainer.clientHeight; const viewportHeight = mainContainer.clientHeight;
const align = options?.align || 'top'; const align = options?.align || 'top';
// Calculate the base scroll offset (top of the row)
let offset = calculateScrollTopForIndex(index); let offset = calculateScrollTopForIndex(index);
const targetRowHeight = getRowHeightAtIndex(index);
// Calculate row height for the target index
const adjustedIndex = enableHeader ? Math.max(0, index - 1) : index;
const targetRowHeight = getRowHeightAtIndex(adjustedIndex);
if (align === 'center') { if (align === 'center') {
offset = offset - viewportHeight / 2 + targetRowHeight / 2; offset = offset - viewportHeight / 2 + targetRowHeight / 2;
@@ -160,22 +107,64 @@ export const useTableScrollToIndex = ({
offset = Math.max(0, offset); offset = Math.max(0, offset);
scrollToTableOffset(offset); scrollToTableOffset(offset);
}, },
[ [calculateScrollTopForIndex, getRowHeightAtIndex, rowRef, scrollToTableOffset],
calculateScrollTopForIndex,
enableHeader,
getRowHeightAtIndex,
rowRef,
scrollToTableOffset,
],
); );
const scrollToTableIndex = useCallback(
(index: number, options?: TableScrollToIndexOptions) => {
const shouldFollow = autoScrollToActiveRow && options?.followActiveRow;
if (shouldFollow) {
pendingFollowScrollRef.current = { index, options };
userInterruptedFollowRef.current = false;
}
applyScrollToIndex(index, options);
},
[applyScrollToIndex, autoScrollToActiveRow],
);
useEffect(() => {
const viewport = rowRef.current?.childNodes[0] as HTMLDivElement | undefined;
if (!viewport) return;
const handleUserScroll = () => {
if (isProgrammaticScrollRef.current) return;
userInterruptedFollowRef.current = true;
pendingFollowScrollRef.current = null;
};
viewport.addEventListener('scroll', handleUserScroll, { passive: true });
return () => viewport.removeEventListener('scroll', handleUserScroll);
}, [rowRef]);
useEffect(() => {
if (!autoScrollToActiveRow || !hasAlbumGroupColumn) return;
const pending = pendingFollowScrollRef.current;
if (!pending || userInterruptedFollowRef.current) return;
if (albumGroupContentHeights.size === 0) return;
const timeout = window.setTimeout(() => {
if (userInterruptedFollowRef.current) return;
const currentPending = pendingFollowScrollRef.current;
if (!currentPending) return;
applyScrollToIndex(currentPending.index, currentPending.options);
}, 50);
return () => window.clearTimeout(timeout);
}, [albumGroupContentHeights, applyScrollToIndex, autoScrollToActiveRow, hasAlbumGroupColumn]);
return useMemo( return useMemo(
() => ({ () => ({
calculateScrollTopForIndex, calculateScrollTopForIndex,
DEFAULT_ROW_HEIGHT, getRowHeightAtIndex,
scrollToTableIndex, scrollToTableIndex,
scrollToTableOffset, scrollToTableOffset,
}), }),
[calculateScrollTopForIndex, DEFAULT_ROW_HEIGHT, scrollToTableIndex, scrollToTableOffset], [calculateScrollTopForIndex, getRowHeightAtIndex, scrollToTableIndex, scrollToTableOffset],
); );
}; };
@@ -816,6 +816,7 @@ export interface TableItemProps {
interface ItemTableListProps { interface ItemTableListProps {
activeRowId?: string; activeRowId?: string;
autoFitColumns?: boolean; autoFitColumns?: boolean;
autoScrollToActiveRow?: boolean;
CellComponent?: JSXElementConstructor<CellComponentProps<TableItemProps>>; CellComponent?: JSXElementConstructor<CellComponentProps<TableItemProps>>;
cellPadding?: 'lg' | 'md' | 'sm' | 'xl' | 'xs'; cellPadding?: 'lg' | 'md' | 'sm' | 'xl' | 'xs';
columns: ItemTableListColumnConfig[]; columns: ItemTableListColumnConfig[];
@@ -1255,6 +1256,7 @@ ItemTableListStickyUI.displayName = 'ItemTableListStickyUI';
const BaseItemTableList = ({ const BaseItemTableList = ({
activeRowId, activeRowId,
autoFitColumns = false, autoFitColumns = false,
autoScrollToActiveRow = false,
CellComponent = ItemTableListColumn, CellComponent = ItemTableListColumn,
cellPadding = 'sm', cellPadding = 'sm',
columns, columns,
@@ -1411,47 +1413,10 @@ const BaseItemTableList = ({
onScrollEndRef.current = onScrollEnd; onScrollEndRef.current = onScrollEnd;
}, [onScrollEnd]); }, [onScrollEnd]);
const { const hasAlbumGroupColumn = useMemo(
calculateScrollTopForIndex, () => parsedColumns.some((col) => col.id === TableColumn.ALBUM_GROUP),
DEFAULT_ROW_HEIGHT, [parsedColumns],
scrollToTableIndex, );
scrollToTableOffset,
} = useTableScrollToIndex({
cellPadding,
columns: parsedColumns,
data,
enableAlternateRowColors,
enableExpansion,
enableHeader,
enableHorizontalBorders,
enableRowHoverHighlight,
enableSelection,
enableVerticalBorders,
itemType,
pinnedLeftColumnRef,
pinnedRightColumnRef,
playerContext,
rowHeight,
rowRef,
size,
tableId,
});
useTablePaneSync({
enableDrag,
enableDragScroll,
enableHeader,
handleRef,
onScrollEndRef,
pinnedLeftColumnCount,
pinnedLeftColumnRef,
pinnedRightColumnCount,
pinnedRightColumnRef,
pinnedRowRef,
rowRef,
scrollContainerRef,
scrollShadowStore,
});
const getRowHeight = useCallback( const getRowHeight = useCallback(
(index: number, cellProps: TableItemProps) => { (index: number, cellProps: TableItemProps) => {
@@ -1515,6 +1480,99 @@ const BaseItemTableList = ({
[albumGroupImageSize, enableHeader, headerHeight, rowHeight, pinnedRowCount, size], [albumGroupImageSize, enableHeader, headerHeight, rowHeight, pinnedRowCount, size],
); );
const scrollCellProps = useMemo<TableItemProps>(
() => ({
albumGroupContentHeights,
albumGroupImageSize,
cellPadding,
columns: parsedColumns,
controls: {} as ItemControls,
data: dataWithGroups,
enableAlternateRowColors,
enableExpansion,
enableHeader,
enableHorizontalBorders,
enableRowHoverHighlight,
enableSelection,
enableVerticalBorders,
getRowHeight,
getRowItem: (rowIndex: number) => {
if (shouldUseAccessor && getItem) {
if (enableHeader && rowIndex === 0) {
return null;
}
const dataIndex = enableHeader ? rowIndex - 1 : rowIndex;
return getItem(dataIndex);
}
return dataWithGroups[rowIndex];
},
hasAlbumGroupColumn,
internalState: {} as ItemListStateActions,
itemType,
playerContext,
size,
tableId,
}),
[
albumGroupContentHeights,
albumGroupImageSize,
cellPadding,
dataWithGroups,
enableAlternateRowColors,
enableExpansion,
enableHeader,
enableHorizontalBorders,
enableRowHoverHighlight,
enableSelection,
enableVerticalBorders,
getItem,
getRowHeight,
hasAlbumGroupColumn,
itemType,
parsedColumns,
playerContext,
shouldUseAccessor,
size,
tableId,
],
);
const {
calculateScrollTopForIndex,
getRowHeightAtIndex,
scrollToTableIndex,
scrollToTableOffset,
} = useTableScrollToIndex({
albumGroupContentHeights,
autoScrollToActiveRow,
enableHeader,
getRowHeight,
hasAlbumGroupColumn,
pinnedLeftColumnRef,
pinnedRightColumnRef,
pinnedRowCount,
rowRef,
scrollCellProps,
});
useTablePaneSync({
enableDrag,
enableDragScroll,
enableHeader,
handleRef,
onScrollEndRef,
pinnedLeftColumnCount,
pinnedLeftColumnRef,
pinnedRightColumnCount,
pinnedRightColumnRef,
pinnedRowRef,
rowRef,
scrollContainerRef,
scrollShadowStore,
});
// Create a wrapper for getRowHeight that doesn't require cellProps (for sticky group rows hook) // Create a wrapper for getRowHeight that doesn't require cellProps (for sticky group rows hook)
const getRowHeightWrapper = useCallback( const getRowHeightWrapper = useCallback(
(index: number) => { (index: number) => {
@@ -1574,28 +1632,21 @@ const BaseItemTableList = ({
const { handleKeyDown } = useTableKeyboardNavigation({ const { handleKeyDown } = useTableKeyboardNavigation({
calculateScrollTopForIndex, calculateScrollTopForIndex,
cellPadding,
data, data,
DEFAULT_ROW_HEIGHT,
enableHeader, enableHeader,
enableSelection, enableSelection,
extractRowId, extractRowId,
getItem, getItem,
getItemIndex, getItemIndex,
getRowHeightAtIndex,
getStateItem, getStateItem,
hasRequiredStateItemProperties, hasRequiredStateItemProperties,
internalState, internalState,
itemCount: baseItemCount, itemCount: baseItemCount,
itemType,
parsedColumns,
pinnedRightColumnCount, pinnedRightColumnCount,
pinnedRightColumnRef, pinnedRightColumnRef,
playerContext,
rowHeight,
rowRef, rowRef,
scrollToTableIndex, scrollToTableIndex,
size,
tableId,
}); });
useTableInitialScroll({ useTableInitialScroll({
@@ -1606,6 +1657,7 @@ const BaseItemTableList = ({
}); });
useTableImperativeHandle({ useTableImperativeHandle({
autoScrollToActiveRow,
enableHeader, enableHeader,
handleRef, handleRef,
internalState, internalState,
@@ -179,6 +179,7 @@ export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(
<ItemTableList <ItemTableList
activeRowId={currentSongUniqueId} activeRowId={currentSongUniqueId}
autoFitColumns={table.autoFitColumns} autoFitColumns={table.autoFitColumns}
autoScrollToActiveRow={followCurrentSong}
CellComponent={ItemTableListColumn} CellComponent={ItemTableListColumn}
columns={table.columns} columns={table.columns}
data={filteredData} data={filteredData}