diff --git a/doc/daily-notification-plugin-integration-plan.md b/doc/daily-notification-plugin-integration-plan.md
index 58606380..4637554f 100644
--- a/doc/daily-notification-plugin-integration-plan.md
+++ b/doc/daily-notification-plugin-integration-plan.md
@@ -255,18 +255,58 @@ export interface NativeFetcherConfig {
#### Views Structure
```
src/views/
- └── AccountViewView.vue (existing - add Daily Notifications section)
+ └── AccountViewView.vue (existing - add DailyNotificationSection component)
```
-#### Supporting Components (Optional - Only if AccountViewView needs extraction)
+#### Supporting Components
```
-src/components/notifications/ (optional)
- ├── NotificationToggle.vue (optional - extract toggle if AccountViewView too long)
- ├── NotificationTimePicker.vue (optional - extract time picker if needed)
- └── NotificationStatusDisplay.vue (optional - extract status display if needed)
+src/components/notifications/
+ └── DailyNotificationSection.vue (required - extracted section component)
```
-**Note**: Supporting components should only be created if AccountViewView exceeds reasonable length limits (>200 lines). Keep everything in AccountViewView if possible.
+**Component Structure**: `DailyNotificationSection.vue` will use vue-facing-decorator with ES6 classes
+
+```vue
+
+
+
+
+
+```
---
@@ -422,7 +462,7 @@ function getTimeFromInput(timeInput: string): string {
### Data Flow
-#### 1. Initialization
+#### 1. Initialization (Sync with Plugin State)
```typescript
async initializeState() {
@@ -440,13 +480,33 @@ async initializeState() {
this.notificationsSupported = true;
- // Load from settings
- const nativeNotificationTime = settings.nativeNotificationTime || "";
- this.nativeNotificationEnabled = !!nativeNotificationTime;
- this.nativeNotificationTimeStorage = nativeNotificationTime;
-
- if (nativeNotificationTime) {
- this.nativeNotificationTime = formatTimeForDisplay(nativeNotificationTime);
+ // CRITICAL: Sync with plugin state first (source of truth)
+ // Plugin may have an existing schedule even if settings don't
+ if (status.isScheduled && status.scheduledTime) {
+ // Plugin has a scheduled notification - sync UI to match
+ this.nativeNotificationEnabled = true;
+ this.nativeNotificationTimeStorage = status.scheduledTime;
+ this.nativeNotificationTime = formatTimeForDisplay(status.scheduledTime);
+
+ // Also sync settings to match plugin state
+ const settings = await this.$accountSettings();
+ if (settings.nativeNotificationTime !== status.scheduledTime) {
+ await this.$saveSettings({
+ nativeNotificationTime: status.scheduledTime,
+ nativeNotificationTitle: settings.nativeNotificationTitle || this.nativeNotificationTitle,
+ nativeNotificationMessage: settings.nativeNotificationMessage || this.nativeNotificationMessage,
+ });
+ }
+ } else {
+ // No plugin schedule - check settings for user preference
+ const settings = await this.$accountSettings();
+ const nativeNotificationTime = settings.nativeNotificationTime || "";
+ this.nativeNotificationEnabled = !!nativeNotificationTime;
+ this.nativeNotificationTimeStorage = nativeNotificationTime;
+
+ if (nativeNotificationTime) {
+ this.nativeNotificationTime = formatTimeForDisplay(nativeNotificationTime);
+ }
}
// Update UI with current status
@@ -454,6 +514,12 @@ async initializeState() {
}
```
+**Key Points**:
+- `getDailyNotificationStatus()` is called on mount to check for pre-existing schedules
+- Plugin state is the source of truth - if plugin has a schedule, UI syncs to match
+- Settings are synced with plugin state if they differ
+- If no plugin schedule exists, fall back to settings
+
#### 2. Enable Notification
```typescript
@@ -529,18 +595,63 @@ async disableNativeNotification() {
}
```
-#### 4. Edit Time
+#### 4. Edit Time (Update Schedule)
-**Approach**: Use inline HTML5 time input for quick edits
+**Approach**: When time changes, immediately update the scheduled notification
```typescript
async editNativeNotificationTime() {
// Show inline HTML5 time input for quick changes
this.showTimeEdit = true;
}
+
+async updateNotificationTime(newTime: string) {
+ // newTime is in "HH:mm" format from HTML5 time input
+ if (!this.nativeNotificationEnabled) {
+ // If notification is disabled, just save the time preference
+ this.nativeNotificationTimeStorage = newTime;
+ this.nativeNotificationTime = formatTimeForDisplay(newTime);
+ await this.$saveSettings({
+ nativeNotificationTime: newTime,
+ });
+ return;
+ }
+
+ // Notification is enabled - update the schedule
+ try {
+ const platformService = PlatformServiceFactory.getInstance();
+
+ // 1. Cancel existing notification
+ await platformService.cancelDailyNotification();
+
+ // 2. Schedule with new time
+ await platformService.scheduleDailyNotification({
+ time: newTime, // "09:00" in local time
+ title: this.nativeNotificationTitle,
+ body: this.nativeNotificationMessage,
+ sound: true,
+ priority: 'high'
+ });
+
+ // 3. Update local state
+ this.nativeNotificationTimeStorage = newTime;
+ this.nativeNotificationTime = formatTimeForDisplay(newTime);
+
+ // 4. Save to settings
+ await this.$saveSettings({
+ nativeNotificationTime: newTime,
+ });
+
+ this.notify.success("Notification time updated successfully", TIMEOUTS.SHORT);
+ this.showTimeEdit = false;
+ } catch (error) {
+ logger.error("Failed to update notification time:", error);
+ this.notify.error("Failed to update notification time. Please try again.", TIMEOUTS.LONG);
+ }
+}
```
-**Implementation Note**: HTML5 time input provides native mobile picker experience when shown inline, making it ideal for quick time adjustments in AccountViewView.
+**Implementation Note**: HTML5 time input provides native mobile picker experience when shown inline, making it ideal for quick time adjustments. When the time changes, the notification schedule is immediately updated via PlatformService.
### Settings Schema
@@ -643,39 +754,46 @@ interface Settings {
**Goals**: Integrate notification scheduling into AccountViewView with optional supporting components
#### Tasks
-1. **Supporting Components (Optional)**
- - [ ] Create supporting components only if AccountViewView exceeds length limits
- - [ ] Consider: `NotificationToggle.vue`, `NotificationTimePicker.vue`, `NotificationStatusDisplay.vue`
- - [ ] Follow project styling patterns
- - [ ] Add TypeScript interfaces
- - [ ] Keep components focused and reusable within AccountViewView context
-
-2. **AccountViewView Integration** ✅ **ACCEPTED**
- - [ ] Add separate "Daily Notifications" section
- - [ ] Check platform capabilities before showing UI (`v-if="notificationsSupported"`)
- - [ ] Add computed property for platform capability detection
+1. **DailyNotificationSection Component**
+ - [ ] Create `src/components/notifications/DailyNotificationSection.vue`
+ - [ ] Use vue-facing-decorator with ES6 class extending Vue
+ - [ ] Add PlatformServiceMixin to component
+ - [ ] Implement platform capability detection on mount
+ - [ ] Implement initialization that syncs with plugin state (checks for pre-existing schedules)
- [ ] Add toggle switch for enabling/disabling notifications
- [ ] Add HTML5 time input for scheduling time
- [ ] Integrate with PlatformService via PlatformServiceFactory
- - [ ] Save/load settings from `settings` table
- [ ] Implement time format conversion (display vs storage)
- [ ] Add enable/disable notification methods
- - [ ] Add edit time functionality
+ - [ ] Add edit time functionality with schedule update (cancel old, schedule new)
- [ ] Add permission request flow
- [ ] Add error handling and user feedback
+ - [ ] Save/load settings from `settings` table
+ - [ ] Follow project styling patterns
+ - [ ] Add TypeScript interfaces
+ - [ ] Add file-level documentation
+
+2. **AccountViewView Integration**
+ - [ ] Import DailyNotificationSection component
+ - [ ] Add component to template (minimal integration)
+ - [ ] Verify component renders correctly
+ - [ ] Test component hiding on unsupported platforms
#### Acceptance Criteria
-- [ ] Supporting components created only if AccountViewView exceeds length limits
-- [ ] AccountViewView has separate "Daily Notifications" section
-- [ ] **AccountViewView notification section hidden on unsupported platforms** (`v-if="notificationsSupported"`)
-- [ ] Notification section checks PlatformService capabilities before showing
-- [ ] Toggle and time input functional in AccountViewView
+- [ ] DailyNotificationSection component created using vue-facing-decorator
+- [ ] Component extends Vue class with PlatformServiceMixin
+- [ ] Component checks platform support on mount via `getDailyNotificationStatus()`
+- [ ] Component syncs with plugin state on initialization (checks for pre-existing schedules)
+- [ ] Component hidden on unsupported platforms (`v-if="notificationsSupported"`)
+- [ ] Toggle and time input functional
+- [ ] Time changes update notification schedule immediately (cancel old, schedule new)
- [ ] Settings persist across app restarts
-- [ ] Plugin state syncs with settings
+- [ ] Plugin state syncs with settings on mount
- [ ] All logging uses project logger
- [ ] Error handling implemented
- [ ] Loading states visible
- [ ] UI matches existing design patterns
+- [ ] AccountViewView integration is minimal (just imports and uses component)
---
@@ -837,16 +955,16 @@ async mounted() {
#### Components That Must Implement This Pattern
-1. **AccountViewView.vue**: Daily Notifications section uses `v-if="notificationsSupported"`
-2. **Supporting components** (if created): Must check support before rendering any scheduling UI
-3. **Any component providing scheduling UI**: Must verify `getDailyNotificationStatus() !== null` before showing scheduling controls
+1. **DailyNotificationSection.vue**: Daily Notifications section uses `v-if="notificationsSupported"` and checks `getDailyNotificationStatus()` on mount
+2. **Any component providing scheduling UI**: Must verify `getDailyNotificationStatus() !== null` before showing scheduling controls
#### Verification Checklist
-- [ ] AccountViewView notification section hidden via `v-if` on unsupported platforms
-- [ ] Supporting components (if created) check and hide on unsupported platforms
-- [ ] All components tested on Web/Electron to verify hiding works
+- [ ] DailyNotificationSection checks platform support on mount and hides on unsupported platforms
+- [ ] DailyNotificationSection syncs with plugin state on initialization (checks for pre-existing schedules)
+- [ ] Component tested on Web/Electron to verify hiding works
- [ ] No console errors when components are hidden
+- [ ] Time changes properly update notification schedule
### Code Quality Standards
- **Logging**: Use `logger` from `@/utils/logger`, not `console.*`
@@ -938,8 +1056,11 @@ await platformService.scheduleDailyNotification({
- [ ] Plugin integrated using PlatformService architecture
- [ ] Feature works on Capacitor (Android/iOS)
- [ ] Feature hidden/graceful on Web/Electron
-- [ ] AccountViewView integration complete and functional
-- [ ] **AccountViewView notification section hides itself on unsupported platforms**
+- [ ] DailyNotificationSection component created and functional
+- [ ] **DailyNotificationSection hides itself on unsupported platforms**
+- [ ] Component syncs with plugin state on mount (checks for pre-existing schedules)
+- [ ] Time changes update notification schedule immediately
+- [ ] AccountViewView integration minimal (just imports component)
- [ ] Settings persist across app restarts
- [ ] Logging standardized (no console.*)
- [ ] Error handling robust