Skip to content

feat(backup): import/restore UX — exact name, progress buttons, spinner, extraction log#34

Merged
luisguzman-adfa merged 8 commits into
mainfrom
feat/backup-ux
Jun 23, 2026
Merged

feat(backup): import/restore UX — exact name, progress buttons, spinner, extraction log#34
luisguzman-adfa merged 8 commits into
mainfrom
feat/backup-ux

Conversation

@luisguzman-adfa

Copy link
Copy Markdown
Collaborator

UX polish for the backup import/restore flow. No architecture-validation logic — that lives in #31; this PR is meant to merge first and stay out of its way.

  • Exact imported name: an imported backup keeps its exact filename; on collision, -1/-2/-3 (BackupNameResolver, pure-JVM + unit-tested).
  • Progress buttons: "Launch Server"-style fill on Restore / Backup / Fast-install / Delete; fill uses accent_secondary (purple).
  • Braille spinner in "Import Backup from SD Card" while importing; extraction streams via TarExtractor.onProgress.
  • Contextual extraction log for restore (live tar lines + persistent ✓/result), now dismissible (✕) and using NestedScrollView so it scrolls properly.

New string restore_log_label added to all 6 locales (FR apostrophe escaped for AAPT2).

Verified locally: all 6 string XMLs parse, layout parses, brace balance OK, and the branch merges into main with no conflicts.

Imported backups were renamed to imported_backup_<epoch>.tar.gz, losing the
original name. Now:
- new pure domain BackupNameResolver: keeps the EXACT desired name; on collision
  inserts -1/-2/... before the extension; preserves .tar.gz/.tar.xz; sanitizes
  path/empty/null. Unit-tested (BackupNameResolverTest).
- importBackupSafely queries the SAF content:// DISPLAY_NAME (ContentResolver +
  OpenableColumns) and resolves a unique name against the existing backups.

First part of the backups UX work (single PR); button animations + CLI extraction
log follow on this branch.

(cherry picked from commit da2bd8b)
…xtractor.onProgress)

- Import button shows a minimalist braille spinner while copying, then settles
  (the exact resolved name is shown by the success path).
- TarExtractor: ExtractionListener gains a default no-op onProgress(line); tar now
  runs verbose (-xvf) and streams output lines to the listener on the main thread,
  throttled to ~20/s so it never floods the UI. Enables the contextual CLI log
  (Deploy) without breaking existing listeners.

Next on this branch: ProgressButton on Restore/Backup/Fast-install/Delete + the
contextual CLI log view + persistent result.

(cherry picked from commit da22f14)
…stent result)

Restore now surfaces extraction in-app instead of only logcat:
- new collapsible 'restore_log_panel' in fragment_deploy.xml (terminal-style
  monospace ScrollView + header + result chip), hidden until a restore starts.
- DeployFragment: restore start reveals + clears the panel; the listener's
  onProgress streams tar lines into it (auto-scroll); onComplete shows a green
  check, onError a warning mark -- both PERSIST so the user always sees what
  happened. Reuses existing restore strings; only one new string added.
- New string restore_log_label added to ALL 6 locales (en/es/fr/pt source-quality;
  ru/hi as English placeholders pending the i18n PR).

Compiles as a standalone increment. ProgressButton on the action buttons is next.

(cherry picked from commit e2853d5)
…/Fast-install/Delete

Convert the 4 long-running action buttons to org.iiab.controller.ProgressButton
(layout tags + field types) and drive the animated progress fill from each
action's begin/end:
- Restore: start on begin, stop on onComplete/onError (alongside the CLI log).
- Backup: start on compress begin, stop at all 3 completion/abort/error sites.
- Delete: start on confirm, stop in the finally (on UI thread).
- Fast-install: start on download begin, stop at the central finishInstallationSuccess
  / abortInstallation exits (covers every path).
start/stopProgress are idempotent, so no stuck/duplicated animations.

Concludes the backups UX feature on this branch (name + spinner + CLI + buttons).
Not opening the PR yet per request — pull this branch to build & test live.

(cherry picked from commit 6120aa2)
… error)

'Journal d'extraction' -> 'Journal d\'extraction'. An unescaped apostrophe in an
Android string resource breaks aapt2 ('Can not extract resource from ParsedResource').

(cherry picked from commit a28092f)
…f danger red

The ProgressButton default fill is btn_danger (red), which reads as conflict.
Set app:progressButtonColor=@color/accent_secondary (#6A3FB5, the permissions-
selector purple) on the 4 action buttons — calmer, non-alarming.

(cherry picked from commit c46f549)
Extraction-log UX, with no architecture logic (that lives in #31):
- '✕' close button in the panel header hides the log (frees space).
- Root + inner scroll use NestedScrollView so the log scrolls properly while
  nested in the screen; still auto-scrolls to the latest line during extraction.
…fore)

The leading braille spinner sat next to the button's download icon and read as
noise. Move it to the end of the importing label so it clearly marks progress.
@luisguzman-adfa luisguzman-adfa merged commit bbaa170 into main Jun 23, 2026
1 check failed
@luisguzman-adfa luisguzman-adfa deleted the feat/backup-ux branch June 24, 2026 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant