{#snippet code(line: Modification)} {#if line.highlight && line.highlight.items.length > 0}
{@html line.highlight.items .map( paint => `
${escape(paint.item)}
`, ) .join("")}
{:else if line.line !== ""}
{line.line}
{:else}
{/if} {/snippet} {#snippet commentHeader(filePath?: string, selectionRange?: SelectionRange)} {#if filePath && selectionRange}
{filePath.split("/").length > 1 ? "…/" : ""}{filePath .split("/") .slice(-1)}:{selectionRange.start.side === "left" ? "L" : "R"}{selectionRange.start.lineNumber} {#if selectionRange.end} -> {selectionRange.end.side === "left" ? "L" : "R"}{selectionRange.end .lineNumber} {/if}
{/if} {/snippet} {#snippet readonlyLine(r: LineRow)} {@const line = r.modification}
{lineNumber(line, "left") ?? ""}
{lineNumber(line, "right") ?? ""}
{#if line.type === "addition"}+{:else if line.type === "deletion"}-{/if}
{@render code(line)}
{/snippet} {#snippet interactiveLine(r: LineRow, ctx: CommentContext)} {@const line = r.modification} {@const cc = ctx.codeComments} {@const thread = findLineThread(ctx.threadByLine, r.file, line)} {@const showThread = thread !== undefined && !ctx.expandedStates[thread.root.id]} {@const sel = ctx.selection} {@const inFile = sel !== undefined && sel.fileIdx === r.fileIndex} {@const isSel = inFile && sel.hunkIdx === r.hunkIndex && sel.lineIdx === r.lineIndex} {@const closeOnLine = r.last && !showThread && !isSel} {@const closeOnThread = r.last && showThread && !isSel} {@const closeOnForm = r.last && isSel} {@const selectable = cc.createComment !== undefined && thread === undefined}
{ if (selectable) { e.preventDefault(); e.stopPropagation(); ctx.onSelectLine( r.fileIndex, "left", line, r.hunkIndex, r.lineIndex, r.file, ); } }}> {lineNumber(line, "left") ?? ""}
{ if (selectable) { e.preventDefault(); e.stopPropagation(); ctx.onSelectLine( r.fileIndex, "right", line, r.hunkIndex, r.lineIndex, r.file, ); } }}> {lineNumber(line, "right") ?? ""}
{#if line.type === "addition"}+{:else if line.type === "deletion"}-{/if}
{@render code(line)} {#if thread}
ctx.onToggleThread(thread.root.id)} />
{/if}
{#if showThread && thread}
{@render commentHeader( thread.root.location?.path, rangeAnchorsFromCodeLocation(thread.root.location), )} {#if cc.changeCommentStatus && roles.isDelegateOrAuthor( cc.config.publicKey, cc.repoDelegates.map(delegate => delegate.did), thread.root.author.did, )}
{#if thread.root.resolved}
{:else}
{/if}
{/if}
{ await cc.createComment(body, embeds, thread.root.id); } : undefined} editComment={cc.editComment} canEditComment={partial( roles.isDelegateOrAuthor, cc.config.publicKey, cc.repoDelegates.map(delegate => delegate.did), )} deleteComment={cc.deleteComment} />
{/if} {#if isSel && sel}
{ e.stopPropagation(); }}>
{@render commentHeader(sel.file, { start: sel.start })}
ctx.onClearSelection()} focus placeholder="Leave a comment" disableAttachments={cc.disableAttachments} submit={async (body, embeds) => { try { await cc.createComment(body, embeds, undefined, sel.codeLocation); } catch (e) { console.error("Comment creation failed", e); } finally { ctx.onClearSelection(); } }} />
{/if} {/snippet} {#if row.type === "file-gap"}
{:else if row.type === "file-header"}
onToggleFile?.(row.fileIndex)} title={expanded ? "Collapse file" : "Expand file"}>
{#if row.file.status === "moved" || row.file.status === "copied"}
→
{:else}
{/if} {#if row.file.status === "added"}
Added
{:else if row.file.status === "deleted"}
Deleted
{:else if row.file.status === "moved"}
Moved
{:else if row.file.status === "copied"}
Copied
{/if}
{#if row.file.diff.type === "plain" && row.file.diff.hunks.length > 0}
+{row.file.diff.stats.additions}
-{row.file.diff.stats.deletions}
{/if}
{#if comments && (row.file.status === "added" || row.file.status === "deleted" || row.file.status === "modified")} {@const counts = comments.threadCountsByFile.get(row.file.path)} {#if counts !== undefined && counts.unresolved > 0}
{counts.unresolved}
{/if} {#if counts !== undefined && counts.resolved > 0}
{counts.resolved}
{/if} {/if}
fileDiffToText(row.file)} fileName={fileDiffName(row.file)} title="File diff actions" />
{:else if row.type === "hunk-header"}
{row.header}
{:else if row.type === "file-note"}
{#if row.note === "binary"}
Binary file {:else} Empty file {/if}
{:else if comments} {@render interactiveLine(row, comments)} {:else} {@render readonlyLine(row)} {/if}