1import type {
2 NativeReviewDiffRow,
3 NativeReviewDiffStyle,
4 NativeReviewDiffToken,
5} from "../diffs/nativeReviewDiffSurface";
6import type { ResolvedMobileCodeSurface } from "../../lib/appearancePreferences";
7import { MOBILE_CODE_SURFACE, MOBILE_TYPOGRAPHY } from "../../lib/typography";
8import type { SourceHighlightTokens } from "./sourceHighlightingState";
9
10export const NATIVE_SOURCE_CONTENT_WIDTH = 32_000;
11
12export function createNativeSourceStyle(
13 codeSurface: ResolvedMobileCodeSurface,
14): NativeReviewDiffStyle {
15 return {
16 rowHeight: codeSurface.rowHeight,
17 contentWidth: NATIVE_SOURCE_CONTENT_WIDTH,
18 changeBarWidth: 0,
19 gutterWidth: codeSurface.gutterWidth,
20 codePadding: codeSurface.codePadding,
21 textVerticalInset: codeSurface.textVerticalInset,
22 codeFontSize: codeSurface.fontSize,
23 codeFontWeight: "regular",
24 lineNumberFontSize: codeSurface.lineNumberFontSize,
25 lineNumberFontWeight: "regular",
26 emptyStateFontSize: Math.round(
27 MOBILE_TYPOGRAPHY.label.fontSize * (codeSurface.fontSize / MOBILE_CODE_SURFACE.fontSize),
28 ),
29 emptyStateFontWeight: "medium",
30 };
31}
32
33const SOURCE_FILE_ID = "source-file";
34
35function expandTabs(value: string): string {
36 return value.replace(/\t/g, " ");
37}
38
39export function nativeSourceRowId(index: number): string {
40 return `source-line:${index}`;
41}
42
43export function buildNativeSourceRows(
44 lines: ReadonlyArray<string>,
45): ReadonlyArray<NativeReviewDiffRow> {
46 return lines.map((line, index) => ({
47 kind: "line",
48 id: nativeSourceRowId(index),
49 fileId: SOURCE_FILE_ID,
50 content: expandTabs(line),
51 change: "context",
52 newLineNumber: index + 1,
53 }));
54}
55
56export function buildNativeSourceTokens(
57 tokenLines: SourceHighlightTokens | null,
58): Readonly<Record<string, ReadonlyArray<NativeReviewDiffToken>>> {
59 if (tokenLines === null) {
60 return {};
61 }
62
63 return Object.fromEntries(
64 tokenLines.map((tokens, index) => [
65 nativeSourceRowId(index),
66 tokens.map((token) => ({
67 content: expandTabs(token.content),
68 color: token.color,
69 fontStyle: token.fontStyle,
70 })),
71 ]),
72 );
73}