Afsluiten na git-opslag telt als geslaagd, ook als opslaan faalde of werd geannuleerd #1948

Closed
opened 2026-09-03 10:14:15 +00:00 by brenno · 0 comments
Owner

Het probleem

Wie een deck uit git open heeft en de app sluit, krijgt de vraag om op te slaan. Kiest hij Opslaan, dan gaat OciDeck altijd verder alsof dat gelukt is: de herstelbestanden worden gewist en de app sluit.

Dat gebeurt ook als:

  1. de gebruiker de git-opslaan-dialoog annuleert;
  2. de commit of push faalt (netwerk, conflict, auth);
  3. _saveToGit een snackbar toont met "opslaan mislukt".

De wijzigingen staan dan niet in de repo, de herstelkopie is weg, en de app is dicht. Dat is dataverlies plus een stille leugen: de afsluitlus dacht dat alles bewaard was.

WebDAV en S3 geven bij een fout wél false terug en blokkeren het sluiten. Git is de uitzondering.

Hoe het nu werkt

Afsluiten in lib/widgets/app_shell.dart:

case _CloseChoice.save:
  final saved = await _saveAllDirtyTabs();
  if (saved) await _destroy();

_destroy wist de herstelbestanden (discardEach) en roept quitApp aan.

_saveAllDirtyTabs vraagt saveTabWithDestination, die bij een git-herkomst _saveToOrigin aanroept:

case GitOrigin():
  await _saveToGit(context, ref);
  return true;

_saveToGit (lib/widgets/shell/shell_actions_git.dart) is Future<void>. Het vangt uitzonderingen zelf, toont een snackbar, en geeft geen succes/falen terug. Annuleren van de commitdialoog is ook een stille return. Daarna is true al onderweg naar de afsluitlus.

Waarom dat zo gebouwd is

Git-opslaan vraagt om een commitboodschap en kan in een wachtrij of conflict eindigen. Die rijkere uitkomst (GitSaveStatus) is nooit aangesloten op de bool die de rest van de app als "is het bewaard?" gebruikt. WebDAV/S3 zijn later wél op die bool gezet.

Denkrichting (niet uitgewerkt)

Laat _saveToGit een bool (of GitSaveStatus) teruggeven. Alleen committed, merged en queued zijn "bewaard genoeg om herstel te wissen". failed, conflict, pushFailed en annuleren zijn false: venster blijft open, herstel blijft liggen.

pushFailed is een grijze zone: lokaal is er een commit. Dan mag sluiten, maar wis herstel pas als die commit er écht is, en zeg dat publiceren nog moet.

Raakvlakken

  • lib/widgets/shell/shell_actions_connections.dart (_saveToOrigin)
  • lib/widgets/shell/shell_actions_git.dart (_saveToGit)
  • lib/widgets/app_shell.dart (_handleClose, _saveAllDirtyTabs, _destroy)
  • lib/state/tabs_provider_git.dart (GitSaveStatus)

Geen bestandsformaatwijziging. Regressietest: afsluiten met een vuil git-tabblad waarvan opslaan faalt of wordt geannuleerd — de app mag niet sluiten en mag de herstelkopie niet wissen.

## Het probleem Wie een deck uit git open heeft en de app sluit, krijgt de vraag om op te slaan. Kiest hij **Opslaan**, dan gaat OciDeck altijd verder alsof dat gelukt is: de herstelbestanden worden gewist en de app sluit. Dat gebeurt ook als: 1. de gebruiker de git-opslaan-dialoog **annuleert**; 2. de commit of push **faalt** (netwerk, conflict, auth); 3. `_saveToGit` een snackbar toont met "opslaan mislukt". De wijzigingen staan dan niet in de repo, de herstelkopie is weg, en de app is dicht. Dat is dataverlies plus een stille leugen: de afsluitlus dacht dat alles bewaard was. WebDAV en S3 geven bij een fout wél `false` terug en blokkeren het sluiten. Git is de uitzondering. ## Hoe het nu werkt Afsluiten in `lib/widgets/app_shell.dart`: ```dart case _CloseChoice.save: final saved = await _saveAllDirtyTabs(); if (saved) await _destroy(); ``` `_destroy` wist de herstelbestanden (`discardEach`) en roept `quitApp` aan. `_saveAllDirtyTabs` vraagt `saveTabWithDestination`, die bij een git-herkomst `_saveToOrigin` aanroept: ```dart case GitOrigin(): await _saveToGit(context, ref); return true; ``` `_saveToGit` (`lib/widgets/shell/shell_actions_git.dart`) is `Future<void>`. Het vangt uitzonderingen zelf, toont een snackbar, en geeft geen succes/falen terug. Annuleren van de commitdialoog is ook een stille `return`. Daarna is `true` al onderweg naar de afsluitlus. ## Waarom dat zo gebouwd is Git-opslaan vraagt om een commitboodschap en kan in een wachtrij of conflict eindigen. Die rijkere uitkomst (`GitSaveStatus`) is nooit aangesloten op de `bool` die de rest van de app als "is het bewaard?" gebruikt. WebDAV/S3 zijn later wél op die `bool` gezet. ## Denkrichting (niet uitgewerkt) Laat `_saveToGit` een `bool` (of `GitSaveStatus`) teruggeven. Alleen `committed`, `merged` en `queued` zijn "bewaard genoeg om herstel te wissen". `failed`, `conflict`, `pushFailed` en annuleren zijn `false`: venster blijft open, herstel blijft liggen. `pushFailed` is een grijze zone: lokaal is er een commit. Dan mag sluiten, maar wis herstel pas als die commit er écht is, en zeg dat publiceren nog moet. ## Raakvlakken - `lib/widgets/shell/shell_actions_connections.dart` (`_saveToOrigin`) - `lib/widgets/shell/shell_actions_git.dart` (`_saveToGit`) - `lib/widgets/app_shell.dart` (`_handleClose`, `_saveAllDirtyTabs`, `_destroy`) - `lib/state/tabs_provider_git.dart` (`GitSaveStatus`) Geen bestandsformaatwijziging. Regressietest: afsluiten met een vuil git-tabblad waarvan opslaan faalt of wordt geannuleerd — de app mag niet sluiten en mag de herstelkopie niet wissen.
brenno 2026-09-03 15:45:51 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#1948
No description provided.