Files
crowd-funder-for-time-pwa/doc/daily-notification-alignment-outline.md
Jose Olarte III 9902e5fac7 chore: align with daily-notification-plugin 2.0.0 (org.timesafari namespace)
- Update Android manifest, Java imports, and capacitor.plugins.json to use
  org.timesafari.dailynotification (receivers, intent action, plugin classpath)
- Update iOS Info.plist BGTaskSchedulerPermittedIdentifiers to org.timesafari.*
- Bump @timesafari/daily-notification-plugin 1.3.3 → 2.0.0 (package-lock, Podfile.lock)
- Update docs and test-notification-receiver.sh to reference new package/action names
- Lockfile: minor bumps for @expo/cli, @expo/fingerprint, @expo/router-server, babel-preset-expo
2026-03-12 17:20:45 +08:00

107 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Daily Notification Plugin: Alignment Outline
**Purpose:** Checklist of changes/additions needed in this app to align with the test app (`daily-notification-plugin/test-apps/daily-notification-test`) so that:
1. **Rollover recovery** (and rollover itself) works.
2. **Notifications show when the app is in the foreground** (not only background/closed).
3. **Plugin loads at app launch** so recovery runs after reboot without the user opening notification UI.
**Reference:** Test app at
`/Users/aardimus/Sites/trentlarson/daily-notification-plugin_test/daily-notification-plugin/test-apps/daily-notification-test`
---
## 1. iOS AppDelegate
**File:** `ios/App/App/AppDelegate.swift`
### 1.1 Add imports
- [ ] `import UserNotifications`
- [ ] Import the Daily Notification plugin framework (Swift module name: **TimesafariDailyNotificationPlugin** per this apps Podfile; test app uses **DailyNotificationPlugin**)
### 1.2 Conform to `UNUserNotificationCenterDelegate`
- [ ] Add `, UNUserNotificationCenterDelegate` to the class declaration:
`class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate`
### 1.3 Force-load plugin at launch
- [ ] In `application(_:didFinishLaunchingWithOptions:)`, **before** other setup, add logic to force-load the plugin class (e.g. `_ = DailyNotificationPlugin.self` or the class exposed by the TimesafariDailyNotificationPlugin pod) so that the plugins `load()` (and thus `performRecovery()`) runs at app launch, not only when JS first calls the plugin.
### 1.4 Set notification center delegate
- [ ] In `didFinishLaunchingWithOptions`, set:
`UNUserNotificationCenter.current().delegate = self`
- [ ] In `applicationDidBecomeActive`, **re-set** the same delegate (in case Capacitor or another component clears it).
### 1.5 Implement `userNotificationCenter(_:willPresent:withCompletionHandler:)`
- [ ] When a notification is delivered (including in foreground), read `notification_id` and `scheduled_time` from `notification.request.content.userInfo`.
- [ ] Post rollover event:
`NotificationCenter.default.post(name: NSNotification.Name("DailyNotificationDelivered"), object: nil, userInfo: ["notification_id": id, "scheduled_time": scheduledTime])`
- [ ] Call completion handler with presentation options so the notification is shown in foreground, e.g.
`completionHandler([.banner, .sound, .badge])` (use `.alert` on iOS 13 if needed).
### 1.6 Implement `userNotificationCenter(_:didReceive:withCompletionHandler:)`
- [ ] Handle notification tap/interaction; call `completionHandler()` when done.
---
## 2. Android Manifest
**File:** `android/app/src/main/AndroidManifest.xml`
### 2.1 Fix receiver placement
- [ ] Move the two `<receiver>` elements (**DailyNotificationReceiver** and **BootReceiver**) **inside** the `<application>` block (e.g. after `<activity>...</activity>` and before `<provider>...</provider>`).
- [ ] Remove the stray second `</application>` so there is a single `<application>...</application>` containing activity, receivers, and provider.
### 2.2 (Optional) Add NotifyReceiver
- [ ] If the plugins Android integration expects **NotifyReceiver** for alarm-based delivery, add a `<receiver>` for `org.timesafari.dailynotification.NotifyReceiver` inside `<application>` (see test app manifest for exact declaration).
### 2.3 (Optional) BootReceiver options
- [ ] Consider aligning with test app: add `android:directBootAware="true"`, `android:exported="true"`, and intent-filter actions `LOCKED_BOOT_COMPLETED`, `MY_PACKAGE_REPLACED`, `PACKAGE_REPLACED` if you need the same boot/update behavior.
---
## 3. Capacitor / JS startup (optional but recommended)
**File:** `src/main.capacitor.ts` (or the main entry used for native builds)
### 3.1 Load plugin at startup
- [ ] Add a top-level import or an early call that touches the Daily Notification plugin so the JS side loads it at app startup (e.g. `import "@timesafari/daily-notification-plugin"` or a small init that calls `getRebootRecoveryStatus()` or `configure()`).
This ensures the plugin is loaded as soon as the app runs; together with the iOS force-load in AppDelegate, recovery runs at launch.
---
## 4. Plugin configuration (optional)
- [ ] If you use the native fetcher or need plugin config (db path, storage, etc.), call `DailyNotification.configure()` and/or `configureNativeFetcher()` when appropriate (e.g. after login or when notification UI is first used), similar to the test apps `configureNativeFetcher()` in HomeView.
---
## 5. Summary table
| Area | Change / addition |
|-------------------------|------------------------------------------------------------------------------------|
| **iOS AppDelegate** | Conform to `UNUserNotificationCenterDelegate`; set delegate; force-load plugin; implement `willPresent` (post `DailyNotificationDelivered` + show in foreground) and `didReceive`. |
| **Android manifest** | Move DailyNotificationReceiver and BootReceiver inside `<application>`; remove duplicate `</application>`; optionally add NotifyReceiver and BootReceiver options. |
| **main.capacitor.ts** | Optionally import or call plugin at startup so it (and recovery) load at launch. |
| **Plugin config** | Optionally call `configure()` / `configureNativeFetcher()` where appropriate. |
---
## 6. Verification
After making the changes:
- [ ] **iOS:** Build and run; trigger a daily notification and confirm it appears when the app is in the foreground.
- [ ] **iOS:** Confirm rollover (next days schedule) still occurs after a notification fires (check logs for `DNP-ROLLOVER` / `DailyNotificationDelivered`).
- [ ] **iOS:** Restart the app (or reboot) and confirm recovery runs without opening the notification settings screen (e.g. logs show plugin load and recovery).
- [ ] **Android:** Build and run; confirm receivers are registered (no manifest errors) and that notifications and boot recovery behave as expected.