Release 0.2.2 — browse submitted changelists, People & Roles, AI summaries

- History: GitHub-style split view of submitted changelists; preview file
  contents at their exact revision (code/image/3D/uasset) via `p4 print`
- People & Roles modal: who works on the depot, activity indicators,
  group/role assignment (p4 users / groups / group -i)
- AI commit summaries via OpenRouter (sparkle button); key/model in Settings
- Commit-message draft persists until Submit (not cleared on local commit)
- Resizable History file-list column (pointer-capture drag)
- Fix UI-scale leaving a gap at the bottom (compensate zoom in .win height)
- Author avatars on history rows; bump version to 0.2.2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bonchellon
2026-07-07 18:18:07 +03:00
parent 168b6afab3
commit 8e2cac4437
12 changed files with 613 additions and 46 deletions

View File

@ -48,6 +48,7 @@ const MAX = 800_000; // don't try to render/highlight enormous files
// for new files, or a colored unified diff for edits.
export default function CodeView({ file }: { file: OpenedFile }) {
const dp = file.depotFile || "";
const spec = file._spec || ""; // set → read this exact submitted revision
const { name } = splitPath(dp);
const action = (file.action || "").toLowerCase();
const [diff, setDiff] = useState<string | null>(null);
@ -58,9 +59,11 @@ export default function CodeView({ file }: { file: OpenedFile }) {
useEffect(() => {
let live = true;
setDiff(null); setCode(null); setErr(""); setTooBig(false);
// edits show a diff; adds have none, so fetch it but don't depend on it
p4.diff(dp).then((d) => live && setDiff(d)).catch(() => live && setDiff(""));
p4.readDepot(dp).then((buf) => {
// working-copy edits show a diff against the depot; historical revisions just
// show their full content (no meaningful working diff to fetch).
if (!spec) p4.diff(dp).then((d) => live && setDiff(d)).catch(() => live && setDiff(""));
const load = spec ? p4.printDepot(spec) : p4.readDepot(dp);
load.then((buf) => {
if (!live) return;
if (buf.byteLength > MAX) { setTooBig(true); setCode(""); return; }
const bytes = new Uint8Array(buf);
@ -69,7 +72,7 @@ export default function CodeView({ file }: { file: OpenedFile }) {
setCode(new TextDecoder("utf-8", { fatal: false }).decode(bytes));
}).catch((e) => live && setErr(String(e)));
return () => { live = false; };
}, [dp]);
}, [dp, spec]);
const lang = langOf(name);
const highlighted = useMemo(() => {