diff --git a/doc/daily-notification-accountview-integration-strategy.md b/doc/daily-notification-accountview-integration-strategy.md deleted file mode 100644 index 7d7fd374..00000000 --- a/doc/daily-notification-accountview-integration-strategy.md +++ /dev/null @@ -1,472 +0,0 @@ -# Daily Notification Plugin - AccountViewView Integration Strategy - -**Author**: Matthew Raymer -**Date**: 2025-11-03 -**Status**: 🎯 **PLANNING** - UI integration strategy -**Feature**: Daily Notification Scheduling in Account Settings - ---- - -## Overview - -This document outlines the strategy for integrating daily notification scheduling into `AccountViewView.vue`, allowing users to configure notification times directly from their account settings. - ---- - -## Current State Analysis - -### Account Settings Context - -**Location**: `AccountViewView.vue` - Settings view for user account configuration - -**Integration Approach**: Add new "Daily Notifications" section for scheduling native daily notifications using PlatformService. - ---- - -## Integration Strategy - -**Approach**: Create a separate "Daily Notifications" section - -This approach adds a dedicated "Daily Notifications" section that checks PlatformService capabilities. On Capacitor platforms, it provides full functionality. On other platforms, the UI is hidden when PlatformService returns `null` for notification methods. - -**Key Benefits**: -- Uses PlatformService interface pattern (consistent with camera, filesystem) -- Platform-specific features properly isolated -- Can use native time picker (better UX on mobile) -- Future-proof: Easy to extend with additional notification features -- Graceful degradation on unsupported platforms - -**Implementation**: -```vue - - - - Daily Notifications - - - - - - - Daily Notification - - - - - - - - - - Scheduled for: {{ nativeNotificationTime }} - - Edit Time - - - - -``` - ---- - -## Approach Rationale - -**Decision Date**: 2025-11-03 -**Status**: ✅ **ACCEPTED** - Will proceed with separate native notification section - -1. **Clear Platform Distinction**: Users understand this is for mobile apps -2. **No Conflicts**: Doesn't interfere with disabled web notifications -3. **Better UX**: Can use native time picker on mobile -4. **Future-Proof**: Easy to extend with additional native notification features - -### Implementation Status - -- [x] Approach decision finalized -- [ ] Implementation begins (Phase 1) - ---- - -## UI Component Design - -### 1. Platform Capability Detection - -```typescript -// In AccountViewView component -async checkNotificationSupport(): Promise { - const platformService = PlatformServiceFactory.getInstance(); - const status = await platformService.getDailyNotificationStatus(); - return status !== null; // null means not supported -} -``` - -### 2. State Management - -```typescript -// Component properties -nativeNotificationEnabled: boolean = false; -nativeNotificationTime: string = ""; // Display format: "9:00 AM" -nativeNotificationTimeStorage: string = ""; // Plugin format: "09:00" -nativeNotificationTitle: string = "Daily Update"; -nativeNotificationMessage: string = "Your daily notification is ready!"; -``` - -### 3. Time Input ✅ **SELECTED: HTML5 Time Input** - -**Decision**: Use HTML5 `` for native mobile experience - -```vue - -``` - -**Benefits**: -- Native mobile time picker UI on Capacitor platforms -- Simpler implementation (no custom time parsing needed) -- Automatic 24-hour format output (compatible with plugin) -- System handles locale-specific time formatting -- Better UX on mobile devices - -**Note**: HTML5 time input provides time in "HH:mm" format (24-hour) which matches the plugin's expected format perfectly. - -### 4. Time Format Conversion (Using System Time) - -**Key Principle**: Use device's local system time - no timezone conversions needed. The plugin handles system time natively. - -```typescript -// Convert "09:00" (plugin storage format) to "9:00 AM" (display) -function formatTimeForDisplay(time24: string): string { - const [hours, minutes] = time24.split(':'); - const hourNum = parseInt(hours); - const isPM = hourNum >= 12; - const displayHour = hourNum === 0 ? 12 : hourNum > 12 ? hourNum - 12 : hourNum; - return `${displayHour}:${minutes} ${isPM ? 'PM' : 'AM'}`; -} - -// HTML5 time input provides "HH:mm" in local time - use directly -// No UTC conversion needed - plugin handles local timezone -function getTimeFromInput(timeInput: string): string { - // timeInput is already in "HH:mm" format from - // This is in the user's local timezone - pass directly to plugin - return timeInput; // e.g., "09:00" in user's local time -} -``` - -**Time Handling**: - -- **PlatformService Integration**: Uses device's local system time directly - NO UTC conversion needed. The plugin schedules notifications on the device itself, using the device's timezone. - -**Implementation Principles**: -- HTML5 `` provides time in device's local timezone -- Plugin receives time in "HH:mm" format and schedules relative to device's local time -- No manual timezone conversion or UTC calculations needed -- System automatically handles: - - Timezone changes - - Daylight saving time transitions - - Device timezone updates -- User sets "9:00 AM" in their local time → plugin schedules for 9:00 AM local time every day - ---- - -## Data Flow - -### 1. Initialization - -```typescript -async initializeState() { - // ... existing initialization ... - - const platformService = PlatformServiceFactory.getInstance(); - - // Check if notifications are supported on this platform - const status = await platformService.getDailyNotificationStatus(); - if (status === null) { - // Notifications not supported - don't initialize - return; - } - - // Load from settings - const nativeNotificationTime = settings.nativeNotificationTime || ""; - this.nativeNotificationEnabled = !!nativeNotificationTime; - this.nativeNotificationTimeStorage = nativeNotificationTime; - - if (nativeNotificationTime) { - this.nativeNotificationTime = formatTimeForDisplay(nativeNotificationTime); - } - - // Update UI with current status - this.notificationStatus = status; -} -``` - -### 2. Enable Notification - -```typescript -async enableNativeNotification() { - try { - const platformService = PlatformServiceFactory.getInstance(); - - // 1. Request permissions if needed - const permissions = await platformService.checkNotificationPermissions(); - if (permissions === null || permissions.notifications !== 'granted') { - const result = await platformService.requestNotificationPermissions(); - if (result === null || !result.notifications) { - throw new Error("Notification permissions denied"); - } - } - - // 2. Schedule notification via PlatformService - // Time is in device's local system time (from HTML5 time input) - // PlatformService handles timezone and scheduling internally - await platformService.scheduleDailyNotification({ - time: this.nativeNotificationTimeStorage, // "09:00" in local time - title: this.nativeNotificationTitle, - body: this.nativeNotificationMessage, - sound: true, - priority: 'high' - }); - - // 3. Save to settings - await this.$saveSettings({ - nativeNotificationTime: this.nativeNotificationTimeStorage, - nativeNotificationTitle: this.nativeNotificationTitle, - nativeNotificationMessage: this.nativeNotificationMessage, - }); - - // 4. Update UI state - this.nativeNotificationEnabled = true; - - this.notify.success("Daily notification scheduled successfully", TIMEOUTS.SHORT); - } catch (error) { - logger.error("Failed to enable notification:", error); - this.notify.error("Failed to schedule notification. Please try again.", TIMEOUTS.LONG); - } -} - -### 3. Disable Notification - -```typescript -async disableNativeNotification() { - try { - const platformService = PlatformServiceFactory.getInstance(); - - // 1. Cancel notification via PlatformService - await platformService.cancelDailyNotification(); - - // 2. Clear settings - await this.$saveSettings({ - nativeNotificationTime: "", - nativeNotificationTitle: "", - nativeNotificationMessage: "", - }); - - // 3. Update UI state - this.nativeNotificationEnabled = false; - this.nativeNotificationTime = ""; - this.nativeNotificationTimeStorage = ""; - - this.notify.success("Daily notification disabled", TIMEOUTS.SHORT); - } catch (error) { - logger.error("Failed to disable native notification:", error); - this.notify.error("Failed to disable notification. Please try again.", TIMEOUTS.LONG); - } -} -``` - -### 4. Edit Time - -**Approach**: Use inline HTML5 time input for quick edits - -```typescript -async editNativeNotificationTime() { - // Show inline HTML5 time input for quick changes - // For complex editing (title, message), navigate to ScheduleView - this.showTimeEdit = true; -} -``` - -**Implementation Note**: HTML5 time input provides native mobile picker experience when shown inline, making it ideal for quick time adjustments in AccountViewView. - ---- - -## Settings Schema - -### New Settings Fields - -```typescript -// Add to Settings interface in src/db/tables/settings.ts -interface Settings { - // ... existing fields ... - - // Native notification settings (Capacitor only) - nativeNotificationTime?: string; // "09:00" format (24-hour) - nativeNotificationTitle?: string; // Default: "Daily Update" - nativeNotificationMessage?: string; // Default message -} -``` - -### Settings Persistence - -- Store in `settings` table via `$saveSettings()` -- Use same pattern as `notifyingNewActivityTime` -- Persist across app restarts -- Sync with plugin state on component mount - ---- - -## Plugin Integration - -### PlatformService Usage - -```typescript -import { PlatformServiceFactory } from '@/services/PlatformServiceFactory'; - -const platformService = PlatformServiceFactory.getInstance(); - -// Check if notifications are supported -const status = await platformService.getDailyNotificationStatus(); -if (status === null) { - // Notifications not supported on this platform -} -``` - -### Key Operations (via PlatformService) - -1. **Check Status**: `getDailyNotificationStatus()` - Returns status or `null` if unsupported -2. **Check Permissions**: `checkNotificationPermissions()` - Returns permissions or `null` if unsupported -3. **Request Permissions**: `requestNotificationPermissions()` - Requests permissions or returns `null` if unsupported -4. **Schedule**: `scheduleDailyNotification(options)` - Schedules notification or throws error if unsupported -5. **Cancel**: `cancelDailyNotification()` - Cancels notification or throws error if unsupported - ---- - -## UI/UX Considerations - -### Visual Design -- **Section Style**: Match existing notification section (`bg-slate-100 rounded-md`) -- **Toggle Switch**: Reuse existing custom toggle pattern -- **Time Display**: Show in user-friendly format ("9:00 AM") -- **Edit Button**: Small, subtle link/button to edit time - -### User Feedback -- **Success**: Toast notification when scheduled successfully -- **Error**: Clear error message with troubleshooting guidance -- **Loading**: Show loading state during plugin operations -- **Permission Request**: Handle gracefully if denied - -### Accessibility -- **ARIA Labels**: Proper labels for all interactive elements -- **Keyboard Navigation**: Full keyboard support -- **Screen Reader**: Clear announcements for state changes - ---- - -## Implementation Phases - -### Phase 1: Basic Integration -- [ ] Add platform detection property -- [ ] Create native notification section in template -- [ ] Add component state properties -- [ ] Implement toggle functionality -- [ ] Basic enable/disable operations - -### Phase 2: Time Management -- [ ] Add time input (HTML5 time picker) -- [ ] Implement time format conversion -- [ ] Add edit time functionality -- [ ] Save/load time from settings - -### Phase 3: Plugin Integration -- [ ] Integrate with DailyNotificationFactory -- [ ] Schedule notification on enable -- [ ] Cancel notification on disable -- [ ] Update notification on time change -- [ ] Sync plugin state with settings - -### Phase 4: Polish & Error Handling -- [ ] Permission request flow -- [ ] Error handling and user feedback -- [ ] Status verification -- [ ] Help/info dialogs -- [ ] Accessibility improvements - ---- - -## Implementation Decisions - -### Time Input Format ✅ -- **Selected**: HTML5 `` for Capacitor platforms -- **Rationale**: Native mobile experience, simpler code, automatic 24-hour format - -### Edit Approach ✅ -- **Selected**: Inline HTML5 time input for quick edits in AccountViewView -- **Note**: For complex editing (title, message changes), users can navigate to dedicated ScheduleView - -### Settings Field Names ✅ -- **Selected**: `nativeNotificationTime`, `nativeNotificationTitle`, `nativeNotificationMessage` -- **Rationale**: Clear distinction from web push notification fields - -### Notification Title/Message ✅ -- **Selected**: Allow customization, default to "Daily Update" / "Your daily notification is ready!" -- **Rationale**: Flexibility for users, sensible defaults - ---- - -## Success Criteria - -- [ ] Native notification section appears only on Capacitor platforms -- [ ] Toggle enables/disables notifications via plugin -- [ ] Time can be set and edited -- [ ] Settings persist across app restarts -- [ ] Plugin state syncs with settings -- [ ] Error handling provides clear user feedback -- [ ] UI matches existing design patterns -- [ ] Accessibility requirements met - ---- - -## Related Components - -- **PlatformService**: Interface for platform capabilities (notification methods) -- **PlatformServiceFactory**: Factory for getting platform service instance -- **ScheduleView**: Dedicated scheduling interface (for complex editing) -- **AccountViewView**: Main settings view (integration target) - ---- - -## Next Steps - -1. ~~**Decide on Approach**: Separate native notification section~~ ✅ **DECIDED** -2. **Define Settings Schema**: Add native notification fields to Settings interface -3. **Create UI Components**: Build notification section in AccountViewView -4. **Integrate Plugin**: Connect UI to DailyNotificationFactory service -5. **Test Flow**: Verify enable/disable/edit workflows -6. **Add Help Content**: Create help documentation for native notifications - ---- - -**See also**: -- `doc/daily-notification-plugin-integration-plan.md` - Overall integration plan -- `src/views/AccountViewView.vue` - Target component for integration -- `src/services/PlatformService.ts` - PlatformService interface definition -- `src/services/PlatformServiceFactory.ts` - Factory for platform service instances - diff --git a/doc/daily-notification-plugin-integration-plan.md b/doc/daily-notification-plugin-integration-plan.md index ba07104a..992e4485 100644 --- a/doc/daily-notification-plugin-integration-plan.md +++ b/doc/daily-notification-plugin-integration-plan.md @@ -16,7 +16,7 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in - **Platform**: All platforms (Capacitor provides full functionality, Web/Electron return null) - **Architecture**: PlatformService interface integration (all platforms implement, unsupported return null) -- **Components**: Home view (diagnostics/status) + Schedule view (time setting) +- **Components**: Home view (diagnostics/status), Schedule view (time setting), AccountViewView integration (settings UI) - **Store**: Pinia store for notification state management - **Routes**: New routes for schedule, notifications, history, settings views @@ -30,6 +30,7 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in - **Medium**: New Vue components, Pinia store, router routes - **Pattern**: Following PlatformService interface pattern (like camera, filesystem methods) - all platforms implement, unsupported return null - **Integration**: Plugin API integration with error handling +- **UI Integration**: AccountViewView modification with new notification section #### Platform Impact - **Single Platform**: Capacitor-only (Android/iOS) @@ -43,6 +44,7 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in - Notification scheduling - Status checking - Cross-platform validation (ensure web/electron unaffected) + - AccountViewView UI integration ### Dependency Complexity @@ -52,10 +54,13 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in - Store creation (Pinia) - Component dependencies (ActionCard, StatusCard) - Logger integration (replace console.* with project logger) + - AccountViewView modifications + - Settings schema updates #### External Dependencies - **Medium**: - `@timesafari/daily-notification-plugin` (external package) + - `@capacitor/core` (already in project) - Capacitor core APIs - Platform detection utilities @@ -79,6 +84,9 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in 4. **Store State Management**: Notification state persistence - **Mitigation**: Follow existing Pinia patterns in codebase +5. **AccountViewView Integration**: UI changes must not affect existing functionality + - **Mitigation**: Use platform capability detection, hide UI on unsupported platforms + --- ## Platform Analysis @@ -250,7 +258,8 @@ src/views/ ├── ScheduleView.vue (new - notification scheduling) ├── NotificationsView.vue (new - view scheduled notifications) ├── NotificationHistoryView.vue (new - notification history) - └── NotificationSettingsView.vue (new - notification settings) + ├── NotificationSettingsView.vue (new - notification settings) + └── AccountViewView.vue (existing - add Daily Notifications section) ``` #### Supporting Components @@ -297,6 +306,341 @@ src/stores/ --- +## AccountViewView Integration Strategy + +### Overview + +Integrate daily notification scheduling into `AccountViewView.vue`, allowing users to configure notification times directly from their account settings. + +### Integration Approach ✅ **ACCEPTED** + +**Decision**: Create a separate "Daily Notifications" section + +This approach adds a dedicated "Daily Notifications" section that checks PlatformService capabilities. On Capacitor platforms, it provides full functionality. On other platforms, the UI is hidden when PlatformService returns `null` for notification methods. + +**Key Benefits**: +- Uses PlatformService interface pattern (consistent with camera, filesystem) +- Platform-specific features properly isolated +- Can use native time picker (better UX on mobile) +- Future-proof: Easy to extend with additional notification features +- Graceful degradation on unsupported platforms + +### UI Component Design + +#### 1. Platform Capability Detection + +```typescript +// In AccountViewView component +async checkNotificationSupport(): Promise { + const platformService = PlatformServiceFactory.getInstance(); + const status = await platformService.getDailyNotificationStatus(); + return status !== null; // null means not supported +} +``` + +#### 2. State Management + +```typescript +// Component properties +nativeNotificationEnabled: boolean = false; +nativeNotificationTime: string = ""; // Display format: "9:00 AM" +nativeNotificationTimeStorage: string = ""; // Plugin format: "09:00" +nativeNotificationTitle: string = "Daily Update"; +nativeNotificationMessage: string = "Your daily notification is ready!"; +notificationsSupported: boolean = false; // Computed from PlatformService +``` + +#### 3. Template Section + +```vue + + + + Daily Notifications + + + + + + + Daily Notification + + + + + + + + + + Scheduled for: {{ nativeNotificationTime }} + + Edit Time + + + + +``` + +#### 4. Time Input ✅ **SELECTED: HTML5 Time Input** + +**Decision**: Use HTML5 `` for native mobile experience + +```vue + +``` + +**Benefits**: +- Native mobile time picker UI on Capacitor platforms +- Simpler implementation (no custom time parsing needed) +- Automatic 24-hour format output (compatible with plugin) +- System handles locale-specific time formatting +- Better UX on mobile devices + +**Note**: HTML5 time input provides time in "HH:mm" format (24-hour) which matches the plugin's expected format perfectly. + +#### 5. Time Format Conversion (Using System Time) + +**Key Principle**: Use device's local system time - no timezone conversions needed. The plugin handles system time natively. + +```typescript +// Convert "09:00" (plugin storage format) to "9:00 AM" (display) +function formatTimeForDisplay(time24: string): string { + const [hours, minutes] = time24.split(':'); + const hourNum = parseInt(hours); + const isPM = hourNum >= 12; + const displayHour = hourNum === 0 ? 12 : hourNum > 12 ? hourNum - 12 : hourNum; + return `${displayHour}:${minutes} ${isPM ? 'PM' : 'AM'}`; +} + +// HTML5 time input provides "HH:mm" in local time - use directly +// No UTC conversion needed - plugin handles local timezone +function getTimeFromInput(timeInput: string): string { + // timeInput is already in "HH:mm" format from + // This is in the user's local timezone - pass directly to plugin + return timeInput; // e.g., "09:00" in user's local time +} +``` + +**Time Handling**: +- **PlatformService Integration**: Uses device's local system time directly - NO UTC conversion needed. The plugin schedules notifications on the device itself, using the device's timezone. + +**Implementation Principles**: +- HTML5 `` provides time in device's local timezone +- Plugin receives time in "HH:mm" format and schedules relative to device's local time +- No manual timezone conversion or UTC calculations needed +- System automatically handles: + - Timezone changes + - Daylight saving time transitions + - Device timezone updates +- User sets "9:00 AM" in their local time → plugin schedules for 9:00 AM local time every day + +### Data Flow + +#### 1. Initialization + +```typescript +async initializeState() { + // ... existing initialization ... + + const platformService = PlatformServiceFactory.getInstance(); + + // Check if notifications are supported on this platform + const status = await platformService.getDailyNotificationStatus(); + if (status === null) { + // Notifications not supported - don't initialize + this.notificationsSupported = false; + return; + } + + this.notificationsSupported = true; + + // Load from settings + const nativeNotificationTime = settings.nativeNotificationTime || ""; + this.nativeNotificationEnabled = !!nativeNotificationTime; + this.nativeNotificationTimeStorage = nativeNotificationTime; + + if (nativeNotificationTime) { + this.nativeNotificationTime = formatTimeForDisplay(nativeNotificationTime); + } + + // Update UI with current status + this.notificationStatus = status; +} +``` + +#### 2. Enable Notification + +```typescript +async enableNativeNotification() { + try { + const platformService = PlatformServiceFactory.getInstance(); + + // 1. Request permissions if needed + const permissions = await platformService.checkNotificationPermissions(); + if (permissions === null || permissions.notifications !== 'granted') { + const result = await platformService.requestNotificationPermissions(); + if (result === null || !result.notifications) { + throw new Error("Notification permissions denied"); + } + } + + // 2. Schedule notification via PlatformService + // Time is in device's local system time (from HTML5 time input) + // PlatformService handles timezone and scheduling internally + await platformService.scheduleDailyNotification({ + time: this.nativeNotificationTimeStorage, // "09:00" in local time + title: this.nativeNotificationTitle, + body: this.nativeNotificationMessage, + sound: true, + priority: 'high' + }); + + // 3. Save to settings + await this.$saveSettings({ + nativeNotificationTime: this.nativeNotificationTimeStorage, + nativeNotificationTitle: this.nativeNotificationTitle, + nativeNotificationMessage: this.nativeNotificationMessage, + }); + + // 4. Update UI state + this.nativeNotificationEnabled = true; + + this.notify.success("Daily notification scheduled successfully", TIMEOUTS.SHORT); + } catch (error) { + logger.error("Failed to enable notification:", error); + this.notify.error("Failed to schedule notification. Please try again.", TIMEOUTS.LONG); + } +} +``` + +#### 3. Disable Notification + +```typescript +async disableNativeNotification() { + try { + const platformService = PlatformServiceFactory.getInstance(); + + // 1. Cancel notification via PlatformService + await platformService.cancelDailyNotification(); + + // 2. Clear settings + await this.$saveSettings({ + nativeNotificationTime: "", + nativeNotificationTitle: "", + nativeNotificationMessage: "", + }); + + // 3. Update UI state + this.nativeNotificationEnabled = false; + this.nativeNotificationTime = ""; + this.nativeNotificationTimeStorage = ""; + + this.notify.success("Daily notification disabled", TIMEOUTS.SHORT); + } catch (error) { + logger.error("Failed to disable native notification:", error); + this.notify.error("Failed to disable notification. Please try again.", TIMEOUTS.LONG); + } +} +``` + +#### 4. Edit Time + +**Approach**: Use inline HTML5 time input for quick edits + +```typescript +async editNativeNotificationTime() { + // Show inline HTML5 time input for quick changes + // For complex editing (title, message), navigate to ScheduleView + this.showTimeEdit = true; +} +``` + +**Implementation Note**: HTML5 time input provides native mobile picker experience when shown inline, making it ideal for quick time adjustments in AccountViewView. + +### Settings Schema + +#### New Settings Fields + +```typescript +// Add to Settings interface in src/db/tables/settings.ts +interface Settings { + // ... existing fields ... + + // Native notification settings (Capacitor only) + nativeNotificationTime?: string; // "09:00" format (24-hour) + nativeNotificationTitle?: string; // Default: "Daily Update" + nativeNotificationMessage?: string; // Default message +} +``` + +#### Settings Persistence + +- Store in `settings` table via `$saveSettings()` +- Use same pattern as `notifyingNewActivityTime` +- Persist across app restarts +- Sync with plugin state on component mount + +### UI/UX Considerations + +#### Visual Design +- **Section Style**: Match existing notification section (`bg-slate-100 rounded-md`) +- **Toggle Switch**: Reuse existing custom toggle pattern +- **Time Display**: Show in user-friendly format ("9:00 AM") +- **Edit Button**: Small, subtle link/button to edit time + +#### User Feedback +- **Success**: Toast notification when scheduled successfully +- **Error**: Clear error message with troubleshooting guidance +- **Loading**: Show loading state during plugin operations +- **Permission Request**: Handle gracefully if denied + +#### Accessibility +- **ARIA Labels**: Proper labels for all interactive elements +- **Keyboard Navigation**: Full keyboard support +- **Screen Reader**: Clear announcements for state changes + +### Implementation Decisions ✅ + +#### Time Input Format ✅ +- **Selected**: HTML5 `` for Capacitor platforms +- **Rationale**: Native mobile experience, simpler code, automatic 24-hour format + +#### Edit Approach ✅ +- **Selected**: Inline HTML5 time input for quick edits in AccountViewView +- **Note**: For complex editing (title, message changes), users can navigate to dedicated ScheduleView + +#### Settings Field Names ✅ +- **Selected**: `nativeNotificationTime`, `nativeNotificationTitle`, `nativeNotificationMessage` +- **Rationale**: Clear distinction from web push notification fields + +#### Notification Title/Message ✅ +- **Selected**: Allow customization, default to "Daily Update" / "Your daily notification is ready!" +- **Rationale**: Flexibility for users, sensible defaults + +--- + ## Phase Breakdown ### Phase 1: Foundation & Infrastructure @@ -344,10 +688,10 @@ src/stores/ --- -### Phase 2: Core Components +### Phase 2: Core Components & AccountViewView Integration **Complexity**: Medium -**Goals**: Create reusable components and main views +**Goals**: Create reusable components, main views, and AccountViewView integration #### Tasks 1. **Reusable Components** @@ -370,24 +714,33 @@ src/stores/ - Replace `console.*` with project logger - Add loading states -4. **AccountViewView Integration** ✅ **ACCEPTED: Option A** +4. **AccountViewView Integration** ✅ **ACCEPTED** - Add separate "Daily Notifications" section - - Check platform capabilities before showing UI + - Check platform capabilities before showing UI (`v-if="notificationsSupported"`) + - Add computed property for platform capability detection - 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 permission request flow + - Add error handling and user feedback #### Acceptance Criteria - [ ] ActionCard and StatusCard components created - [ ] Home view shows notification diagnostics - [ ] Schedule view allows notification scheduling -- [ ] AccountViewView has separate "Daily Notifications" section (Option A accepted) +- [ ] AccountViewView has separate "Daily Notifications" section - [ ] Notification section checks PlatformService capabilities before showing - [ ] Toggle and time input functional in AccountViewView +- [ ] Settings persist across app restarts +- [ ] Plugin state syncs with settings - [ ] All logging uses project logger - [ ] Error handling implemented - [ ] Loading states visible +- [ ] UI matches existing design patterns --- @@ -436,11 +789,13 @@ src/stores/ - Test permission requests - Test status updates - Test native fetcher configuration + - Test AccountViewView integration on Capacitor 2. **Cross-Platform Validation** - Verify web build doesn't break - Verify Electron build doesn't break - Verify feature is hidden on non-Capacitor platforms + - Verify AccountViewView section hidden on web/electron - Test graceful degradation 3. **Integration Testing** @@ -448,6 +803,7 @@ src/stores/ - Test status checking workflow - Test navigation between views - Test store state persistence + - Test AccountViewView enable/disable/edit workflows 4. **Error Scenarios** - Test plugin unavailable scenarios @@ -458,6 +814,7 @@ src/stores/ #### Acceptance Criteria - [ ] All Capacitor tests passing - [ ] Web/Electron builds unaffected +- [ ] AccountViewView integration verified on all platforms - [ ] Integration tests passing - [ ] Error scenarios handled gracefully - [ ] Documentation updated @@ -468,7 +825,7 @@ src/stores/ ### Milestone 1: Foundation Complete **Success Criteria**: -- Factory service operational +- PlatformService interface extended - Store created and tested - Routes accessible - No build regressions @@ -477,6 +834,7 @@ src/stores/ **Success Criteria**: - Home view shows diagnostics - Schedule view functional +- AccountViewView integration complete - Plugin integration working - Logging standardized @@ -502,24 +860,27 @@ src/stores/ - Factory service platform detection - Store actions and state management - Component rendering and interactions +- AccountViewView notification section rendering ### Integration Tests - Plugin API calls - Permission flows - Status updates - Navigation between views +- AccountViewView enable/disable/edit workflows ### Platform Tests -- **Capacitor Android**: Notification scheduling, permissions, status -- **Capacitor iOS**: Notification scheduling, permissions, status -- **Web**: Feature hidden, no errors -- **Electron**: Feature hidden, no errors +- **Capacitor Android**: Notification scheduling, permissions, status, AccountViewView UI +- **Capacitor iOS**: Notification scheduling, permissions, status, AccountViewView UI +- **Web**: Feature hidden, no errors, AccountViewView section hidden +- **Electron**: Feature hidden, no errors, AccountViewView section hidden ### E2E Tests (Playwright) - Full notification scheduling workflow - Permission request flow - Status checking workflow - Error handling scenarios +- AccountViewView notification configuration workflow --- @@ -537,6 +898,8 @@ src/stores/ - Platform detection utilities - Router configuration - Existing component patterns +- AccountViewView component +- Settings schema and persistence ### Configuration Dependencies - **Active DID Management**: Use `$getActiveIdentity()` from `PlatformServiceMixin` (existing) @@ -561,6 +924,7 @@ src/stores/ - **Service Interface**: Abstract interface with platform implementations - **Store Pattern**: Pinia store for state management - **Composition API vs Class**: Use provided code style (Composition API for HomeView, Class for ScheduleView) +- **PlatformService Pattern**: Check capabilities via method results, not environment variables ### PlatformService Integration Strategy @@ -615,6 +979,7 @@ await platformService.scheduleDailyNotification({ - Use dynamic imports exclusively - Test web/electron builds after each phase - Ensure no static plugin imports +- Verify AccountViewView section properly hidden ### Risk 4: Configuration Dependencies (RESOLVED) **Mitigation**: @@ -623,14 +988,22 @@ await platformService.scheduleDailyNotification({ - **Use existing settings**: Get `apiServer` and `starredPlanHandleIds` from `$accountSettings()` - **No config files needed**: The HomeView component code references `TEST_USER_ZERO_CONFIG`, but should instead use the currently active DID and settings +### Risk 5: AccountViewView Integration Issues +**Mitigation**: +- Use platform capability detection before showing UI +- Test on all platforms to ensure proper hiding +- Follow existing UI patterns for consistency +- Add comprehensive error handling + --- ## Success Criteria Summary -- [ ] Plugin integrated using factory architecture +- [ ] Plugin integrated using PlatformService architecture - [ ] Feature works on Capacitor (Android/iOS) - [ ] Feature hidden/graceful on Web/Electron - [ ] All components created and functional +- [ ] AccountViewView integration complete and functional - [ ] Store manages notification state - [ ] Router routes accessible - [ ] Logging standardized (no console.*) @@ -648,6 +1021,7 @@ await platformService.scheduleDailyNotification({ 3. **Extend PlatformService**: Add notification methods to PlatformService interface and implement in all platform services 4. **Set Up Store**: Create Pinia store for notification state 5. **Begin Phase 1 Implementation**: Start with foundation tasks +6. **AccountViewView Integration**: Implement Daily Notifications section in Phase 2 --- @@ -656,3 +1030,4 @@ await platformService.scheduleDailyNotification({ - `.cursor/rules/app/architectural_patterns.mdc` - Architecture patterns - `.cursor/rules/app/timesafari_platforms.mdc` - Platform requirements - `src/services/QRScanner/QRScannerFactory.ts` - Factory pattern reference +- `src/views/AccountViewView.vue` - Target component for integration