fix: drive the notification prompt from live permission state - #147
Merged
Conversation
The "Enable notifications" snackbar never went away once the permission was granted. MainActivity computed hasNotificationPermission once, eagerly, while building the setContent argument list: a plain Boolean reading no snapshot state, so it never recomposed. The snackbar's LaunchedEffect was keyed on that frozen value, and Material3's showSnackbar defaults to an indefinite duration when an actionLabel is present, so nothing ever cancelled the suspended call. Replace the three uncoordinated call sites with a single state holder, rememberNotificationPermissionState(), and render the prompt as plain state-driven UI rather than through showSnackbar — the pattern already used by AddDescriptorSnackbar. Visibility is now a function of the permission, so a grant retracts the prompt with no coroutine to cancel. Also fixed in the same flow: - The node no longer dies when notifications are declined. Service start was gated on the permission callback, so denying left FlorestaService never started: no sync, and no Electrum server for connected wallets. A dataSync foreground service starts fine without POST_NOTIFICATIONS; only its notification is withheld. - No dialog is opened on launch any more. MainActivity fired one before setContent (so the snackbar rendered underneath it) and ScreenNode fired a second, competing one whose result was discarded. The dialog now opens only when the user taps the action. - The action no longer dead-ends after Android's automatic "don't ask again": it switches to "Open settings" and opens the app's settings page. On Android 12 and below, where there is no runtime permission, it starts in that mode. - After a denial the message escalates to warn that wallets lose access to the Electrum server. - Prompt dismissal survives rotation (rememberSaveable), and the descriptor prompt is held back while this one shows so the two cannot overlap. - Strings moved to strings.xml; dead Notifications.kt and the now-unused helper functions removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nothing in journeys/ touched notifications, so the snackbar regression had no guard. Add two journeys and document the snackbar_enable_notifications tag. enable_notifications_snackbar.xml is the regression repro: no dialog on launch, tap Enable, grant, and assert the prompt retracts itself without being dismissed. notification_permission_denied.xml covers the denial path, including that the node keeps running and serving Electrum with the permission refused, and that the action escalates to "Open settings" after Android applies "don't ask again". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jvsena42
enabled auto-merge (rebase)
July 30, 2026 18:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The "Enable notifications" snackbar never went away once the permission was granted through the system dialog.
MainActivitycomputedhasNotificationPermissiononce, eagerly, while building thesetContentargument list — a plainBooleanreading no snapshot state, so it never recomposed. The snackbar'sLaunchedEffectwas keyed on that frozen value, and Material3'sshowSnackbardefaults to an indefinite duration when anactionLabelis present, so nothing ever cancelled the suspended call.Reproduced on
main:POST_NOTIFICATIONS: granted=truewith the snackbar still on screen 26s later.The fix replaces three uncoordinated call sites (
MainActivity.onCreate,MainScreen, and a second competing requester inScreenNode) with one state holder,rememberNotificationPermissionState(), and renders the prompt as plain state-driven UI instead ofshowSnackbar— the patternAddDescriptorSnackbaralready uses, whose existing comment explains whyshowSnackbaris wrong for persistent prompts. Visibility is now a function of the permission, so a grant retracts the prompt with no coroutine to cancel.Other gaps found in the same flow
FlorestaServicenever started — no sync, and no Electrum server for connected wallets. Confirmed onmain: network/peers/difficulty stuck at—, 0 peers. AdataSyncforeground service starts fine withoutPOST_NOTIFICATIONS; only its notification is withheld.ScreenNodefired a second, competing request whose result was discarded. Nothing opens the dialog now except the user tapping the action.rememberSaveable); the descriptor prompt is held back while this one shows so the two cannot overlap; strings moved tostrings.xml; deadNotifications.ktand unused helper functions removed.Verified on device (emulator, x86_64, Android 16 / API 36)
permission_allow_buttonabsentgranted=true,snackbar_enable_notificationsgone, same pidON_RESUMEre-checkflags=[USER_SET|USER_FIXED]isForeground=true, progress0.998945 → 0.998949server.version→["Floresta 0.5.1","1.4"],blockchain.headers.subscribe→ height960288Not verified: the API 29–32 path is reasoned from the code, not executed — only API 35/36 system images are installed locally.
Checklist
feat:,fix:,chore:, ...)journeys/README.mdtestTags updated for UI changes./gradlew detekt,./gradlew lintDebug, and./gradlew testpass locallyPreview
New
snackbar_enable_notifications, shown above the bottom nav on every tab:Enable· ✕Enable· ✕Open settings· ✕Screenshots of all three states were captured locally at
shots/1-initial-prompt.png,2-after-denial.png,3-open-settings.png— attaching images isn't possible from the CLI, so drop them in if you want them inline.🤖 Generated with Claude Code