fix(downloads): keep collapse rows mounted across viewport
This commit is contained in:
@@ -3,6 +3,7 @@ import { buildDownloadLogicalRows, type DownloadLogicalRow } from "./downloads-m
|
||||
import {
|
||||
activateDownloadDisclosureTransition,
|
||||
DOWNLOAD_DISCLOSURE_DURATION_MS,
|
||||
getDownloadDisclosurePinnedIds,
|
||||
mergeDownloadDisclosureRows,
|
||||
prepareDownloadDisclosureTransition,
|
||||
scheduleDownloadDisclosureActivation,
|
||||
@@ -98,6 +99,7 @@ export function VirtualizedDownloadsBody({ actions, model, state }: { actions: D
|
||||
desiredRowsRef.current = desiredRows;
|
||||
const previousRowsRef = useRef<readonly DownloadLogicalRow[]>(desiredRows);
|
||||
const transitionRowsRef = useRef<DownloadDisclosureRow[] | null>(null);
|
||||
const transitionPinnedIdsRef = useRef<string[]>([]);
|
||||
const [transitionRows, setTransitionRows] = useState<DownloadDisclosureRow[] | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -108,10 +110,16 @@ export function VirtualizedDownloadsBody({ actions, model, state }: { actions: D
|
||||
const prepared = prepareDownloadDisclosureTransition(transitionRowsRef.current ?? previousRowsRef.current, desiredRowsRef.current);
|
||||
if (!prepared.animated) {
|
||||
transitionRowsRef.current = null;
|
||||
transitionPinnedIdsRef.current = [];
|
||||
previousRowsRef.current = desiredRowsRef.current;
|
||||
setTransitionRows(null);
|
||||
return;
|
||||
}
|
||||
transitionPinnedIdsRef.current = getDownloadDisclosurePinnedIds(prepared.rows, {
|
||||
scrollTop: viewport.scrollTop,
|
||||
viewportHeight: viewport.viewportHeight,
|
||||
overscan: DOWNLOAD_VIRTUAL_OVERSCAN_ROWS
|
||||
});
|
||||
transitionRowsRef.current = prepared.rows;
|
||||
setTransitionRows(prepared.rows);
|
||||
let settleTimer = 0;
|
||||
@@ -122,6 +130,7 @@ export function VirtualizedDownloadsBody({ actions, model, state }: { actions: D
|
||||
settleTimer = window.setTimeout(() => {
|
||||
previousRowsRef.current = desiredRowsRef.current;
|
||||
transitionRowsRef.current = null;
|
||||
transitionPinnedIdsRef.current = [];
|
||||
setTransitionRows(null);
|
||||
}, DOWNLOAD_DISCLOSURE_DURATION_MS);
|
||||
});
|
||||
@@ -136,7 +145,7 @@ export function VirtualizedDownloadsBody({ actions, model, state }: { actions: D
|
||||
scrollTop: viewport.scrollTop,
|
||||
viewportHeight: viewport.viewportHeight,
|
||||
overscan: DOWNLOAD_VIRTUAL_OVERSCAN_ROWS,
|
||||
pinnedIds: [model.editingPackageId]
|
||||
pinnedIds: [model.editingPackageId, ...transitionPinnedIdsRef.current]
|
||||
}), [model.editingPackageId, renderedRows, viewport.scrollTop, viewport.viewportHeight]);
|
||||
const spacerStyle = { "--downloads-virtual-total-height": `${virtualWindow.totalHeight}px` } as CSSProperties;
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { DownloadLogicalRow } from "./downloads-model";
|
||||
import { DOWNLOAD_FILE_ROW_HEIGHT } from "./download-virtualizer";
|
||||
import {
|
||||
DOWNLOAD_FILE_ROW_HEIGHT,
|
||||
calculateDownloadVirtualWindow,
|
||||
type DownloadVirtualWindowOptions
|
||||
} from "./download-virtualizer";
|
||||
|
||||
export const DOWNLOAD_DISCLOSURE_DURATION_MS = 300;
|
||||
export const DOWNLOAD_DISCLOSURE_MAX_ANIMATED_ITEMS = 64;
|
||||
@@ -149,3 +153,13 @@ export function activateDownloadDisclosureTransition(rows: readonly DownloadDisc
|
||||
: { ...row, height: 0, disclosureOpacity: 0 };
|
||||
});
|
||||
}
|
||||
|
||||
export function getDownloadDisclosurePinnedIds(
|
||||
preparedRows: readonly DownloadDisclosureRow[],
|
||||
options: DownloadVirtualWindowOptions
|
||||
): string[] {
|
||||
const windowOptions = { ...options, pinnedIds: [] };
|
||||
const startRows = calculateDownloadVirtualWindow(preparedRows, windowOptions).rows;
|
||||
const targetRows = calculateDownloadVirtualWindow(activateDownloadDisclosureTransition(preparedRows), windowOptions).rows;
|
||||
return [...new Set([...startRows, ...targetRows].map((entry) => entry.id))];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user