docs: mark Phase 1.5 done; sync architecture, modernize, readme

- ROADMAP: all Phase 1.5 boxes checked; done-notes (clone snapshots,
  Copy handle, no Instant on wasm, button enables with the pending burst)
- ARCHITECTURE: undo/redo in the header tree and a paragraph on the
  snapshot history; gaps list no longer mentions undo
- README: undo/redo in 'What works today'
This commit is contained in:
yaroslav k 2026-08-16 12:32:25 +03:00
parent ff5ec498b2
commit bb304bed6a
3 changed files with 26 additions and 10 deletions

View File

@ -100,8 +100,8 @@ JSON as-is.
## Component tree
App
├─ Header name, image, date steppers, session steppers,
Save (download)/Load (file import)/Clear (wipe)
│ Save (download)/Load (file import)/Clear (wipe),
↩ Undo/redo (buttons + Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y)
├─ Modal overlay dialog: confirm (action) or error (close)
├─ Sidebar
│ ├─ Image portrait
@ -133,6 +133,13 @@ then a debounced (500 ms) effect writes on any store change via
`Settings::VERSION` (the migration hook). `ModalState` holds title/message/
action as signals; the confirm button reads the action at click time.
Undo/redo lives in `state::undo`: the same store trigger feeds a
snapshot history (`HistoryHandle` in context). The first change of a
burst is remembered; when the burst goes quiet for 1 s, the pre-burst
state becomes an undo step. Undo/redo restore via `replace_state`
the autosave effect persists the undone state too. Clear and import
push a snapshot first, so they are undoable themselves.
`Numput` is the shared numeric input: `+n`/`-n` adjust relative to the
current value, a plain number sets absolutely, invalid input is reverted,
and the value renders with thousands separators. `NumputChange` is the same
@ -157,8 +164,6 @@ currently mounted on any page.
## Current gaps
- Quests, notes, contacts: models and mock data only
- No undo/redo (planned as Phase 1.5; snapshot-based, rides on the
persist machinery)
- `Character` and `Wiki` pages render placeholders
- Prepared spells list is empty; `Spell` is a name-only stub; attunements
have no UI; `Settings` has only `version`

View File

@ -8,6 +8,8 @@ game. The UI is in Russian.
- Campaign header: name, in-game date steppers, session counter, and
Save / Load / Clear: download `dashboard.json`, import a file back,
wipe to a blank campaign
- Undo/redo: header buttons and Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y over
edit bursts; Clear and import are undoable too
- Character sidebar: portrait, names, class, level, XP, hit points with
temp HP bar, hit dice, death saves, spell slots
- Inventories page (`/inv`): personal and party-common inventories,

View File

@ -105,21 +105,30 @@ Snapshot-based undo rides on the Phase 1 machinery: serialize → push →
fires on any mutation, so no component changes are needed and every later
phase's edits are undoable from day one.
- [ ] `state::undo.rs` (hydrate-gated): undo/redo stacks of serialized
- [x] `state::undo.rs` (hydrate-gated): undo/redo stacks of serialized
`Dashboard`, capped (e.g. 100); push coalesced on the store trigger
(one snapshot per ~1 s window → one undo step = one edit burst)
- [ ] a new edit after undo clears the redo stack; Clear and import push a
- [x] a new edit after undo clears the redo stack; Clear and import push a
snapshot first, so they are undoable too
- [ ] `undo()` / `redo()` call `replace_state`; expose stack depths as
- [x] `undo()` / `redo()` call `replace_state`; expose stack depths as
`RwSignal<usize>` for button disabled states
- [ ] header buttons: ↩ Отменить / Вернуть (disabled when empty)
- [ ] shortcuts: Ctrl+Z, Ctrl+Shift+Z (Ctrl+Y); ignore when focus is in an
- [x] header buttons: ↩ Отменить / Вернуть (disabled when empty)
- [x] shortcuts: Ctrl+Z, Ctrl+Shift+Z (Ctrl+Y); ignore when focus is in an
input/textarea/select, so typing never triggers undo
- [ ] unit tests for stack semantics; e2e: edit → undo → redo; reload keeps
- [x] unit tests for stack semantics; e2e: edit → undo → redo; reload keeps
the undone state (undo writes through autosave)
- **Acceptance:** every edit since the last window is reversible with a
keystroke; undo survives a reload.
**Done (2026-08-16):** implementation in `src/state/undo.rs`; e2e-verified
in chromium (buttons, shortcuts, reload, undoable Clear). Notes:
- Snapshots are `Dashboard` clones, not JSON: the dashboard is small.
- `HistoryHandle` is `Copy` (RwSignal fields) — context-friendly and
capture-safe under edition-2024 closure rules.
- No `std::time::Instant`: it panics on wasm32; the settle timer is the
only clock. The undo button enables with the pending burst, so a
fresh edit is undoable before the 1 s window settles.
## Phase 2 — Character page (M, ~1-2 days)
`/` currently renders the literal string "character".