mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-12 05:10:52 +02:00
queue sheet update
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
useState
|
||||
} from 'react';
|
||||
import {
|
||||
InteractionManager,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
View,
|
||||
@@ -77,6 +78,7 @@ import {
|
||||
type QueueIndexByKey,
|
||||
} from './queueActions';
|
||||
import {
|
||||
QUEUE_INITIAL_RENDER_DISTANCE,
|
||||
QUEUE_ROW_HEIGHT,
|
||||
queuePreviewRowCount,
|
||||
queueRenderDistance,
|
||||
@@ -204,9 +206,16 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
|
||||
// the tray's first frame and unmounts once the real list has painted (onLoad
|
||||
// fires a frame after first layout completes, so rows are already underneath).
|
||||
const [listPainted, setListPainted] = useState(false);
|
||||
const onListLoad = useCallback(() => setListPainted(true), []);
|
||||
const listPaintedRef = useRef(false);
|
||||
const onListLoad = useCallback(() => {
|
||||
listPaintedRef.current = true;
|
||||
setListPainted(true);
|
||||
}, []);
|
||||
const [renderCoverageReady, setRenderCoverageReady] = useState(embedded);
|
||||
const previewCount = queuePreviewRowCount(windowHeight);
|
||||
const renderDistance = queueRenderDistance(windowHeight);
|
||||
const renderDistance = renderCoverageReady
|
||||
? queueRenderDistance(windowHeight)
|
||||
: QUEUE_INITIAL_RENDER_DISTANCE;
|
||||
// Bottom padding clears the gesture-nav inset so the last row is fully
|
||||
// scrollable into view at the 100% snap.
|
||||
const listContentStyle = useMemo(
|
||||
@@ -244,27 +253,43 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
|
||||
const virtualLoadQueued = useRef(false);
|
||||
const virtualRetryTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const virtualPageLoaderRef = useRef<(reset: boolean) => Promise<void>>(async () => {});
|
||||
const deferredMountTask = useRef<
|
||||
ReturnType<typeof InteractionManager.runAfterInteractions> | null
|
||||
>(null);
|
||||
|
||||
const resetVirtualTracks = useCallback(() => {
|
||||
virtualLoadGeneration.current += 1;
|
||||
virtualLoadQueued.current = false;
|
||||
if (virtualRetryTimer.current) {
|
||||
clearTimeout(virtualRetryTimer.current);
|
||||
virtualRetryTimer.current = null;
|
||||
}
|
||||
|
||||
const state = getVirtualQueueState();
|
||||
const seed = state
|
||||
? seedVirtualQueueTracks(
|
||||
rollingUpcomingTracksRef.current,
|
||||
state.activePosition,
|
||||
state.totalCount,
|
||||
)
|
||||
: [];
|
||||
const previous = virtualTracksRef.current;
|
||||
const unchanged =
|
||||
seed.length === previous.length &&
|
||||
seed.every((track, index) => track === previous[index]);
|
||||
virtualTracksRef.current = unchanged ? previous : seed;
|
||||
if (!unchanged) setVirtualTracks(seed);
|
||||
return state;
|
||||
}, []);
|
||||
|
||||
const loadVirtualPage = useCallback((reset: boolean): Promise<void> => {
|
||||
if (reset) {
|
||||
virtualLoadGeneration.current += 1;
|
||||
virtualLoadQueued.current = false;
|
||||
if (virtualRetryTimer.current) {
|
||||
clearTimeout(virtualRetryTimer.current);
|
||||
virtualRetryTimer.current = null;
|
||||
if (!embedded && listPaintedRef.current && deferredMountTask.current) {
|
||||
deferredMountTask.current.cancel();
|
||||
deferredMountTask.current = null;
|
||||
setRenderCoverageReady(true);
|
||||
}
|
||||
|
||||
const state = getVirtualQueueState();
|
||||
const seed = state
|
||||
? seedVirtualQueueTracks(
|
||||
rollingUpcomingTracksRef.current,
|
||||
state.activePosition,
|
||||
state.totalCount,
|
||||
)
|
||||
: [];
|
||||
virtualTracksRef.current = seed;
|
||||
setVirtualTracks(seed);
|
||||
|
||||
const state = resetVirtualTracks();
|
||||
if (!state) return Promise.resolve();
|
||||
if (virtualLoadPromise.current) {
|
||||
virtualLoadQueued.current = true;
|
||||
@@ -358,15 +383,44 @@ export const QueueTray = memo(function QueueTray({ onClose, embedded = false }:
|
||||
}
|
||||
});
|
||||
return request;
|
||||
}, []);
|
||||
}, [embedded, resetVirtualTracks]);
|
||||
virtualPageLoaderRef.current = loadVirtualPage;
|
||||
|
||||
useEffect(() => {
|
||||
void loadVirtualPage(true);
|
||||
}, [loadVirtualPage, virtualActivePosition, virtualMode, virtualState?.sessionId]);
|
||||
if (embedded || listPaintedRef.current) {
|
||||
void loadVirtualPage(true);
|
||||
} else {
|
||||
resetVirtualTracks();
|
||||
}
|
||||
}, [
|
||||
embedded,
|
||||
loadVirtualPage,
|
||||
resetVirtualTracks,
|
||||
virtualActivePosition,
|
||||
virtualMode,
|
||||
virtualState?.sessionId,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (embedded || !listPainted) return;
|
||||
|
||||
const task = InteractionManager.runAfterInteractions(() => {
|
||||
if (deferredMountTask.current !== task) return;
|
||||
deferredMountTask.current = null;
|
||||
setRenderCoverageReady(true);
|
||||
void virtualPageLoaderRef.current(false);
|
||||
});
|
||||
deferredMountTask.current = task;
|
||||
|
||||
return () => {
|
||||
task.cancel();
|
||||
if (deferredMountTask.current === task) deferredMountTask.current = null;
|
||||
};
|
||||
}, [embedded, listPainted]);
|
||||
|
||||
useEffect(() => () => {
|
||||
virtualLoadGeneration.current += 1;
|
||||
deferredMountTask.current?.cancel();
|
||||
if (virtualRetryTimer.current) clearTimeout(virtualRetryTimer.current);
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
QUEUE_INITIAL_RENDER_AHEAD_ROWS,
|
||||
QUEUE_INITIAL_RENDER_DISTANCE,
|
||||
QUEUE_RENDER_AHEAD_MIN_ROWS,
|
||||
QUEUE_RENDER_WINDOW_MULTIPLIER,
|
||||
QUEUE_ROW_HEIGHT,
|
||||
@@ -8,6 +10,11 @@ import {
|
||||
queueRenderDistance,
|
||||
} from './queuePerformance.ts';
|
||||
|
||||
test('queue opens with the former four-row render-ahead distance', () => {
|
||||
assert.equal(QUEUE_INITIAL_RENDER_AHEAD_ROWS, 4);
|
||||
assert.equal(QUEUE_INITIAL_RENDER_DISTANCE, QUEUE_ROW_HEIGHT * 4);
|
||||
});
|
||||
|
||||
test('queue render-ahead covers two windows with a twelve-row minimum', () => {
|
||||
assert.equal(QUEUE_RENDER_AHEAD_MIN_ROWS, 12);
|
||||
assert.equal(QUEUE_RENDER_WINDOW_MULTIPLIER, 2);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
export const QUEUE_ROW_HEIGHT = 64;
|
||||
export const QUEUE_INITIAL_RENDER_AHEAD_ROWS = 4;
|
||||
export const QUEUE_INITIAL_RENDER_DISTANCE =
|
||||
QUEUE_ROW_HEIGHT * QUEUE_INITIAL_RENDER_AHEAD_ROWS;
|
||||
export const QUEUE_RENDER_AHEAD_MIN_ROWS = 12;
|
||||
export const QUEUE_RENDER_WINDOW_MULTIPLIER = 2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user