Skip to content

use native system dialog for disable cloud backups#1863

Merged
transphorm merged 2 commits intodevfrom
justin/self-2356
Mar 24, 2026
Merged

use native system dialog for disable cloud backups#1863
transphorm merged 2 commits intodevfrom
justin/self-2356

Conversation

@transphorm
Copy link
Copy Markdown
Member

@transphorm transphorm commented Mar 24, 2026

Summary

  • Replace custom useModal dialog with native Alert.alert for the "Disable cloud backups" destructive action in CloudBackupScreen
  • Uses style: 'destructive' on the action button and style: 'cancel' on dismiss, giving users the standard platform confirmation UX for irreversible operations

Changes

React Native app

  • app/src/screens/account/settings/CloudBackupScreen.tsx — replaced useModal-based custom modal with native Alert.alert for the disable backup confirmation

Linear Issues

  • Closes SELF-2356 — Use native system dialogs for destructive actions

Test Plan

  • yarn lint && yarn types passes
  • Cloud backup disable flow shows native OS dialog (not custom modal)
  • Cancel dismisses dialog and resets pending state
  • Confirm triggers biometrics → disables backup → updates settings

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Switched the cloud backup disable confirmation to use the device's native alert for a simpler, more consistent experience.
  • Bug Fixes
    • Improved disable flow: cancel reliably clears pending state; failures now surface an error alert and clear pending state to avoid stuck UI.

@transphorm transphorm changed the title commit use native system dialog for disable cloud backups Mar 24, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

Replaces the custom useModal-driven "Disable cloud backups" confirmation in CloudBackupScreen.tsx with a native Alert.alert prompt; moves disable-confirmation control flow into Alert button callbacks while preserving the async disable sequence and cleanup.

Changes

Cohort / File(s) Summary
Cloud Backup Disable Flow Refactor
app/src/screens/account/settings/CloudBackupScreen.tsx
Replaced useModal + useMemo modal config with a useCallback-created showDisableModal that calls Alert.alert. Moved disable flow from modal handlers to Alert button onPress callbacks: Cancel now only clears pending state; Disable runs the async sequence (track start → biometric auth → disableBackup()toggleCloudBackupEnabled() → track done), with catch logging + error Alert and finally clearing pending state. No public API changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #1425: Modifies cloud backup logic in the same file, adding a pre-check and modal to the iCloud backup enable flow, complementing this disable flow refactoring.

Suggested labels

codex

Poem

⚡️ A prompt appears where modals used to be,
Native Alert sings a simpler melody,
Async steps march on with tracking in hand,
Errors warned, state cleared—tidy and planned,
Cloud backups bow; the flow stays free.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: replacing a custom modal with native system dialog for disabling cloud backups.
Description check ✅ Passed The description covers all required template sections: clear summary of changes, test plan with verification steps, and references the closed Linear issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch justin/self-2356

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/src/screens/account/settings/CloudBackupScreen.tsx (1)

74-101: Consider whether native Alert.alert aligns with project conventions.

The coding guidelines specify using the custom modal system with useModal hook and callback registry. While Alert.alert works, it deviates from the established pattern used elsewhere in this file (e.g., showNoRegisteredAccountModal on lines 103-120). This inconsistency could make maintenance harder and loses the haptic feedback integration that the custom modal system provides.

Additionally, on Android, users can dismiss the alert by tapping outside without triggering either callback, which would leave iCloudPending stuck as true.

If the native alert is intentional for this specific flow, consider adding a note explaining why, or handle the Android dismissal case explicitly using cancelable: false in the options:

     Alert.alert(
       'Disable cloud backups',
       'Are you sure you want to disable cloud backups? You may lose your recovery phrase.',
       [
         {
           text: 'Cancel',
           style: 'cancel',
           onPress: () => setICloudPending(false),
         },
         {
           text: 'Disable',
           style: 'destructive',
           onPress: async () => { /* ... */ },
         },
       ],
+      { cancelable: false },
     );

Based on learnings: "Screens must be organized by feature modules (passport, home, settings, etc.) with custom modal system using useModal hook and callback registry."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/screens/account/settings/CloudBackupScreen.tsx` around lines 74 -
101, The native Alert.alert in showDisableModal deviates from the app's modal
pattern and can leave iCloudPending true if dismissed on Android; replace this
Alert.alert usage with the project's custom modal via useModal/callback registry
(same approach as showNoRegisteredAccountModal) to present the disable
confirmation, wire the Cancel and Disable handlers to call
setICloudPending(false) and run loginWithBiometrics(), disableBackup(),
toggleCloudBackupEnabled(), and trackEvent(...) as before, and ensure the modal
is non-cancelable or that the modal’s onDismiss also clears
setICloudPending(false) and triggers any needed haptic feedback; if you must
keep Alert.alert, at minimum pass { cancelable: false } and document why native
Alert is used.
🤖 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/screens/account/settings/CloudBackupScreen.tsx`:
- Line 101: The dependency array on the hook ending with "},
[loginWithBiometrics, disableBackup, toggleCloudBackupEnabled, trackEvent]);"
must be formatted as a multi-line array to satisfy Prettier; update the
useEffect (or relevant hook) so the dependencies are each on their own line
(loginWithBiometrics, disableBackup, toggleCloudBackupEnabled, trackEvent) and
close the array and call on separate lines to match the project's Prettier
rules.
- Around line 84-97: The onPress handler for the "Disable" action currently uses
a try/finally and swallows errors from loginWithBiometrics(), disableBackup(),
and toggleCloudBackupEnabled(), so failures give no user feedback and may leave
state inconsistent; update the handler to wrap the async sequence in
try/catch/finally, call loginWithBiometrics(), then await disableBackup() and
only call toggleCloudBackupEnabled() if disableBackup() succeeds, and in the
catch block log/track the error (e.g., trackEvent with a failure event) and
surface an error to the user (alert/toast), while preserving the existing
setICloudPending(false) in finally; reference the onPress callback and the
functions loginWithBiometrics, disableBackup, toggleCloudBackupEnabled,
setICloudPending, and trackEvent when making changes.

---

Nitpick comments:
In `@app/src/screens/account/settings/CloudBackupScreen.tsx`:
- Around line 74-101: The native Alert.alert in showDisableModal deviates from
the app's modal pattern and can leave iCloudPending true if dismissed on
Android; replace this Alert.alert usage with the project's custom modal via
useModal/callback registry (same approach as showNoRegisteredAccountModal) to
present the disable confirmation, wire the Cancel and Disable handlers to call
setICloudPending(false) and run loginWithBiometrics(), disableBackup(),
toggleCloudBackupEnabled(), and trackEvent(...) as before, and ensure the modal
is non-cancelable or that the modal’s onDismiss also clears
setICloudPending(false) and triggers any needed haptic feedback; if you must
keep Alert.alert, at minimum pass { cancelable: false } and document why native
Alert is used.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3cc3818f-4f6d-4d52-acb6-3cea36a1ca27

📥 Commits

Reviewing files that changed from the base of the PR and between 8947671 and 925b3a9.

📒 Files selected for processing (1)
  • app/src/screens/account/settings/CloudBackupScreen.tsx

Comment thread app/src/screens/account/settings/CloudBackupScreen.tsx
Comment thread app/src/screens/account/settings/CloudBackupScreen.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/screens/account/settings/CloudBackupScreen.tsx`:
- Around line 74-113: The UI is toggling cloud backup state even when Android
Google-signin cancellation causes disableBackup() to return silently; update the
contract so CloudBackupScreen can reliably know outcome: change disableBackup
(in cloud-backup/index.ts) to return a boolean success flag (true = deleted,
false = user-cancelled) or alternatively throw on cancellation (matching
download()), and then update CloudBackupScreen's showDisableModal to check the
returned value (or rely on thrown error) before calling
toggleCloudBackupEnabled(); ensure callers of disableBackup are updated to
handle the new boolean/exception behavior (and keep loginWithBiometrics and
trackEvent usage intact).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d5c611ca-d474-4b00-98f8-eaf3d71c37f3

📥 Commits

Reviewing files that changed from the base of the PR and between 925b3a9 and 0809a1c.

📒 Files selected for processing (1)
  • app/src/screens/account/settings/CloudBackupScreen.tsx

Comment thread app/src/screens/account/settings/CloudBackupScreen.tsx
@transphorm transphorm merged commit e885351 into dev Mar 24, 2026
23 checks passed
@transphorm transphorm deleted the justin/self-2356 branch March 24, 2026 20:47
@transphorm transphorm mentioned this pull request Mar 25, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant