ui: design system, app shell and messenger refactor (plan P1-P3) #198
Loading…
Reference in a new issue
No description provided.
Delete branch "ui/refactor-shell-messenger"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements P1–P3 of the Android UI/UX refactor plan on one branch: design tokens and a shared component set (P1), the app shell and navigation standard (P2), and the messenger + invite refresh (P3).
View layer only. No Rust core, no FFI/JNI surface, no Tor lifecycle, no
docs/PROTOCOL.md/docs/THREAT_MODEL.md, no.forgejo/workflows/**changes —git diff --stat origin/main...HEAD -- ':!android'is empty.P1 — design system
ui/Theme.ktis now the single source of tokens:OwColors(canvas#0A0C0E, surfaces, mint accent#2EE59D, text ramp, danger/warning/info tints),OwRadius(card 16dp, control 12dp squircles, pill only for status badges and address chips),OwSize, and oneMonoStyle.ui/components/:OwButton(primary/secondary/outline/destructive — the alpha build's 999dp pill made every action look identical),OwButtonRow,OwSegmentedControl,OwAlertBanner,OwCard,OwTopBar,OwBottomTabBar,OwConfirmDialog,OwIcon,OwIconButton,OwStatusDot,OwDivider,OwOverflowMenu,Identicon, plusLabel/Monotype helpers and a single-colour icon set (res/drawable/ic_ow_*.xml).host:portand block heights — never a sentence.P2 — app shell and navigation standard
MainActivityis aScaffoldwhose only job is the persistent bottom tab bar: Chats (default), Wallet, Node & Settings. Sub-screens keep a chevron back button and hide the bar. Tab selection pops to the start destination and restores that tab's saved state.Scaffoldzeroes its owncontentWindowInsets, andModifier.screenContentInsets()appliessystemBars ∪ ime— unioned per-side, never summed — so the composer is not drawn behind the keyboard underenableEdgeToEdge().LocalBottomBarPresentstops a screen padding for the bar twice.⋮overflow: rotate identity and delete message history both land behind a typed confirmation (DELETE), destructive styling confined to the confirm button. Saved wallets and profile live there too.P3 — messenger and invite refresh
Add contact,Share my invite); the empty state names the next step and carries the same two buttons. Stale-locator rows get a warning dot and label instead of a paragraph.OwAlertBannerfor the "not discoverable" honesty note. Chat, profile and rotate screens now use the shared top bar and chevron icon instead of a<text glyph.Verification
Run in the worktree
/home/lancelot/Projects/onionwire/.worktrees/t_718859b4/android(the earlier "213 tests pass" evidence was collected in the main checkout and did not include this branch's files — discarded):./gradlew :app:compileDebugKotlin—BUILD SUCCESSFUL, 33/33 tasks executed, 0 warnings (the one KT-73255 annotation-target warning was fixed in7d86fd6)../gradlew :app:testDebugUnitTest --rerun-tasks—BUILD SUCCESSFUL, 16 classes / 221 tests / 0 failures / 0 errors, including the two new JVM testsRosterOnionTest(a v3 locator keeps its.onionsuffix; the suffix is never the part cut) andcomponents/IdenticonTest.This is local verification only — CI builds the APK and publishes. Nothing here claims a shipped APK.
Notes for review
WalletScreen.ktandWalletManagerScreen.ktkeep their textBackbuttons: they are the apk-dev child card's scope and are deliberately untouched here.android/README.mddocuments the shell, the token locations and the new file layout.Follow-up commits on the branch
7d86fd6— dropped the leftovered25519 pubkeyphrase from aChatScreenKDoc so the Phase-3 acceptance grep is empty acrossui/, and pinned@DrawableResto@param:(KT-73255). Compile is warning-free.5a47019— empty state now matches §3.3 exactly: the shield is muted (the accent stays on the primary CTA) and the heading is 18sp/600 rather than 16sp.dc45d9c— the last raw Material buttons (chat send, profile save, both rotate actions) now go throughOwButton; it gained an optionalRowScopecontent slot so chat-send keeps its spinner. Rotate's confirm is the Destructive tier and the post-rotation action is "Share the new invite" (the top bar already owns the chevron back).Re-verified after the last commit:
:app:compileDebugKotlinand:app:testDebugUnitTestondc45d9c— 221 tests / 0 failures / 0 errors (16 classes). CI (android-ci / android) reportedpending/ "Waiting to run" on this head when the card was handed off; no APK is claimed from this PR.Plans P2 and P3 are one change: the shell decides who calls the roster, so the roster cannot land before it. The tree is green at this commit, which is why they are not split. Shell (P2) - The horizontal text-link bar is gone. Three top-level destinations hang off a persistent 64dp bottom bar — Chats (default), Wallet, Node and Settings — and everything else is a sub-screen behind a chevron. - MainActivity owns the shell: a Scaffold with the tab bar around a NavHost of chats / wallet / settings plus share, paste, chat, profile, wallets and rotate. Tab selection pops back to the start destination and restores saved state, so a chat left open behind the Wallet tab survives a trip to Settings. - The node keeps living on the wallet screen, where its card already is, so the third tab is the security surface: profile, saved wallets, rotate identity, delete message history, the keep-alive status row, and — disclosed here instead of under the roster — the identity/SDK lines that made the home screen read as a test build. - OwTopBar: 20sp bold title, optional "Tor active" pill beneath it, a 36dp padlock surface for Lock, and the overflow. Rotate identity, saved wallets and delete history live in the overflow; the destructive two go through a typed confirmation dialog or the typed ROTATE screen, never a single tap. - Insets: the tab bar consumes the navigation-bar inset and LocalBottomBarPresent tells screens inside the shell not to pad for it again, so there is no double gap above the tabs and the IME still wins when the keyboard is up. - window.isNavigationBarContrastEnforced = false on Q+, so the system's translucent scrim does not draw a second band over the canvas. Messenger (P3) - The identity block is one bar: identicon, "Your identity", the truncated fingerprint in mono, a copy-invite icon and a QR icon. Gone from here: the YOU (stable forever) card, the "sdk … · identity = ed25519 pubkey" line and the keep-alive paragraph. The full fingerprint and locator stay on the profile and invite screens. - The empty state says what to do and offers both ways out ("Add contact", "Share my invite"), and keeps the honest sentence: invites are not discoverable. - Friend rows: petname, short mono fingerprint, and a locator shortened as head…tail.onion — the suffix is never the part that is cut, and a v3 onion is never soft-wrapped. - Invite sharing shows a QR of the payload beside the copyable text; the clip is marked sensitive on API 33+. No ViewModel, SDK, Tor or wallet call changed. Every callback is the call the old screens made; the wallet screens are untouched for the next card.