mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
fix(app): keep the chat scroller pinned to the end while it resizes (#1860)
This commit is contained in:
1 parent
a2099fb0e2
commit
2af0405317
36 files changed
+171
-191
No files matched your search
-46
@@ -1,46 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {MasonryListComputer} from '@app/features/channel/components/MasonryListComputer';
|
||||
import {bench, describe} from 'vitest';
|
||||
|
||||
const ITEM_COUNT = 500;
|
||||
const VIEWPORT_WIDTH = 520;
|
||||
const VIEWPORT_HEIGHT = 420;
|
||||
const COLUMNS = 3;
|
||||
const ITEM_GUTTER = 8;
|
||||
const ITEM_KEYS = Array.from({length: ITEM_COUNT}, (_, index) => `gif-${index}`);
|
||||
const ITEM_HEIGHTS = Array.from({length: ITEM_COUNT}, (_, index) => 90 + ((index * 37) % 180));
|
||||
const SCROLL_OFFSETS = Array.from({length: 1_000}, (_, index) => (index * 173) % 30_000);
|
||||
|
||||
function configureComputer(computer: MasonryListComputer, version: number): void {
|
||||
computer.mergeProps({
|
||||
sections: [ITEM_COUNT],
|
||||
columns: COLUMNS,
|
||||
itemGutter: ITEM_GUTTER,
|
||||
bufferWidth: VIEWPORT_WIDTH,
|
||||
padding: {left: 12, right: 12, top: 0, bottom: 0},
|
||||
version,
|
||||
getItemKey: (_section, itemIndex) => ITEM_KEYS[itemIndex] ?? null,
|
||||
getItemHeight: (_section, itemIndex) => ITEM_HEIGHTS[itemIndex] ?? 0,
|
||||
getSectionHeight: () => 0,
|
||||
});
|
||||
}
|
||||
|
||||
describe('MasonryListComputer benchmarks', () => {
|
||||
bench('computes full masonry layout for 500 GIFs', () => {
|
||||
const computer = new MasonryListComputer();
|
||||
configureComputer(computer, 1);
|
||||
computer.computeVisibleSections(0, VIEWPORT_HEIGHT);
|
||||
computer.getState();
|
||||
});
|
||||
|
||||
bench('computes 1k visible windows over a stable GIF layout', () => {
|
||||
const computer = new MasonryListComputer();
|
||||
configureComputer(computer, 1);
|
||||
computer.computeVisibleSections(0, VIEWPORT_HEIGHT);
|
||||
for (const scrollTop of SCROLL_OFFSETS) {
|
||||
computer.computeVisibleSections(scrollTop, scrollTop + VIEWPORT_HEIGHT + 480);
|
||||
}
|
||||
computer.getState();
|
||||
});
|
||||
});
|
||||
@@ -60,7 +60,7 @@ export function useScrollerViewport(scrollerRef: React.RefObject<ScrollerHandle
|
||||
[scheduleViewportSize],
|
||||
);
|
||||
useEffect(() => {
|
||||
const state = scrollerRef.current?.getScrollerState();
|
||||
const state = scrollerRef.current?.readViewportMetrics();
|
||||
if (!state || state.offsetWidth === 0 || state.offsetHeight === 0) return;
|
||||
scheduleViewportSize({width: state.offsetWidth, height: state.offsetHeight});
|
||||
}, [scrollerRef, scheduleViewportSize]);
|
||||
|
||||
Reference in new issue
Block a user