Keep diff headers and painted content on the same scroll clock while preserving native scrolling and independent per-file horizontal offsets. Complete review, selection, typography, tree, and palette parity without returning line rendering to React.
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import type { DiffDocumentModel } from "./types";
|
|
|
|
export interface NativeCanvasSlab {
|
|
key: string;
|
|
path: string;
|
|
fileIndex: number;
|
|
top: number;
|
|
height: number;
|
|
}
|
|
|
|
export function nativeStickyHeaderIndices(fileCount: number): number[] {
|
|
return Array.from({ length: fileCount }, (_, index) => index * 2 + 1);
|
|
}
|
|
|
|
export function buildNativeCanvasSlabs(
|
|
model: DiffDocumentModel,
|
|
viewportHeight: number,
|
|
): NativeCanvasSlab[] {
|
|
const slabHeight = Math.max(768, viewportHeight * 2);
|
|
return model.files.flatMap((file) => {
|
|
const slabs: NativeCanvasSlab[] = [];
|
|
for (let top = file.bodyTop; top < file.bottom; top += slabHeight) {
|
|
const height = Math.min(slabHeight, file.bottom - top);
|
|
slabs.push({
|
|
key: `${file.path}:${top}:${height}`,
|
|
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);
|
|
const bottom = scrollTop + viewportHeight * 2;
|
|
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);
|
|
}
|