# 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 app’s 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 plugin’s `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 plugin’s Android integration expects **NotifyReceiver** for alarm-based delivery, add a `<receiver>` for `com.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 app’s `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 day’s 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.
