Skip to content

Commit

A running run's or job's time no longer trips hydration: it counts to a different now on the server and in the browser, as TimeAgo already allows

syntaqxcommitted Parentfd30559Browse files
4 files+31−80/4 viewed
+13−0
8383 return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
8484 }
8585
86+/**
87+ * How long something ran, as text. While it is still running the server and
88+ * the browser count to a different now, so the text may differ on hydration
89+ * (as TimeAgo's does).
90+ */
91+export function Duration({ start, end, className }: { start: string | null; end: string | null; className?: string }) {
92+ return (
93+ <span className={className} suppressHydrationWarning>
94+ {duration(start, end)}
95+ </span>
96+ );
97+}
98+
8699 /** `main` from `refs/heads/main`, `v1.2` from a tag, `#12` for a pull request. */
87100 export function shortRef(ref: string): string {
88101 const pull = /^refs\/pull\/(\d+)\//.exec(ref);
+6−1
231231 {name}
232232 {detail && <span className="text-muted"> — {detail}</span>}
233233 </span>
234− {time && <span className="shrink-0 animate-fade-in font-mono text-xs text-faint">{time}</span>}
234+ {time && (
235+ // A running job's time counts to now, which differs between server and browser.
236+ <span className="shrink-0 animate-fade-in font-mono text-xs text-faint" suppressHydrationWarning>
237+ {time}
238+ </span>
239+ )}
235240 {timing && <SkeletonLine className="w-10 shrink-0 text-xs" />}
236241 {to && (
237242 <Link to={to} className="shrink-0 text-xs text-muted hover:text-fg hover:underline">
+10−5
3131
3232 import type { Route } from "./+types/actions-run";
3333 import { page } from "../../lib/meta";
34−import { LogText, Notes, StatusIcon, duration, shortRef, standingWord, useJobLog } from "../../components/actions";
34+import { Duration, LogText, Notes, StatusIcon, shortRef, standingWord, useJobLog } from "../../components/actions";
3535 import { Markdown } from "../../components/markdown";
3636 import { Button, ErrorText, SubmitButton, TimeAgo, usePending } from "../../components/ui";
3737 import { CheckboxOption } from "../../components/ui/checkbox";
150150 {matches} {matches === 1 ? "line" : "lines"}
151151 </span>
152152 )}
153− <span className="ml-auto shrink-0 font-mono text-xs text-faint">{duration(step.startedAt, step.finishedAt)}</span>
153+ <Duration className="ml-auto shrink-0 font-mono text-xs text-faint" start={step.startedAt} end={step.finishedAt} />
154154 </summary>
155155 <div className="border-t border-line bg-bg/60">
156156 {text === undefined ? (
365365 <h3 className="text-base font-semibold">{job.name}</h3>
366366 <span className="text-sm text-muted">
367367 {job.cancelling ? "Cancelling: running its cleanup steps" : standingWord({ ...job, of: "job" })}
368− {job.startedAt && ` · ${duration(job.startedAt, job.finishedAt)}`}
368+ {job.startedAt && (
369+ <>
370+ {" · "}
371+ <Duration start={job.startedAt} end={job.finishedAt} />
372+ </>
373+ )}
369374 </span>
370375 <span className="ml-auto flex items-center gap-2">
371376 {rerun}
776781 {run.event}
777782 {run.actor && ` by ${run.actor}`} · <TimeAgo at={run.createdAt} />
778783 </span>
779− {run.startedAt && <span className="font-mono text-xs">{duration(run.startedAt, run.finishedAt)}</span>}
784+ {run.startedAt && <Duration className="font-mono text-xs" start={run.startedAt} end={run.finishedAt} />}
780785 {run.attempt > 1 && attempts.length <= 1 && <span>Attempt {run.attempt}</span>}
781786 {cancelling && <span className="text-warn">Its jobs are running their cleanup steps</span>}
782787 {detail.approval?.state === "approved" && detail.approval.approvedBy && <span>Approved by {detail.approval.approvedBy}</span>}
868873 >
869874 <StatusIcon status={job.status} conclusion={job.conclusion} of="job" environment={job.environment} size={14} />
870875 <span className="min-w-0 truncate">{job.name}</span>
871− <span className="ml-auto shrink-0 font-mono text-xs text-faint">{duration(job.startedAt, job.finishedAt)}</span>
876+ <Duration className="ml-auto shrink-0 font-mono text-xs text-faint" start={job.startedAt} end={job.finishedAt} />
872877 </Link>
873878 ))}
874879 </nav>
+2−2
66
77 import type { Route } from "./+types/actions";
88 import { page } from "../../lib/meta";
9−import { Notes, StatusIcon, duration, shortRef } from "../../components/actions";
9+import { Duration, Notes, StatusIcon, shortRef } from "../../components/actions";
1010 import { AddCiPrompt } from "../../components/add-ci";
1111 import { Button, ComputeNote, CopyLine, EmptyState, ErrorText, SubmitButton, TimeAgo, usePending } from "../../components/ui";
1212 import { CheckboxOption } from "../../components/ui/checkbox";
120120 </span>
121121 <span className="w-28 shrink-0 text-right text-xs text-faint">
122122 <TimeAgo at={run.createdAt} />
123− {run.startedAt && <span className="block font-mono">{duration(run.startedAt, run.finishedAt)}</span>}
123+ {run.startedAt && <Duration className="block font-mono" start={run.startedAt} end={run.finishedAt} />}
124124 </span>
125125 </Link>
126126 </li>