feat(viewer): reload/conflict reducer and editability rules
- viewerState.ts: pure reducer for the clean/dirty, same/changed/gone, container-down and overwrite-on-save states (spec §5), plus the pollEffect/canSave helpers EditorPane will drive off. - editability.ts: classifies a fetched file as text/image/binary and decides whether it is editable, deferring to Rust's readonly_reason when it refuses. Per preflight P1, languages.ts/.test.ts move to Task 10 (needs the CodeMirror packages Task 6 installs; out of scope for this task's worktree). Per P3, the "reloaded" action now carries `truncated` and `polledHash` so a poll-driven reload of a truncated (prefix-hash-only) file adopts the polled full-file hash instead of re-triggering a reload on every subsequent poll -- with a reducer test covering it. Per P13, tightened the poll_failed/canSave test to start from a dirty doc so it actually exercises containerDown rather than passing only because the doc was clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { imageMimeFor, looksBinary, TEXT_PREVIEW_LIMIT } from "../components/projects/home/filePreview";
|
||||
import type { ViewerFile } from "../lib/types";
|
||||
|
||||
export type ViewerKind = "text" | "image" | "binary";
|
||||
export interface Editability { kind: ViewerKind; editable: boolean; reason: string | null }
|
||||
|
||||
const MIB = TEXT_PREVIEW_LIMIT / (1024 * 1024);
|
||||
|
||||
export function classifyViewerFile(path: string, file: ViewerFile, bytes: Uint8Array): Editability {
|
||||
if (imageMimeFor(path)) return { kind: "image", editable: false, reason: "Images are shown, not edited." };
|
||||
if (looksBinary(bytes)) return { kind: "binary", editable: false, reason: "This file is not text." };
|
||||
if (file.truncated) return { kind: "text", editable: false, reason: `Files over ${MIB} MiB are read-only.` };
|
||||
if (!file.editable) return { kind: "text", editable: false, reason: file.readonly_reason ?? "This location is read-only." };
|
||||
return { kind: "text", editable: true, reason: null };
|
||||
}
|
||||
Reference in New Issue
Block a user