Add notifications.

This commit is contained in:
Greyson Parrelli
2026-08-26 23:24:14 -04:00
parent afad6a2636
commit 7414c89fe6
33 changed files with 1026 additions and 381 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- The topbar brand mark as a favicon: the Octicon `file-diff` glyph knocked
out of a Primer-blue tile (bgColor.accent.emphasis #316dca, shaded a shade
either side for depth). Same shape and colour as <Icon name="file-diff" />
either side for depth). Same shape and color as <Icon name="file-diff" />
in the header, so the tab matches the app. Vite copies public/ to dist/,
which web/embed.go ships inside the binary. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+5 -5
View File
@@ -213,7 +213,7 @@ export default function App() {
// The parsed diff lives here rather than in DiffView because the comments rail
// needs it too: deciding which comments the diff can still place is one
// judgement, made once, so the rail and the diff can't disagree about it.
// judgment, made once, so the rail and the diff can't disagree about it.
const parsedFiles = useMemo(() => (payload ? parseDiff(payload.patch) : []), [payload]);
// What each file's diff currently says, digested. Viewed marks are stored
@@ -395,20 +395,20 @@ export default function App() {
useEffect(() => {
if (!path || !revision || stale) return;
let cancelled = false;
let canceled = false;
let busy = false;
const check = async () => {
// A hidden pane is a pane nobody is reading. It gets checked the moment it
// comes back instead, which is when the answer matters.
if (cancelled || busy || document.hidden) return;
if (canceled || busy || document.hidden) return;
busy = true;
const seq = reqRef.current;
try {
const { revision: now } = await api.revision(ctx, { ignoreWhitespace: ignoreWs });
// A load that started while this was in flight has already answered the
// question, with a revision this closure doesn't know about.
if (cancelled || seq !== reqRef.current) return;
if (canceled || seq !== reqRef.current) return;
if (now && now !== revision) setStale(now);
} catch {
// A failed poll says nothing about the diff — the next one will.
@@ -424,7 +424,7 @@ export default function App() {
document.addEventListener('visibilitychange', onVisible);
window.addEventListener('focus', onVisible);
return () => {
cancelled = true;
canceled = true;
window.clearInterval(timer);
document.removeEventListener('visibilitychange', onVisible);
window.removeEventListener('focus', onVisible);
+1 -1
View File
@@ -228,7 +228,7 @@ function SingleThread({
}
// BodyEditor edits a comment's text in place of its rendered body. It starts
// from the saved text and only reports a change on save, so cancelling always
// from the saved text and only reports a change on save, so canceling always
// leaves the stored comment untouched.
function BodyEditor({
initial,
+5 -5
View File
@@ -206,12 +206,12 @@ function FileView({
setOldSource(null);
return;
}
let cancelled = false;
let canceled = false;
api.fileContent(base, file.oldPath).then((s) => {
if (!cancelled) setOldSource(s);
if (!canceled) setOldSource(s);
});
return () => {
cancelled = true;
canceled = true;
};
}, [base, file.oldPath, file.type]);
@@ -227,14 +227,14 @@ function FileView({
// Highlighting is done over the *whole* file, never over the visible hunks
// alone. Prism is a stateful tokenizer: a construct that opens above the first
// visible line — a block comment, a template literal, a heredoc — leaves it in
// the wrong state and mis-colours everything after it, so what got highlighted
// the wrong state and mis-colors everything after it, so what got highlighted
// would depend on which context happened to be collapsed. Handing it the base
// source (react-diff-view derives the head side by applying `hunks`) makes the
// result identical no matter what is expanded.
//
// A wholly added or deleted file needs no base source: its hunks already carry
// every line, so tokenizing them is exact. Otherwise we wait for the fetch
// rather than highlight a fragment — a beat of plain text beats wrong colours.
// rather than highlight a fragment — a beat of plain text beats wrong colors.
const tokens: HunkTokens | undefined = useMemo(() => {
const lang = languageForFile(path);
if (!lang) return undefined;
+2 -2
View File
@@ -5,8 +5,8 @@
// pulled in as a dependency because we need a dozen of ~600, and a local table
// keeps the icon set visible in one place instead of hidden behind imports.
//
// Every glyph is authored on a 16×16 grid with `fill: currentColor`, so colour
// comes from the surrounding text colour and size from the `size` prop.
// Every glyph is authored on a 16×16 grid with `fill: currentColor`, so color
// comes from the surrounding text color and size from the `size` prop.
const PATHS = {
'chevron-down':
+9 -9
View File
@@ -1,7 +1,7 @@
/* ============================================================================
review — local code review UI
The styling is GitHub's, not an interpretation of it. Every colour below is a
The styling is GitHub's, not an interpretation of it. Every color below is a
Primer token: the dark block is Primer's `dark dimmed` theme and the light
block is `light`, both at the values GitHub currently ships. The diff
geometry — 12px/24px mono rows, 45px line-number columns, a 22px marker
@@ -63,7 +63,7 @@
--attention-soft: rgba(174, 124, 20, 0.15);
--attention-muted: rgba(174, 124, 20, 0.4);
/* Diff blob colours, sampled from a rendered diff. */
/* Diff blob colors, sampled from a rendered diff. */
--add-bg: #263834; /* addition, code cell */
--add-gutter: #31503d; /* addition, line number cell */
--add-word: #31583c; /* addition, word-level mark */
@@ -1153,7 +1153,7 @@ body.is-resizing {
border-left-color: var(--claude);
opacity: 0.6;
}
/* An outdated card keeps its status colour on the pill but takes the attention
/* An outdated card keeps its status color on the pill but takes the attention
edge, since "can't find the code any more" is what you need to notice first. */
.comment-card.is-outdated {
border-left-color: var(--attention);
@@ -1251,7 +1251,7 @@ body.is-resizing {
}
/* What stands in for a diff too large to render, once its warning has been
dismissed — the same centred treatment as .loading, plus the way back in. */
dismissed — the same centered treatment as .loading, plus the way back in. */
.oversize-notice {
max-width: 560px;
margin: 64px auto;
@@ -1370,7 +1370,7 @@ body.is-resizing {
font-family: var(--font-mono);
font-size: 12px;
}
/* Primer Label: 999px pill, coloured border, 12px text. */
/* Primer Label: 999px pill, colored border, 12px text. */
.file-status {
font-size: 12px;
line-height: 18px;
@@ -1468,7 +1468,7 @@ body.is-resizing {
color: var(--muted);
}
/* A viewed file steps back: its header greys out so the ones still to read are
/* A viewed file steps back: its header grays out so the ones still to read are
what the eye lands on. */
.file.is-viewed {
border-color: var(--border-muted);
@@ -1529,7 +1529,7 @@ body.is-resizing {
}
/* ---- Outdated comments -------------------------------------------------- */
/* Attention yellow, the same colour the gutter uses for a commented line: the
/* Attention yellow, the same color the gutter uses for a commented line: the
comment is intact, only its anchor is gone. Nothing here reads as an error. */
.outdated-note {
padding: 12px 16px;
@@ -1719,7 +1719,7 @@ body.is-resizing {
}
/* A range being dragged, or one a pending comment is attached to. GitHub tints
commented lines with attention yellow rather than the accent colour. */
commented lines with attention yellow rather than the accent color. */
.diff-gutter-selected {
background: var(--attention-muted);
color: var(--text);
@@ -1812,7 +1812,7 @@ body.is-resizing {
}
/* ---- Primer prettylights syntax theme ----------------------------------- */
/* Prism's token names mapped onto GitHub's syntax colours. Both places code is
/* Prism's token names mapped onto GitHub's syntax colors. Both places code is
highlighted share them: the diff, and a fenced block in a comment. */
:is(.diff, .md) .token.comment,
:is(.diff, .md) .token.prolog,