# 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 }}
```
---
## 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