0.2.4 — fix code-editor white screen, rename package to "Exbyte Depot"

- Fix critical crash: opening the built-in code editor blanked the whole app
  (white screen). The editing early-return sat above the syntax-highlight
  useMemo, so entering edit mode changed the hook count and React tore down the
  tree (Rules of Hooks violation). Moved all hooks above the early returns.
- Diff-vs-previous button is now shown only for text/code files, not binaries
  (p4 diff2 on a .uasset only prints "files differ", which is useless).
- Package renamed to "Exbyte Depot" (productName + mainBinaryName); identifier
  unchanged so existing installs upgrade in place.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bonchellon
2026-07-08 09:43:33 +03:00
parent 0da836b0ac
commit c175d734d7
6 changed files with 16 additions and 13 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "exbyte-depot", "name": "exbyte-depot",
"private": true, "private": true,
"version": "0.2.3", "version": "0.2.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

2
src-tauri/Cargo.lock generated
View File

@ -960,7 +960,7 @@ dependencies = [
[[package]] [[package]]
name = "exbyte-depot" name = "exbyte-depot"
version = "0.2.2" version = "0.2.3"
dependencies = [ dependencies = [
"encoding_rs", "encoding_rs",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "exbyte-depot" name = "exbyte-depot"
version = "0.2.3" version = "0.2.4"
description = "Exbyte Depot — native Perforce client by Exbyte Studios" description = "Exbyte Depot — native Perforce client by Exbyte Studios"
authors = ["Exbyte Studios"] authors = ["Exbyte Studios"]
edition = "2021" edition = "2021"

View File

@ -1,7 +1,8 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "exbyte-depot", "productName": "Exbyte Depot",
"version": "0.2.3", "mainBinaryName": "Exbyte Depot",
"version": "0.2.4",
"identifier": "com.bonchellon.exbyte-depot", "identifier": "com.bonchellon.exbyte-depot",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",

View File

@ -2209,7 +2209,7 @@ function Preview({ file, onRevert, onFlash, editorId, editorName, onBlame, onDif
{codeFile && onBlame && ( {codeFile && onBlame && (
<span className="gbtn icon" title={t("Blame — who changed each line")} onClick={() => onBlame(spec || dp, name)}>{I.people}</span> <span className="gbtn icon" title={t("Blame — who changed each line")} onClick={() => onBlame(spec || dp, name)}>{I.people}</span>
)} )}
{hist && onDiffPrev && ( {hist && onDiffPrev && codeFile && (
<span className="gbtn icon" title={t("Diff against the previous revision")} onClick={() => onDiffPrev(file)}>{I.clock}</span> <span className="gbtn icon" title={t("Diff against the previous revision")} onClick={() => onDiffPrev(file)}>{I.clock}</span>
)} )}
{!hist && <span className="gbtn" onClick={() => onRevert(file)}>{I.revert}{t("Revert")}</span>} {!hist && <span className="gbtn" onClick={() => onRevert(file)}>{I.revert}{t("Revert")}</span>}

View File

@ -96,6 +96,15 @@ export default function CodeView({ file, onFlash }: { file: OpenedFile; onFlash?
} }
const pencil = <svg viewBox="0 0 24 24" width="13" height="13" fill="none"><path d="m14.5 5.5 4 4M4 20l1-4L16.5 4.5a2 2 0 0 1 3 3L8 19l-4 1Z" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" /></svg>; const pencil = <svg viewBox="0 0 24 24" width="13" height="13" fill="none"><path d="m14.5 5.5 4 4M4 20l1-4L16.5 4.5a2 2 0 0 1 3 3L8 19l-4 1Z" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" /></svg>;
// NB: all hooks must run before any early return (Rules of Hooks) — compute
// the highlighted body here, above the editing/diff/error returns below.
const lang = langOf(name);
const highlighted = useMemo(() => {
if (code == null) return "";
try { return lang ? hljs.highlight(code, { language: lang, ignoreIllegals: true }).value : esc(code); }
catch { return esc(code); }
}, [code, lang]);
// editing mode — plain textarea over the working copy // editing mode — plain textarea over the working copy
if (editing) { if (editing) {
return ( return (
@ -125,13 +134,6 @@ export default function CodeView({ file, onFlash }: { file: OpenedFile; onFlash?
); );
} }
const lang = langOf(name);
const highlighted = useMemo(() => {
if (code == null) return "";
try { return lang ? hljs.highlight(code, { language: lang, ignoreIllegals: true }).value : esc(code); }
catch { return esc(code); }
}, [code, lang]);
if (err === "binary") return <div className="nofile">{t("Binary file — no code preview.")}</div>; if (err === "binary") return <div className="nofile">{t("Binary file — no code preview.")}</div>;
if (err) return <div className="nofile" style={{ color: "var(--del)" }}>{err}</div>; if (err) return <div className="nofile" style={{ color: "var(--del)" }}>{err}</div>;
if (tooBig) return <div className="nofile">{t("File is too large to preview.")}</div>; if (tooBig) return <div className="nofile">{t("File is too large to preview.")}</div>;