Commit Graph
4 Commits
Author SHA1 Message Date
8abc2baf0b Add mobile community invites (#5641)
## Summary
- add a permission-gated mobile community invite page
- create, copy, and natively share configurable invite links
- invite a validated npub directly with member/admin role selection
- reuse Buzz profile actions, search styling, settings rows, and modal
sheets

## Validation
- `just mobile-check`
- `flutter test` (1,275 tests)
- Pixel and iPhone review builds installed and launched

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Kenny Lopez <klopez4212@gmail.com>
Signed-off-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz>
Co-authored-by: Carl <3c4caeafb646d23867f1c4832e68211d77e2561946171625f75c3ce1a3f2670f@buzz.block.builderlab.xyz>
Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz>
2026-08-13 17:47:44 +01:00
6eb65919f1 feat(identity): recover desktop identity from a signed-in phone (#4845)
**Category:** new-feature
**User Impact:** People who lose a desktop identity can securely restore
it from a signed-in Buzz phone without creating a replacement identity.

**Problem:** A fresh or identity-lost desktop could not recover its
existing full Buzz identity from an already-authorized phone.

**Solution:** Add a SAS-confirmed reverse NIP-AB transfer, durable
desktop import, a dedicated mobile recovery entry point, and clearer
desktop recovery dialogs with tested loading, drag-and-drop, and failure
states.


https://github.com/user-attachments/assets/e9215c9c-80d0-462f-9161-0fa184ca2f74

<details>
<summary>File changes</summary>

**crates/buzz-core/src/pairing/session.rs**
Adds the reverse encrypted payload and source-completion state
transitions used for phone-to-desktop recovery.

**desktop/src-tauri/src/commands/identity.rs**
Exposes the existing guarded identity commit path for recovery imports.

**desktop/src-tauri/src/commands/pairing.rs**
Adds recovery-mode pairing, durable nsec import, start serialization,
stale-task protection, and explicit rejection of unsupported recovery
payloads.

**desktop/src-tauri/src/lib.rs**
Registers the recovery pairing command.

**desktop/src/app/App.tsx**
Refreshes the recovered identity before continuing onboarding.

**desktop/src/features/onboarding/machineOnboarding.ts**
Adds recovery transitions to the onboarding state machine.

**desktop/src/features/onboarding/ui/BackupPasswordTimeline.tsx**
Adds the visual backup-to-password-to-unlock progression.

**desktop/src/features/onboarding/ui/IdentityRecoveryPairing.tsx**
Implements QR generation, copy fallback, SAS confirmation, cancellation,
expiry, and completion UI.

**desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx**
Connects private-key, phone, and backup recovery paths to the onboarding
flow.

**desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx**
Polishes recovery dialogs, backup drag-and-drop, loading stability, and
security copy.

**desktop/src/shared/api/tauri.ts**
Keeps the existing pairing API surface focused on standard
desktop-to-mobile pairing.

**desktop/src/shared/api/tauriPairing.ts**
Adds the recovery pairing invoke without growing the ratcheted shared
API file.

**desktop/src/testing/e2eBridge.ts**
Mocks recovery pairing commands and lifecycle events for browser tests.

**desktop/tests/e2e/identity-lost.spec.ts**
Covers lost-identity entry, QR/copy recovery, SAS, cancellation, expiry,
success, errors, backup import, drag-and-drop, and screenshots.

**desktop/tests/e2e/onboarding.spec.ts**
Verifies recovered identities continue through harness setup without
replacement-key side effects.

**mobile/lib/features/pairing/pairing_page.dart**
Adds recovery-only scanning and explicit identity-handoff warnings.

**mobile/lib/features/pairing/pairing_provider.dart**
Recognizes recovery codes, returns the signed-in nsec after mutual SAS
approval, and waits for desktop completion.

**mobile/lib/features/settings/settings_page.dart**
Accepts the recovery route builder at the app composition boundary to
preserve feature isolation.

**mobile/lib/features/settings/settings_page/connection_section.dart**
Adds the signed-in “Send identity to desktop” settings action.

**mobile/test/features/pairing/pairing_page_test.dart**
Covers recovery-only validation and handoff messaging.

**mobile/test/features/pairing/pairing_provider_test.dart**
Covers reverse payload encryption, confirmation ordering, success,
failure, timeout, and cleanup.

</details>

## Reproduction steps

1. Launch Buzz Desktop with identity-lost state and choose **Recover
from your phone**.
2. Confirm the QR and persistent **Copy pairing code** fallback appear
without layout shift.
3. On a signed-in phone, open **Settings → Send identity to desktop**,
scan or paste the recovery code, and compare the six-digit SAS on both
devices.
4. Confirm on both sides and verify Desktop restores the identity and
continues to harness setup.
5. Repeat from identity-lost state with **Recover from a backup file**;
verify picker and drag-and-drop both advance to password entry and
restore the encrypted backup.
6. Exercise cancellation, mismatched/unsupported codes, expired
sessions, and an invalid backup; verify each returns actionable,
non-stuck UI.

## Screenshots

### Desktop phone recovery — complete flow

| Recovery entry | Pairing QR | Code match | Receiving identity |
|---|---|---|---|
| ![Desktop recovery
entry](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-phone-01-recovery-entry.png)
| ![Desktop phone recovery
QR](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-phone-02-qr.png)
| ![Desktop security-code
match](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-phone-03-sas.png)
| ![Desktop receiving
identity](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-phone-04-receiving.png)
|

### iOS Simulator — complete handoff flow

| Settings entry | Recovery scanner | Manual recovery code | Code
confirmation |
|---|---|---|---|
| ![iOS Settings entry for Send identity to
desktop](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/ios-01-settings-entry.png)
| ![iOS recovery scanner
entry](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/ios-02-recovery-entry.png)
| ![iOS manual recovery code
entry](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/ios-03-manual-code.png)
| ![iOS security-code
confirmation](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/ios-04-sas-verification.png)
|

### Encrypted backup recovery — adjusted file flow

| File picker | Drag-and-drop target | Password step |
|---|---|---|
| ![Desktop encrypted-backup file
picker](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-backup-01-file-picker-settled.png)
| ![Desktop encrypted-backup drag-and-drop
target](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-backup-02-drag-drop.png)
| ![Desktop backup password
step](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/4845/desktop-backup-03-enter-password.png)
|

## Verification

- `cargo test -p buzz-core pairing` — 71 passed
- `just mobile-test` — 1,169 passed
- `pnpm build:e2e && pnpm exec playwright test identity-lost.spec.ts
--project=smoke` — 15 passed
- Full pre-push gates — desktop checks, desktop unit tests, Rust tests,
Tauri checks, and mobile tests passed

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
2026-08-06 11:47:18 -07:00
05150c1188 feat(mobile): sync themes per community (#3767)
**Category:** new-feature
**User Impact:** Mobile now keeps each community’s appearance in sync
with desktop, including theme, accent, and system-mode preference.

**Problem:** Appearance choices were device-local, so the same account
could look different between desktop and mobile. Live sync could also
stop after the relay closed a subscription.

**Solution:** Store each community’s encrypted appearance preference on
its relay using the shared desktop wire contract, restore it from a
local identity-scoped cache, and apply replacement events live. Closed
subscriptions now recover with guarded backoff and fetch the latest
preference so no update is lost during the gap.

<details>
<summary>File changes</summary>

**mobile/lib/app.dart**
Connects community appearance state to the authenticated app lifecycle.

**mobile/lib/features/settings/accent_picker_page.dart**
Aligns mobile accent choices and selection behavior with the shared
catalog.

**mobile/lib/features/settings/settings_page/appearance_section.dart**
Clarifies the active appearance and hides accent controls when the Buzz
theme owns its neutral accent.

**mobile/lib/features/settings/theme_picker_page.dart**
Persists catalog theme choices through the community-scoped provider.

**mobile/lib/shared/theme/accent_colors.dart**
Matches desktop’s accent catalog and wire values.

**mobile/lib/shared/theme/buzz_theme.dart**
Keeps Buzz visually neutral without discarding the user’s stored accent
for other themes.

**mobile/lib/shared/theme/community_theme_preference.dart**
Defines and validates the versioned desktop-compatible appearance
payload.

**mobile/lib/shared/theme/community_theme_provider.dart**
Coordinates cache-first appearance loading with account and community
changes.

**mobile/lib/shared/theme/community_theme_sync.dart**
Adds encrypted NIP-78 relay persistence, live replacement handling,
deterministic ordering, safe seeding, and resilient subscription
recovery.

**mobile/lib/shared/theme/theme.dart**
Exports the community appearance modules.

**mobile/test/features/settings/theme_picker_page_test.dart**
Covers the updated settings behavior.

**mobile/test/shared/crypto/nip44_interop_test.dart**
Proves Dart decrypts a desktop-produced nostr-rs NIP-44 v2 preference.

**mobile/test/shared/theme/buzz_theme_test.dart**
Covers Buzz’s neutral rendering and stored-accent restoration.

**mobile/test/shared/theme/community_theme_preference_test.dart**
Covers wire parsing, validation, migration, and future-version handling.

**mobile/test/shared/theme/community_theme_sync_test.dart**
Covers cache/relay lifecycle, replacement ordering, switching races,
absence-only seeding, and closed-subscription recovery.

</details>

## Reproduction steps

1. Sign into desktop and mobile with the same account and join the same
community relay.
2. On desktop, choose a distinctive non-Buzz theme and accent; mobile
should update without a local toggle.
3. Restart mobile and confirm it restores the same appearance.
4. Change the mobile theme and accent and confirm desktop follows.
5. Leave mobile idle or backgrounded through a relay reconnect, then
change desktop again; mobile should resubscribe and catch up
automatically.
6. Switch communities and confirm each community restores only its own
appearance.

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
2026-08-05 13:18:53 -07:00
klopez4212andGitHub dd222a509b Refine mobile settings and themes (#2844)
## Summary
- reorganize mobile settings around profile, appearance, and connection
cards
- add System/Light/Dark theme pairing, accent selection, and the Buzz
gradient theme
- align avatar badges, status editing, and supporting mobile chrome

## Test plan
- `just mobile-check`
- `just mobile-test`
2026-07-26 08:57:31 +01:00