aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-02 20:30:58 +0100
committerDanilo M. <danix@danix.xyz>2026-11-02 20:30:58 +0100
commit4d727989e9114160092f65daa6d4e9f2da384772 (patch)
treed5a306b7f1e7fd916635c12cf9b1db81c68f1913
parenta884718d39bbf7e723a6cce42ff40dcb016038d7 (diff)
downloadHardenedPass-4d727989e9114160092f65daa6d4e9f2da384772.tar.gz
HardenedPass-4d727989e9114160092f65daa6d4e9f2da384772.zip
docs: add the Compose UI overhaul design
Single-activity Compose rewrite with a Material 3 look and breadcrumb folder chips, done on a temporary compose branch and released only once complete. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--docs/superpowers/specs/2026-11-02-compose-ui-overhaul-design.md133
1 files changed, 133 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-11-02-compose-ui-overhaul-design.md b/docs/superpowers/specs/2026-11-02-compose-ui-overhaul-design.md
new file mode 100644
index 00000000..77e1dcae
--- /dev/null
+++ b/docs/superpowers/specs/2026-11-02-compose-ui-overhaul-design.md
@@ -0,0 +1,133 @@
+# Compose UI overhaul: design
+
+Date: 2026-11-02. Status: approved, not started.
+
+## Goal
+
+Replace every XML/View/Fragment screen in HardenedPass with Jetpack Compose, inside a single
+activity, and give the app a new Material 3 look. Visuals, flows and the underlying UI stack all
+change; the data layer does not. Nothing is released until the whole move is complete and stable;
+the maintainer's phone stays on 0.1.4 until then.
+
+## Visual direction
+
+- Material 3 "Material You": dynamic color on Android 12+, a fixed purple scheme on Android 8 to
+ 11 (minSdk 26). Light and dark follow the system.
+- Pill-shaped search bar at the top of the list, grouped rounded surfaces, letter avatars on
+ entries, extended FAB ("New entry").
+- Folder location shown as breadcrumb chips (root, then each folder); the last chip is
+ highlighted. Tapping a chip jumps to that level.
+
+### Password list
+
+- Breadcrumb chips under the search bar.
+- Folders in one grouped surface, entries in another below it. Folder rows show their entry
+ count; entry rows show the username, plus "OTP" when the entry has one.
+- Pull to sync. Long-press starts multi-select (move, delete). FAB opens the create sheet
+ (entry or folder).
+
+### Entry view
+
+- Header: avatar, entry name, folder path. Top bar: back, edit, overflow.
+- First group: password (masked, reveal toggle, copy), username (copy), one-time code with a
+ countdown bar (copy).
+- Second group: remaining extra fields, copy where it makes sense.
+
+### Editor
+
+- Top bar: close, title, Save.
+- Name field, folder as breadcrumb chips with "change" (opens the folder picker).
+- Password with reveal and a generator button; the generator is a bottom sheet with random and
+ diceware tabs.
+- Username field, free-text extra content (pass format kept as text, nothing hidden).
+- "OTP from QR" and "OTP manual" actions.
+
+## Architecture
+
+### Activities
+
+- `MainActivity` (new, not exported, extends `FragmentActivity` for `BiometricPrompt`, uses no
+ fragments) hosts a Compose `NavHost`. It replaces `PasswordStore`, `DecryptActivity`,
+ `PasswordCreationActivity`, `SelectFolderActivity`, `OnboardingActivity`, `SettingsActivity`,
+ `GitServerConfigActivity`, `GitConfigActivity`, `GitLogActivity`, `ProxySelectorActivity`,
+ `SshKeyGenActivity`, `SshKeyImportActivity`, `PGPKeyImportActivity` and `PGPKeyListActivity`.
+- `LaunchActivity` stays the only exported activity. It keeps the biometric gate and the
+ `isFileInRepo` check, then starts `MainActivity` with either the list route or an entry route
+ (dynamic shortcuts).
+- Kept as separate activities, because the autofill service launches them directly:
+ `AutofillDecryptActivity`, `AutofillSaveActivity`, `AutofillPublisherChangedActivity`,
+ `AutofillFilterView`. Their UI moves to Compose with the shared theme.
+- The zxing `CaptureActivity` stays as is (third-party, launched for a result).
+
+### Navigation and state
+
+- `navigation-compose` with type-safe routes (kotlinx-serialization plugin) and
+ `hilt-navigation-compose` for `hiltViewModel()`. These are the only new dependencies.
+- Screens are stateless composables (state in, callbacks out), each driven by a ViewModel.
+ Existing ViewModels (`SearchableRepositoryViewModel`, `PGPKeyListViewModel`) are reused where
+ they fit.
+- Dialogs (folder creation, password generators, OTP import) become Compose dialogs or bottom
+ sheets within the graph.
+- Settings is a few hand-written Compose preference rows (switch, list, click) over the existing
+ `SharedPreferences` keys. No settings library.
+
+### Unchanged
+
+Crypto, git, autofill parsing, preference keys, the Keystore-backed secret storage, clipboard
+handling and the passphrase cache. Existing stores, keys and settings carry over without
+migration.
+
+### Removed at the end
+
+`fragment-ktx`, `recyclerview`, `recyclerview-selection`, `swiperefreshlayout`,
+`modernandroidpreferences`, the view-binding helpers (`FragmentViewBindingDelegate`,
+`FragmentExtensions`), all layout XML files, and Material Components (Views) if nothing still
+needs it.
+
+## Security
+
+- `FLAG_SECURE` is set on the window while the entry view or editor destination is shown and
+ cleared when leaving it, so secrets stay out of screenshots and recents.
+- `MainActivity` is not exported. Routes come only from `LaunchActivity` after its checks; an
+ entry route is still validated with `isFileInRepo`.
+
+## Error handling
+
+Same behavior as today: git, crypto and IO failures surface as a snackbar or dialog on the
+screen that triggered them. Nothing new is swallowed.
+
+## Branching
+
+Work happens on a temporary `compose` branch, an explicit exception to the master-only rule in
+AGENTS.md (recorded there when the branch is created, removed at merge). `master` stays
+releasable for the monthly public suffix list update and hotfixes to 0.1.4. The branch is pushed
+to `origin` as a backup. CI is not extended to the branch: the local pre-commit check from
+AGENTS.md runs before every commit, and CI runs at the merge.
+
+## Migration order
+
+Each step leaves the branch building and runnable. Screens not yet ported are opened from the
+graph through their old intents.
+
+1. Foundation: dependencies, `MainActivity` and `NavHost`, theme, shared components (breadcrumb
+ bar, entry row, field row, grouped surface), `LaunchActivity` routing.
+2. Password list: browsing, search, pull-to-sync, multi-select, create sheet.
+3. Entry view: decrypt, passphrase and biometric prompts, OTP, copy, `FLAG_SECURE`.
+4. Editor: generator sheet, folder picker, OTP from QR and manual.
+5. Setup: onboarding, git server config and clone, SSH keygen and import, PGP import and key
+ list.
+6. Settings, git log, proxy.
+7. Autofill activities' UI.
+8. Cleanup: delete old activities, layouts and dependencies; update AGENTS.md; merge to
+ `master`.
+
+## Testing
+
+- Existing unit tests keep passing.
+- Logic moved into new ViewModels (breadcrumb path, selection, field grouping for the view) gets
+ unit tests.
+- Every step is checked on the `aps-test` emulator against the e2e git server
+ (`scripts/e2e-env.sh`).
+- Before merge: the full device checklist from AGENTS.md (clone over SSH, PGP import, decrypt,
+ TOTP, create and push, conflict recovery, hard reset, fingerprint unlock, Firefox autofill),
+ then the maintainer tests on the phone.