Repository navigation
feat(ios): every notification choice under Home, and the not-following notice - #158
Conversation
…g notice
Fredrik, 5 Nov 2026: the iPhone app should have every notification
choice the web app and the box have. Home › Notifications reads the box's
rules document (GET /api/notifications/rules) and writes it as the web
app does: every entry for a kind the phone knows goes out whole, flipped
only on enabled, and a kind it does not know stays as the box holds it.
The box's own switch sits on top; turning a kind on turns it on too. The
kinds stand in three groups (the car, the box and its devices, access),
in Swedish and English. Above them, the iPhone's own permission: asked
here if never asked, or the way to Settings if refused. A viewer reads
that the owner chooses; an older box says it has no such thing yet.
The push catalogue gains control.not_following, with the phone's words:
"En enhet följer inte FTW" / "{name} gör inte som FTW ber. Öppna FTW för
att se varför." The demo box serves the rules document.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
# Conflicts: # appleApp/FTWKit/Sources/FTWKit/State/AppModel.swift
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8b2d9ea3f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Read when the view opens and when the session comes back. | ||
| .task(id: home.site.session.phase == .streaming) { await rules.load() } | ||
| // Back from the iPhone's Settings, the answer may have changed. | ||
| .task(id: scenePhase) { allowed = await Notifications.allowed() } |
There was a problem hiding this comment.
Register for push after permission is enabled in Settings
If notification permission was denied before this launch, following “Open Settings” and granting permission only refreshes allowed when the user returns; it never registers with APNs. Notifications.start() skips registration for denied permission, and SiteModel.installPushSink() does not reinstall an existing sink when the connection resumes. Consequently, the warning disappears but this phone still receives no notifications until the app is relaunched. When the scene becomes active with permission granted, also register for remote notifications.
Useful? React with 👍 / 👎.
Problem
Fredrik, 5 Nov 2026: "vi bör ha alla val för notiser i ios app också". The web app and the box's settings let an owner choose which notifications the box sends. The iPhone app had no such choice, and it never turned the box's notifications on. So a push such as "Car plugged in" reached an iPhone only if someone had turned it on elsewhere.
Change
NotifySettingsView,NotifyRules):enabled. That keeps the thresholds the box seeded. A kind the phone does not know, and any template rule, stays as the box holds it.control.not_following, with the phone's words:Pairs
This is the third of three:
The catalogue is byte-identical in all three. The screen works on any box that serves
/api/notifications/rules. The new kind appears once the box runs srcfl/ftw#1972.Evidence
swift test: 354 + 646 green on this machine.NotifyRulesTests: what a write sends, that every choice has a group, a label and Swedish, and a demo home whose switches read and write the box's rules without touching thresholds or the template rule.PushTextTests: still holds the catalogue to the phone's words.Largest text size, light:
🤖 Generated with Claude Code