feat: Frühere Stände eines Dokuments, alle zehn Minuten (D54)
Alle 10 Minuten wird der Text des aktiven Dokuments weggelegt — aber nur, wenn er sich seit dem letzten Stand geändert hat. Aufgehoben werden die letzten 20 je Dokument (Nutzer-Entscheidung; rund 3,5 Stunden, max. ~800 kB beim größten Dokument). Angeboten werden sie über einen Knopf rechts neben dem Dokumenten-Wähler, neueste zuoberst, je mit Uhrzeit und Zeilenzahl. „Nur bei Änderung" heißt: gegen den letzten Stand, und solange es keinen gibt, gegen den Text beim Aktivieren des Dokuments. Ohne das legte der erste Takt nach dem Öffnen auch ein unverändertes Dokument weg. Die Dokumente sind wichtiger als ihre Stände: Beide teilen sich den localStorage, also wirft persistSnaps() bei Überlauf den jeweils ältesten Stand weg, bis es passt, notfalls alle — statt das Speichern der Dokumente zu gefährden. Ein gelöschtes Dokument nimmt seine Stände mit. Pad-Dokumente (D31) sammeln keine: Ihr Feld ist schreibgeschützt, ein alter Stand ließe sich dort nicht einsetzen. Zurückgeholt wird undo-fähig (replaceTextUndoable, D53) — ein Griff daneben kostet ein Strg+Z, keine Rückfrage. Vorher wird der aktuelle Stand weggelegt, sonst wäre gerade er das Einzige, was das Zurückholen verlöre. Beim Bauen korrigiert: Das Menü war an der Gruppe ausgerichtet (right:0) und begann 190 px weiter links, also außerhalb des Panels (gemessen: linke Kante bei -65 px). Bezug ist jetzt der Knopf. Nachgemessen (Takt für die Prüfung auf 2 s verkürzt, danach zurückgestellt): ohne Eingabe kein Eintrag, nach einer Eingabe genau einer, ohne weitere keiner dazu; nach 29 Änderungen 20 (gedeckelt, Zeitstempel aufsteigend). Klick auf einen älteren Eintrag lädt ihn (36 -> 32 Zeilen), Diagramm zeichnet neu, undo holt den vorherigen Stand zurück. Plan: 155 Knoten, 0 Warnungen. 240 Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6935b4882d
commit
8fd595abf9
@@ -3522,3 +3522,63 @@ Undo deshalb über `execCommand('undo')`; das steht jetzt auch in
|
||||
`frontend/CLAUDE.md`. Dieselbe Lehre wie D25 (synthetische `TouchEvent`s) und
|
||||
D17-Nachtrag 4 (Bildschirmtastatur): Was die Umgebung stellt, stellt der
|
||||
Emulator nicht.
|
||||
|
||||
## D54 — Frühere Stände: alle zehn Minuten, nur bei Änderung, die letzten zwanzig
|
||||
Ein Sicherheitsnetz gegen Versehen — und der Anlass war ein echtes: Der
|
||||
Tab-Fehler aus D53 konnte eine ganze Auswahl löschen und nahm dabei auch noch
|
||||
das Rückgängig mit. Ohne Netz war der Text dann weg.
|
||||
|
||||
**Aufbewahrt werden die letzten 20 je Dokument** (Nutzer-Entscheidung), also
|
||||
rund 3½ Stunden bei gleichmäßigen Abständen und höchstens ~800 kB beim größten
|
||||
Dokument. Erwogen und verworfen: **ausgedünnt** (alle der letzten Stunde,
|
||||
stündlich für einen Tag, täglich für eine Woche — reicht weiter zurück, kostet
|
||||
aber eine Ausdünn-Regel, die man beim Lesen erst verstehen muss) und
|
||||
**lückenlos 24 Stunden** (bis zu 144 Stände, beim großen Plan ~5,8 MB und damit
|
||||
über dem localStorage-Limit — es bräuchte doch wieder eine Notbremse). Der
|
||||
Anspruch ist bewusst klein: Wer weiter zurück will, hat Git.
|
||||
|
||||
**„Nur bei Änderung" heißt: gegen den letzten Stand, nicht gegen das Laden.**
|
||||
Gibt es noch keinen Stand, wird gegen den Text beim Aktivieren des Dokuments
|
||||
verglichen (`snapBase`). Ohne das legte der erste Takt nach dem Öffnen auch ein
|
||||
**unverändertes** Dokument weg — beim Herumklicken durch mehrere Dokumente
|
||||
sammelte sich so Ballast, den niemand erzeugt hat. Nachgemessen: Ohne Eingabe
|
||||
entsteht der Schlüssel im localStorage gar nicht erst.
|
||||
|
||||
**Die Dokumente sind wichtiger als ihre Stände.** Beide teilen sich den
|
||||
localStorage. Läuft er über, wirft `persistSnaps()` deshalb so lange den
|
||||
jeweils ältesten Stand weg, bis es passt, notfalls alle — statt eine Ausnahme
|
||||
hochzureichen und damit womöglich das Speichern der **Dokumente** zu
|
||||
gefährden. Ein gelöschtes Dokument nimmt seine Stände mit.
|
||||
|
||||
**Zurückgeholt wird undo-fähig** (`replaceTextUndoable`, D53): ein Griff
|
||||
daneben kostet ein Strg+Z, keine Rückfrage — dieselbe Haltung wie beim Falten
|
||||
(D38-Nachtrag 2). Vorher wird der **aktuelle** Stand weggelegt, falls er noch
|
||||
nicht drin ist; sonst wäre ausgerechnet er das Einzige, was das Zurückholen
|
||||
verlöre.
|
||||
|
||||
**Pad-Dokumente (D31) bleiben außen vor.** Ihr Textfeld ist schreibgeschützt —
|
||||
ein alter Stand ließe sich dort gar nicht einsetzen, und Stände zu sammeln,
|
||||
die niemand laden kann, wäre nur Ballast. Der Knopf ist dort verborgen
|
||||
(`src.readOnly` bewacht Sammeln, Laden und Sichtbarkeit).
|
||||
|
||||
**Platzierung: rechts neben dem Dokumenten-Wähler** (Nutzer-Vorgabe), beide in
|
||||
einer Gruppe, die das `margin-right:auto` trägt. Der Positionsbezug des Menüs
|
||||
ist der **Knopf**, nicht die Gruppe: An der Gruppe ausgerichtet (`right:0`)
|
||||
begann es 190 px weiter links und lief aus dem Panel heraus — in der ersten
|
||||
Fassung gebaut, im Bild sofort zu sehen und nachgemessen (linke Kante bei
|
||||
−65 px). Jetzt `position:relative` an einer Hülle um den Knopf und `left:0` am
|
||||
Menü: linke Kante bei 99 px, gleichauf mit dem Knopf, ganz im Panel.
|
||||
|
||||
Jeder Eintrag nennt **Uhrzeit und Zeilenzahl** — die Zeilenzahl sagt auf einen
|
||||
Blick, welchen der ähnlich benannten Stände man greift. Neueste zuoberst,
|
||||
danach sucht man zuerst.
|
||||
|
||||
**Nachgemessen** (Takt für die Prüfung auf 2 s verkürzt, danach zurückgestellt
|
||||
und geprüft): ohne Eingabe kein Eintrag; nach einer Eingabe genau einer; ohne
|
||||
weitere Eingabe kommt keiner dazu; nach 29 Änderungen sind es **20** (gedeckelt,
|
||||
Zeitstempel aufsteigend, der älteste ist der kleinste Text). Menü: 20 Einträge,
|
||||
neueste zuoberst. Klick auf einen älteren Eintrag lädt ihn (36 → 32 Zeilen),
|
||||
schließt das Menü, das Diagramm zeichnet neu (30 Knoten) — und ein `undo` holt
|
||||
den vorherigen Stand zeichengenau zurück. Der **Pad-Fall** ist durch die
|
||||
`readOnly`-Wächter im Code abgedeckt, aber nicht live durchgespielt (er
|
||||
bräuchte ein echtes Pad).
|
||||
|
||||
Reference in New Issue
Block a user