Skip to content

fix(ios): warn that deleting the app unpairs bands and sensors (refs #538) - #576

Merged
abdulsaheel merged 2 commits into
mainfrom
fix/ask-unpair-warning-538
Oct 9, 2026
Merged

abdulsaheel merged 2 commits into
mainfrom
fix/ask-unpair-warning-538

Conversation

@abdulsaheel

@abdulsaheel abdulsaheel commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

User description

Refs #538. On iOS, AccessorySetupKit pairings are removed by the system when the app is deleted, so other apps (including the maker's own) lose the band or sensor too. The app cannot intercept that, so this adds a clear warning where it matters.

  • New string iosUninstallUnpairsWarning in all 7 locales.
  • Shown on iOS only, appended to: the sensor pairing explainer, the forget-sensor and forget-band dialogs, and the "Delete everything" reset dialog.
  • Widget tests: present on iOS, absent on Android.

Moving rings off AccessorySetupKit (to avoid the unpair entirely) is a separate owner decision.

🤖 Generated with Claude Code

Summary by Sourcery

Warn iOS users before pairing, removing devices, or resetting data that deleting the app also unpairs its bands and sensors.

New Features:

  • Add a localized iOS-only warning that uninstalling the app unpairs bands and sensors for all apps on the device.
  • Display the warning in sensor pairing guidance, device removal dialogs, and the full reset confirmation.

Documentation:

  • Provide translations for the warning across all supported locales.

Tests:

  • Verify that the warning appears on iOS and remains absent on Android.

PR Type

Enhancement


Description

  • Adds a localized warning on iOS explaining that uninstalling the app unpairs paired bands and sensors from the system, affecting other apps.

  • Appends the warning to the sensor pairing screen, forget device dialogs, and the full reset dialog.

  • Includes widget tests to verify the warning is displayed exclusively on iOS.


Diagram Walkthrough

flowchart LR
  UI["Dialogs & Pairing Screen"] -- "Text rendering" --> Check{"Is iOS?"}
  Check -- "Yes" --> Append["Append Uninstall Warning"]
  Check -- "No" --> Original["Show Original Text"]
Loading

File Walkthrough

Relevant files
Enhancement
4 files
display_text.dart
Add helper to append iOS uninstall warning                             
+9/-0     
devices.dart
Add iOS warning to forget device dialogs                                 
+4/-4     
pair_sensor.dart
Add iOS warning to sensor pairing explainer                           
+2/-2     
settings.dart
Add iOS warning to full reset dialog                                         
+2/-2     
Tests
1 files
pair_sensor_test.dart
Add tests for platform-specific warning visibility             
+17/-0   
Documentation
7 files
app_de.arb
Add German translation for iOS warning                                     
+1/-0     
app_en.arb
Add English string for iOS warning                                             
+4/-0     
app_es.arb
Add Spanish translation for iOS warning                                   
+1/-0     
app_fr.arb
Add French translation for iOS warning                                     
+1/-0     
app_hi.arb
Add Hindi translation for iOS warning                                       
+1/-0     
app_ru.arb
Add Russian translation for iOS warning                                   
+1/-0     
app_zh.arb
Add Chinese translation for iOS warning                                   
+1/-0     

Summary by CodeRabbit

  • New Features
    • Added an iOS warning to relevant device, sensor, and reset messages: uninstalling the app unpairs bands and sensors from the phone, affecting their availability in other apps.

… app (#538)

AccessorySetupKit pairings are removed by iOS, bond included and for all
apps, when OpenStrap is uninstalled. There is no hook to prevent it, so the
sensor pairing screen, both forget dialogs and the reset dialog now say so
on iOS only. New string translated for every shipped locale.
@sourcery-ai

sourcery-ai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

This PR adds a localized, iOS-only warning to pairing, unpairing, and reset flows, using a shared platform-aware text helper to explain that deleting the app removes AccessorySetupKit pairings for all apps. Widget coverage verifies the warning appears on iOS but not Android.

Sequence diagram for the iOS uninstall pairing warning

sequenceDiagram
    participant User
    participant Dialog as PairingOrResetUI
    participant Helper as withIosUninstallWarning
    participant Localizations

    User->>Dialog: Open pairing, forget, or reset flow
    Dialog->>Helper: withIosUninstallWarning(context, body)
    alt iOS
        Helper->>Localizations: Read iosUninstallUnpairsWarning
        Localizations-->>Helper: Localized warning
        Helper-->>Dialog: body plus uninstall warning
    else Android or other platform
        Helper-->>Dialog: body
    end
    Dialog-->>User: Display explanatory text
Loading

File-Level Changes

Change Details Files
Add a localized iOS-only warning explaining that deleting the app unpairs AccessorySetupKit bands and sensors for all apps.
  • Add the warning string to all seven supported locale files.
  • Create a platform-aware text helper that appends the localized warning only on iOS, with an English fallback.
  • Append the warning to sensor pairing, forget-device, and full-reset explanatory copy.
lib/l10n/app_de.arb
lib/l10n/app_en.arb
lib/l10n/app_es.arb
lib/l10n/app_fr.arb
lib/l10n/app_hi.arb
lib/l10n/app_ru.arb
lib/l10n/app_zh.arb
lib/l10n/display_text.dart
lib/ui2/profile/devices.dart
lib/ui2/profile/pair_sensor.dart
lib/ui2/profile/settings.dart
Verify platform-specific visibility of the warning in the sensor pairing UI.
  • Override the test platform for iOS and Android cases.
  • Assert the warning is present on iOS and absent on Android.
  • Reset the platform override after each test.
test/pair_sensor_test.dart

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: OpenStrap/edge/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0f905c7f-e726-4bb5-9212-61400d1a8735

📥 Commits

Reviewing files that changed from the base of the PR and between 5f2b203 and e7660ae.


⛔ Files ignored due to path filters (1)
  • test/pair_sensor_test.dart is excluded by !test/**

📒 Files selected for processing (11)
  • lib/l10n/app_de.arb
  • lib/l10n/app_en.arb
  • lib/l10n/app_es.arb
  • lib/l10n/app_fr.arb
  • lib/l10n/app_hi.arb
  • lib/l10n/app_ru.arb
  • lib/l10n/app_zh.arb
  • lib/l10n/display_text.dart
  • lib/ui2/profile/devices.dart
  • lib/ui2/profile/pair_sensor.dart
  • lib/ui2/profile/settings.dart

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.



📝 Walkthrough

Walkthrough

Adds a localized warning about iOS pairing loss when OpenStrap is uninstalled. The warning appears in sensor and band messages and in the reset confirmation on iOS.

Changes

iOS Pairing Warning

Layer / File(s) Summary
Warning text and platform helper
lib/l10n/app_*.arb, lib/l10n/display_text.dart
Adds the warning in seven locales. The helper appends it on iOS and uses an English fallback if the localization is unavailable.
Profile message integration
lib/ui2/profile/pair_sensor.dart, lib/ui2/profile/devices.dart, lib/ui2/profile/settings.dart
Passes the sensor explainer, forget-sensor and forget-band confirmations, and reset confirmation through the helper.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Suggested reviewers: tahir101981-creator, pipiche38


Merge Risk: ⚪ Minimal · up to e7660

The warning is added to the intended iOS pairing and reset prompts, and its localization accessor is generated by the normal Flutter workflow. No actionable merge-blocking issue remains.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: warning iOS users that deleting the app unpairs bands and sensors.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.


✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@abdulsaheel

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit e7660ae)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to e7660ae

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Reset global platform override on test failure

If the expect assertion fails, it throws an exception and aborts the test, leaving
debugDefaultTargetPlatformOverride permanently overridden for all subsequent tests
in the suite. Use addTearDown to ensure the global override is always reset
regardless of test failure.

test/pair_sensor_test.dart [215-222]

         debugDefaultTargetPlatformOverride = platform;
+        addTearDown(() => debugDefaultTargetPlatformOverride = null);
         await _pump(t,
             const PairSensorView(entryLabel: 'Bluetooth heart rate sensor'));
         expect(
           find.textContaining('deleting OpenStrap also unpairs'),
           platform == TargetPlatform.iOS ? findsOneWidget : findsNothing,
         );
-        debugDefaultTargetPlatformOverride = null;
Suggestion importance[1-10]: 8

__

Why: Using addTearDown ensures the global debugDefaultTargetPlatformOverride is reset even if the test fails, preventing cascading failures in other tests.

Medium
Use dialog context for inherited widget lookup

Using the outer BuildContext c inside the dialog's builder closure can cause a crash
if the underlying screen is unmounted while the dialog is open, as
withIosUninstallWarning performs an inherited widget lookup. Pass the dialog's own
builder context d instead.

lib/ui2/profile/settings.dart [455-466]

         content: Text(
-          withIosUninstallWarning(c, l?.settingsResetBody ??
+          withIosUninstallWarning(d, l?.settingsResetBody ??
               'This permanently deletes this app\'s data on this device:\n\n'
                   '· every measured day, sleep, workout and route\n'
                   '· every lab result, meal, medication dose, habit, breathing session '
                   'and logged set\n'
                   '· your journal, cycle log and rolling baselines\n'
                   '· your profile, every preference and any stored AI key\n'
                   '· the home-screen widget and every scheduled reminder\n\n'
                   'Exported copies and backups in previous or unavailable folders '
                   'may remain. Delete those separately.\n\n'
                   'The band is unpaired, and it cannot re-send history it has already '
                   'handed over. Export from Your data first if you want a copy.'),
         ),
Suggestion importance[1-10]: 7

__

Why: Using the outer BuildContext c inside a dialog builder can cause crashes if the widget is unmounted when the dialog rebuilds. Passing the dialog's context d to withIosUninstallWarning is safer and follows Flutter best practices.

Medium

Previous suggestions

Suggestions up to commit 54311be
CategorySuggestion                                                                                                                                    Impact
Possible issue
Reset platform override in finally block

If the expect assertion fails, it throws an exception and the
debugDefaultTargetPlatformOverride is never reset. This pollutes the global platform
state for all subsequent tests in the suite, causing cascading failures. Wrap the
test body in a try/finally block to ensure the override is always cleared.

test/pair_sensor_test.dart [215-222]

         debugDefaultTargetPlatformOverride = platform;
-        await _pump(t,
-            const PairSensorView(entryLabel: 'Bluetooth heart rate sensor'));
-        expect(
-          find.textContaining('deleting OpenStrap also unpairs'),
-          platform == TargetPlatform.iOS ? findsOneWidget : findsNothing,
-        );
-        debugDefaultTargetPlatformOverride = null;
+        try {
+          await _pump(t,
+              const PairSensorView(entryLabel: 'Bluetooth heart rate sensor'));
+          expect(
+            find.textContaining('deleting OpenStrap also unpairs'),
+            platform == TargetPlatform.iOS ? findsOneWidget : findsNothing,
+          );
+        } finally {
+          debugDefaultTargetPlatformOverride = null;
+        }
Suggestion importance[1-10]: 7

__

Why: If the expect assertion fails, the test will abort and debugDefaultTargetPlatformOverride will not be reset, which can cause cascading failures in subsequent tests. Wrapping it in a try/finally block ensures the global state is always restored.

Medium

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit e7660ae

@abdulsaheel
abdulsaheel merged commit c7af737 into main Oct 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant