mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
8746bfebfffd31e418b439d262cbb70de54aafa4
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
33f54de2dd |
feat(mobile): organize community and profile settings (#8056)
## Summary Move Invite, Appearance, and Remove community into a **Community settings** section in the community-avatar sheet, above the existing switcher. Keep the sheet untitled and use circle-minus for removal. Personal Settings groups **Set status** and **Copy public key (npub)** above an untitled card containing **Display name**, **Profile description**, and **Edit photo**. Remove the leading icons from status, public key, and Send identity to desktop; keep the latter in its own untitled card. Remove the avatar status badge and top Edit action, and rename the Theme page to **Appearance**. Opening the presence chip triggers selection haptics; copying plays native iOS success feedback and confirms with “Public key (npub) copied.” ### Testing - Mobile formatting, analysis, and file-size checks passed. - 111 affected widget tests passed; all 48 settings tests passed again after the final labels and icon changes. - Final release build installed and launched on a physical iPhone in the separate Buzz Community preview, retaining its existing test account. - Full repository `just ci` was blocked by local disk exhaustion during Rust compilation. The full mobile suite passed (2,609 passed, four skipped), plus three push-unconfigured tests. The presence and copy feedback passed focused widget tests and analysis, including native iOS success-channel coverage. ### Snapshots Light and dark Flutter widget renders with fixture data. Images are GitHub attachments, not committed to the repository. The personal-settings snapshots precede the final “(npub)” label clarification. | Surface | Light | Dark | | --- | --- | --- | | Community sheet | <img src="https://github.com/user-attachments/assets/d52a192e-bd40-4263-ac2d-05d589c7ebf2" width="280" alt="Community sheet, light"> | <img src="https://github.com/user-attachments/assets/8756ebe9-b6d4-4920-8fb7-1cb7ee8ef778" width="280" alt="Community sheet, dark"> | | Personal settings | <img src="https://github.com/user-attachments/assets/962b98bd-e4cf-4cd1-8948-69b349390ceb" width="280" alt="Personal settings, light"> | <img src="https://github.com/user-attachments/assets/223bb0a8-e10e-43b1-83ea-e0955af4627a" width="280" alt="Personal settings, dark"> | | Appearance | <img src="https://github.com/user-attachments/assets/334ba797-55cb-47ce-b677-0befafb7659b" width="280" alt="Appearance, light"> | <img src="https://github.com/user-attachments/assets/79b62503-d476-4dbc-8c75-8cee0ee37e98" width="280" alt="Appearance, dark"> | --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> |
||
|
|
fad4ff637a |
fix(mobile): hide notification settings without relay push capability (#8025)
Hide the iOS Notifications settings section for communities that have not enabled push unless their relay advertises valid push support. A build with a configured gateway previously showed the switch even when the relay could not support push. Communities where push is already enabled retain an off switch and iOS Settings recovery during discovery or when push support is unavailable. The section explains that support is unavailable instead of claiming notifications will arrive. Capability discovery keeps its existing refresh behavior. Returning after at least five seconds in the background reconnects the session and fetches capability again. Tom explicitly chose this behavior without new retries, polling, or refresh triggers. Companion client change for squareup/buzz-releases#104. Related: #7826 (broader notification availability diagnostics). ### Validation Settings widget tests cover hidden first-time opt-in during loading, absent capability, and discovery errors. Recovery tests exercise the real off switch for already-enabled communities in all three states, verifying persisted opt-out, the native snapshot writer, a durable pending relay tombstone after failure, and the iOS Settings link. They also verify that pending recovery stays visible after a relay failure and disappears only after opt-out confirmation. Tests without a gateway definition verify hidden first-time settings and disabled native registration. Mobile analysis and the mobile test suite passed. --------- Signed-off-by: Tom Brow <tomb@block.xyz> |
||
|
|
b8aa0233f9 |
perf(mobile): verify notification cache events in background (#7650)
On iOS, Buzz stores verified profile and channel information for the notification extension. The extension uses this cache to show sender and channel names. Loading profiles or channels also updates the cache. Cache updates currently check event signatures on the UI thread, even when the caller does not wait for the update. This can delay taps and screen updates. This change moves those checks to a background worker. Signature checks, event selection, community boundaries, and the order of native writes are preserved. The worker accepts up to eight batches. When it is busy, later profile requests stay coalesced before fetching; profiles already loaded remain available immediately. Overlapping channel updates trigger a fresh joined-channel cache snapshot after the current export finishes, without delaying or restarting the channel screen. Queue saturation gets up to five retries per operation. Pending updates get their own recovery attempt even if the preceding export fails. Recovery fetches joined-channel data once and retries cache admission without repeating relay reads. It does not fetch the open-channel directory. Verified payloads are split into native-sized writes (256 profiles or 512 paired channels), keeping the same export ordering. Native profile/channel write failures retry the same verified chunk while retaining the export's queue position. All chunks share five retries with 7.75 seconds total backoff; other native errors fail immediately. Terminal failures are recorded, and later successful writes do not hide them. Captured batches keep their original community. Pending channel refetches are retired on a community switch and refreshed when the user returns. The cache remains best effort; prolonged failures can still prevent delivery. Tests through the production APIs reduced UI delay from 27–31 ms to below 0.3 ms for four profiles, and from 59–60 ms to below 0.3 ms for four channel and membership pairs. The native payloads were identical. This does not measure overall screen speed. Validation: 2,225 mobile tests passed (one skipped), along with 18 focused export tests, 12 recovery tests, 39 native Swift tests, 35 focused profile tests, and static analysis. Production regressions cover 13-entity bursts, invalid newer events, community rebuilds, reentrant refreshes, and terminal failures. Regression tests fail when producer recovery controls, terminal-failure draining, or member-only recovery scope are removed. --------- Signed-off-by: Tom Brow <tomb@block.xyz> |
||
|
|
76f7e5ef0c |
feat(push): make gateway origin configurable (#7261)
Make the push gateway origin configurable across the relay, gateway, mobile client, and deployment chart. This is a fresh deployment. The gateway has only run on personal development infrastructure, and push has no existing enabled users. Legacy migration, configured-to-unconfigured mobile transitions, and rolling upgrades from pre-launch gateway binaries are not supported. Populated pre-launch databases are rejected with an informative error before migrations run; their data is untouched. Mobile builds may omit the gateway URL, leaving push unavailable. Once push is enabled, subsequent builds must retain that configuration. ### Validation - All applicable CI checks pass at `5f546cfaf403f0386f146d213adfb4392f4ec29c`, including Rust, mobile/Swift, desktop/integration, security, image builds, and Helm checks. An unrelated agent cancellation test passed on retry. - PostgreSQL CI passed 384 tests, including the production-entry-point regression for refusing populated pre-launch databases before migrations, fresh initialization, and subsequent initialized deployments. - Focused local validation passed all 10 gateway PostgreSQL tests under the CI discovery filter and all 3 unconfigured-mobile tests. Repository-wide PostgreSQL discovery validation and the complete pre-push hooks passed. - Physical-device APNs/App Attest behavior and deployment to a live cluster were not verified in this work. --------- Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> |
||
|
|
f78a32cf03 |
feat(mobile): hard-block under-18 users on the store age signal (#4665)
### What changed? Buzz mobile checks the app-store age signal at launch and hard-blocks the app behind a full-screen 18+ notice when the store says the signed-in person is under 18. No age signal (e.g. declined permission, indeterminate value, unsupported OS versions) results in no block. The age value is never persisted. It is read, used to compute one boolean, and discarded. Nothing is written to disk, and neither the age value nor the range is logged or sent to analytics. Platform notes: - **New dependency `com.google.android.play:age-signals:0.0.4`.** This is the only way to read the Play signal. Its AAR declares `minSdkVersion 23`, below the app's 24, so it forces **no minSdk bump**, and it self-declares its own consent activity, so **no AndroidManifest change** is needed. - **iOS entitlement and linking.** `DeclaredAgeRange` autolinks from the import. `Runner.entitlements` now declares `com.apple.developer.declared-age-range`, and the call remains behind `#available(iOS 26.0, *)`. ### Why? App stores now expose a declared-age range, and Buzz's Terms require users to be 18 or older. This wires the store signal to that rule with the smallest change that is defensible. Absent signals, declined or undeterminable results, and unsupported OS versions allow the app through. A transient native request failure does not become evidence that access is allowed: the app remains gated until a retry produces a result. Only an affirmative under-18 signal produces the permanent restriction screen. ### How is it tested? Added tests: - [`age_signal_provider_test`](https://github.com/block/buzz/tree/main/mobile/test/features/age_gate) covers the 17/18 boundary, open-ended ranges, no-signal, transient recovery, bounded retry exhaustion, malformed payloads, and request-once behavior - [`age_gate_app_test`](https://github.com/block/buzz/tree/main/mobile/test/features/age_gate) proves authenticated content remains unmounted while the signal is pending or retryable, and verifies the retry path - [`age_restriction_page_test`](https://github.com/block/buzz/tree/main/mobile/test/features/age_gate) asserts the block screen offers no bypass affordance - [`community_provider_test`](https://github.com/block/buzz/tree/main/mobile/test/shared/community) verifies age restriction clears push state, persists inactive leases, and retries a failed tombstone - [`AgeSignalPayloadTest`](https://github.com/block/buzz/tree/main/mobile/android/app/src/test/kotlin/xyz/block/buzz/mobile) pins the Android success payload to exactly `{status, ageUpper}` and verifies failures return the distinct retryable platform error ### Deployment note Enable the Declared Age Range capability and regenerate signing profiles carrying the entitlement. This relops/App Store Connect task is not performed by this PR. *🤖 This PR was authored [with an agent](codex://threads/019e5128-536b-73b3-8348-88651123f6da).* | Age restriction screen | | --- | | <img src="https://github.com/user-attachments/assets/5b0f48b1-df9b-4a60-9800-80b33f128535" alt="Age restriction screen" width="320"> | --------- Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: npub12wpjffj7q5qjsky5jvk4ldwlxmse5xll3d8gytk4wqd0c5y7jvwspg37n6 <538324a65e0501285894932d5fb5df36e19a1bff8b4e822ed5701afc509e931d@buzz.block.builderlab.xyz> Co-authored-by: npub1tquskdu6yc4h8l7xxtceculxw600grekeq0xg2ukqfrwl7vrzg3quz3gmp <58390b379a262b73ffc632f19c73e6769ef40f36c81e642b960246eff9831222@buzz.block.builderlab.xyz> Co-authored-by: Codex <noreply@openai.com> |
||
|
|
c432a111ca |
feat(mobile): push notifications MVP (#6269)
This PR implements MVP, iOS-only,
[NIP-PL](
|