| ... | @@ -58,45 +58,6 @@ export interface ReviewRenderableFile { | ... | @@ -58,45 +58,6 @@ export interface ReviewRenderableFile { |
| 58 | readonly rows: ReadonlyArray<ReviewRenderableRow>; | 58 | readonly rows: ReadonlyArray<ReviewRenderableRow>; |
| 59 | } | 59 | } |
| 60 | | 60 | |
| 61 | export interface ReviewFileHeaderListItem { | | |
| 62 | readonly kind: "file-header"; | | |
| 63 | readonly id: string; | | |
| 64 | readonly fileId: string; | | |
| 65 | readonly file: ReviewRenderableFile; | | |
| 66 | readonly expanded: boolean; | | |
| 67 | } | | |
| 68 | | | |
| 69 | export interface ReviewFileSuppressedListItem { | | |
| 70 | readonly kind: "file-suppressed"; | | |
| 71 | readonly id: string; | | |
| 72 | readonly fileId: string; | | |
| 73 | readonly message: string; | | |
| 74 | readonly actionLabel: string | null; | | |
| 75 | } | | |
| 76 | | | |
| 77 | export interface ReviewHunkListItem { | | |
| 78 | readonly kind: "hunk"; | | |
| 79 | readonly id: string; | | |
| 80 | readonly fileId: string; | | |
| 81 | readonly file: ReviewRenderableFile; | | |
| 82 | readonly row: ReviewRenderableHunkRow; | | |
| 83 | } | | |
| 84 | | | |
| 85 | export interface ReviewLineListItem { | | |
| 86 | readonly kind: "line"; | | |
| 87 | readonly id: string; | | |
| 88 | readonly fileId: string; | | |
| 89 | readonly file: ReviewRenderableFile; | | |
| 90 | readonly row: ReviewRenderableLineRow; | | |
| 91 | readonly lineIndex: number; | | |
| 92 | } | | |
| 93 | | | |
| 94 | export type ReviewListItem = | | |
| 95 | | ReviewFileHeaderListItem | | |
| 96 | | ReviewFileSuppressedListItem | | |
| 97 | | ReviewHunkListItem | | |
| 98 | | ReviewLineListItem; | | |
| 99 | | | |
| 100 | export type ReviewFilePreviewState = | 61 | export type ReviewFilePreviewState = |
| 101 | | { | 62 | | { |
| 102 | readonly kind: "render"; | 63 | readonly kind: "render"; |
| ... | @@ -316,77 +277,6 @@ export function getReviewFilePreviewState(file: ReviewRenderableFile): ReviewFil | ... | @@ -316,77 +277,6 @@ export function getReviewFilePreviewState(file: ReviewRenderableFile): ReviewFil |
| 316 | return { kind: "render" }; | 277 | return { kind: "render" }; |
| 317 | } | 278 | } |
| 318 | | 279 | |
| 319 | // The flattened review list item model is inspired by pierre/diffs' iterator-first | | |
| 320 | // virtualization architecture, adapted here for React Native virtualization. | | |
| 321 | // Original project: https://github.com/pingdotgg/pierre/tree/main/packages/diffs | | |
| 322 | // Reference files: | | |
| 323 | // - src/utils/iterateOverDiff.ts | | |
| 324 | // - src/components/VirtualizedFileDiff.ts | | |
| 325 | export function buildReviewListItems(input: { | | |
| 326 | readonly files: ReadonlyArray<ReviewRenderableFile>; | | |
| 327 | readonly expandedFileIds: ReadonlyArray<string>; | | |
| 328 | readonly revealedLargeFileIds: ReadonlyArray<string>; | | |
| 329 | }): ReadonlyArray<ReviewListItem> { | | |
| 330 | const expandedFileIds = new Set(input.expandedFileIds); | | |
| 331 | const revealedLargeFileIds = new Set(input.revealedLargeFileIds); | | |
| 332 | const items: ReviewListItem[] = []; | | |
| 333 | | | |
| 334 | input.files.forEach((file) => { | | |
| 335 | const expanded = expandedFileIds.has(file.id); | | |
| 336 | items.push({ | | |
| 337 | kind: "file-header", | | |
| 338 | id: `${file.id}:header`, | | |
| 339 | fileId: file.id, | | |
| 340 | file, | | |
| 341 | expanded, | | |
| 342 | }); | | |
| 343 | | | |
| 344 | if (!expanded) { | | |
| 345 | return; | | |
| 346 | } | | |
| 347 | | | |
| 348 | const previewState = getReviewFilePreviewState(file); | | |
| 349 | if (previewState.kind === "suppressed") { | | |
| 350 | if (previewState.reason !== "large" || !revealedLargeFileIds.has(file.id)) { | | |
| 351 | items.push({ | | |
| 352 | kind: "file-suppressed", | | |
| 353 | id: `${file.id}:suppressed`, | | |
| 354 | fileId: file.id, | | |
| 355 | message: previewState.message, | | |
| 356 | actionLabel: previewState.actionLabel, | | |
| 357 | }); | | |
| 358 | return; | | |
| 359 | } | | |
| 360 | } | | |
| 361 | | | |
| 362 | let lineIndex = 0; | | |
| 363 | file.rows.forEach((row, rowIndex) => { | | |
| 364 | if (row.kind === "hunk") { | | |
| 365 | items.push({ | | |
| 366 | kind: "hunk", | | |
| 367 | id: `${file.id}:row:${rowIndex}:${row.id}`, | | |
| 368 | fileId: file.id, | | |
| 369 | file, | | |
| 370 | row, | | |
| 371 | }); | | |
| 372 | return; | | |
| 373 | } | | |
| 374 | | | |
| 375 | items.push({ | | |
| 376 | kind: "line", | | |
| 377 | id: `${file.id}:row:${rowIndex}:${row.id}`, | | |
| 378 | fileId: file.id, | | |
| 379 | file, | | |
| 380 | row, | | |
| 381 | lineIndex, | | |
| 382 | }); | | |
| 383 | lineIndex += 1; | | |
| 384 | }); | | |
| 385 | }); | | |
| 386 | | | |
| 387 | return items; | | |
| 388 | } | | |
| 389 | | | |
| 390 | function fallbackHunkHeader(hunk: FileDiffMetadata["hunks"][number]): string { | 280 | function fallbackHunkHeader(hunk: FileDiffMetadata["hunks"][number]): string { |
| 391 | return `@@ -${hunk.deletionStart},${hunk.deletionCount} +${hunk.additionStart},${hunk.additionCount} @@`; | 281 | return `@@ -${hunk.deletionStart},${hunk.deletionCount} +${hunk.additionStart},${hunk.additionCount} @@`; |
| 392 | } | 282 | } |