Files
paseo/packages/app/src/git/diff-document/native-slabs.ts
T
Mohamed Boudra 3998ea11d9 Keep large diffs responsive across web and mobile (#4174)
* perf(app): keep large diffs responsive

Render file headers on the canvas and bound expensive text shaping to the active viewport while preserving sticky, hover, and horizontal-scroll behavior. Let native scroll cancellation arbitrate header presses so finger scrolling cannot expand files.

* test(app): assert canvas diff header accessibility

* test(app): assert canvas diff header semantics
2026-09-01 23:52:11 +02:00

52 lines
1.5 KiB
TypeScript

import type { DiffDocumentModel } from "./types";
export interface NativeCanvasSlab {
key: string;
path: string;
fileIndex: number;
top: number;
height: number;
}
export function buildNativeCanvasSlabs(
model: DiffDocumentModel,
viewportHeight: number,
): NativeCanvasSlab[] {
const slabHeight = Math.max(768, viewportHeight);
return model.files.flatMap((file) => {
const slabs: NativeCanvasSlab[] = [];
let slabIndex = 0;
for (let top = file.bodyTop; top < file.bottom; top += slabHeight, slabIndex += 1) {
const height = Math.min(slabHeight, file.bottom - top);
slabs.push({
key: `${file.path}:${slabIndex}`,
path: file.path,
fileIndex: file.fileIndex,
top,
height,
});
}
return slabs;
});
}
export function nativeCanvasSlabsForViewport(
slabs: readonly NativeCanvasSlab[],
scrollTop: number,
viewportHeight: number,
): NativeCanvasSlab[] {
const top = Math.max(0, scrollTop - viewportHeight / 2);
const bottom = scrollTop + viewportHeight * 1.5;
return slabs.filter((slab) => slab.top < bottom && slab.top + slab.height > top);
}
export function nativeCanvasWindowBucket(scrollTop: number, viewportHeight: number): number {
"worklet";
return Math.floor(Math.max(0, scrollTop) / Math.max(1, viewportHeight / 2));
}
export function nativeCanvasWindowTop(bucket: number, viewportHeight: number): number {
"worklet";
return bucket * Math.max(1, viewportHeight / 2);
}