Fix notification-permission flow and onboarding copy for system test notifications#1024
Conversation
… tests - Updated notification permission management to include new states: 'unknown', 'prompt', and 'not_tauri'. - Improved user feedback for notification permission status in the UI. - Added tests for notification permission flow, including success, denial, and retry scenarios. - Refactored notification sending logic to handle errors more gracefully.
📝 Walkthrough🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/components/OpenhumanLinkModal.tsx`:
- Around line 221-224: The denial branch calls getNotificationPermissionState()
with default options which re-triggers a permission request; change the call in
the if (!granted) path to call getNotificationPermissionState with
requestIfNeeded: false (or the equivalent option your helper accepts) so it only
reads the current state without prompting, then pass that result to
setPermissionState; locate this change around ensureNotificationPermission,
getNotificationPermissionState, and setPermissionState in
OpenhumanLinkModal.tsx.
- Around line 213-217: Replace the direct runtime check coreIsTauri() in
OpenhumanLinkModal (the block that calls setStatus('error') / setError(...))
with the shared helper isTauri() imported from
app/src/services/webviewAccountService.ts; update the import to pull isTauri(),
use isTauri() in place of coreIsTauri(), and ensure the surrounding code (any
invoke calls) remains wrapped in try/catch if applicable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d84a6906-8051-43d8-8b28-6948bae833ed
📒 Files selected for processing (3)
app/src/components/OpenhumanLinkModal.tsxapp/src/components/__tests__/OpenhumanLinkModal.notifications.test.tsxapp/src/lib/nativeNotifications/tauriBridge.ts
…permission handling
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/components/OpenhumanLinkModal.tsx`:
- Around line 220-244: When ensureNotificationPermission() resolves true you
must update the UI permission state immediately instead of only after a
successful send; call setPermissionState('granted') as soon as granted is true
(before calling showNativeNotification) so the UI distinguishes “permission
granted but send failed” from “permission denied.” In the block using
ensureNotificationPermission(), move or add setPermissionState('granted') right
after the granted check (and do the same for the similar block around
showNativeNotification at 257-272), leaving the existing error handling
(setStatus/setError) for send failures intact so send failures do not revert
permission state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5153a181-a3d8-4d87-9613-651314ea4c01
📒 Files selected for processing (2)
app/src/components/OpenhumanLinkModal.tsxapp/src/services/webviewAccountService.ts
✅ Files skipped from review due to trivial changes (1)
- app/src/services/webviewAccountService.ts
| const granted = await ensureNotificationPermission(); | ||
| if (!granted) { | ||
| const nextState = await getNotificationPermissionState({ requestIfNeeded: false }); | ||
| setPermissionState(nextState); | ||
| setStatus('error'); | ||
| setError( | ||
| 'Notification permission is off. Enable OpenHuman in System Settings → Notifications, then retry.' | ||
| ); | ||
| return; | ||
| } | ||
| await showNativeNotification({ | ||
| const sendResult = await showNativeNotification({ | ||
| title: 'OpenHuman is good to go', | ||
| body: 'You will get pings here when something needs your attention.', | ||
| tag: 'welcome-notification-test', | ||
| }); | ||
| if (cancelledRef.current) { | ||
| if (!sendResult.delivered) { | ||
| setStatus('error'); | ||
| setError( | ||
| sendResult.error ?? | ||
| 'OpenHuman could not trigger a system notification. Check OS notification settings and retry.' | ||
| ); | ||
| return; | ||
| } | ||
| setPermissionState('granted'); | ||
| setStatus('sent'); |
There was a problem hiding this comment.
Keep permissionState in sync even when delivery fails.
ensureNotificationPermission() returning true means OS permission is already granted, but permissionState is only set to 'granted' after a successful send. If send fails, the UI can still show the prompt guidance block, which is misleading and blurs permission-denied vs send-failed states.
Proposed fix
const granted = await ensureNotificationPermission();
if (!granted) {
const nextState = await getNotificationPermissionState({ requestIfNeeded: false });
setPermissionState(nextState);
setStatus('error');
setError(
- 'Notification permission is off. Enable OpenHuman in System Settings → Notifications, then retry.'
+ nextState === 'denied'
+ ? 'Notification permission is off. Enable OpenHuman in System Settings → Notifications, then retry.'
+ : 'Notification permission was not granted. Tap Send test notification and allow permission in the OS prompt.'
);
return;
}
+ setPermissionState('granted');
const sendResult = await showNativeNotification({
title: 'OpenHuman is good to go',
body: 'You will get pings here when something needs your attention.',
tag: 'welcome-notification-test',
});
if (!sendResult.delivered) {
setStatus('error');
setError(
sendResult.error ??
'OpenHuman could not trigger a system notification. Check OS notification settings and retry.'
);
return;
}
- setPermissionState('granted');
setStatus('sent');Also applies to: 257-272
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/components/OpenhumanLinkModal.tsx` around lines 220 - 244, When
ensureNotificationPermission() resolves true you must update the UI permission
state immediately instead of only after a successful send; call
setPermissionState('granted') as soon as granted is true (before calling
showNativeNotification) so the UI distinguishes “permission granted but send
failed” from “permission denied.” In the block using
ensureNotificationPermission(), move or add setPermissionState('granted') right
after the granted check (and do the same for the similar block around
showNativeNotification at 257-272), leaving the existing error handling
(setStatus/setError) for send failures intact so send failures do not revert
permission state.
Summary
Added explicit native notification delivery result handling in Tauri bridge:
deliveredreasonerrorSeparated permission logic:
Updated onboarding modal flow:
Added Vitest coverage:
Updated test expectations to match final success messaging
Problem
Modal opening triggered
request_permissionprematurely:UI states not aligned with real outcomes:
Tests were outdated:
Solution
Refactor permission handling:
getNotificationPermissionState({ requestIfNeeded: false })Keep permission request explicit:
ensureNotificationPermission()triggered on user clickImprove send flow:
showNativeNotification()returns structured resultImprove UX messaging:
Expand test coverage:
Submission Checklist
Unit tests
cargo test(core) for updated logicE2E / Integration
app/test/e2etests/json_rpc_e2e.rsN/A
Doc comments
//////!Inline comments
Impact
Runtime / Platform
Compatibility
Security / Privacy
Performance
Related
Summary by CodeRabbit