forked from trent_larson/crowd-funder-for-time-pwa
docs: merge AccountViewView integration strategy into main plan
- Consolidate AccountViewView integration strategy into unified plan - Add comprehensive AccountViewView Integration Strategy section - Include UI component design, data flow, and implementation decisions - Remove separate strategy document to follow meta_feature_planning structure - Update Phase 2 to include AccountViewView integration tasks
This commit is contained in:
@@ -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
|
|
||||||
<!-- New Daily Notifications section -->
|
|
||||||
<section
|
|
||||||
v-if="notificationsSupported"
|
|
||||||
id="sectionDailyNotifications"
|
|
||||||
class="bg-slate-100 rounded-md overflow-hidden px-4 py-4 mt-8 mb-8"
|
|
||||||
aria-labelledby="dailyNotificationsHeading"
|
|
||||||
>
|
|
||||||
<h2 id="dailyNotificationsHeading" class="mb-2 font-bold">
|
|
||||||
Daily Notifications
|
|
||||||
<button
|
|
||||||
class="text-slate-400 fa-fw cursor-pointer"
|
|
||||||
aria-label="Learn more about native notifications"
|
|
||||||
@click.stop="showNativeNotificationInfo"
|
|
||||||
>
|
|
||||||
<font-awesome icon="question-circle" aria-hidden="true" />
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div>Daily Notification</div>
|
|
||||||
<!-- Toggle switch -->
|
|
||||||
<div
|
|
||||||
class="relative ml-2 cursor-pointer"
|
|
||||||
role="switch"
|
|
||||||
:aria-checked="nativeNotificationEnabled"
|
|
||||||
@click="toggleNativeNotification()"
|
|
||||||
>
|
|
||||||
<!-- Custom toggle UI -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Show current time when enabled -->
|
|
||||||
<div v-if="nativeNotificationEnabled" class="mt-2">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<span>Scheduled for: {{ nativeNotificationTime }}</span>
|
|
||||||
<button
|
|
||||||
class="text-blue-500 text-sm"
|
|
||||||
@click="editNativeNotificationTime()"
|
|
||||||
>
|
|
||||||
Edit Time
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 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<boolean> {
|
|
||||||
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 `<input type="time">` for native mobile experience
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<input
|
|
||||||
type="time"
|
|
||||||
v-model="nativeNotificationTimeStorage"
|
|
||||||
class="rounded border border-slate-400 px-2 py-2"
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
**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 <input type="time">
|
|
||||||
// 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 `<input type="time">` 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 `<input type="time">` 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
|
|
||||||
|
|
||||||
@@ -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)
|
- **Platform**: All platforms (Capacitor provides full functionality, Web/Electron return null)
|
||||||
- **Architecture**: PlatformService interface integration (all platforms implement, unsupported 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
|
- **Store**: Pinia store for notification state management
|
||||||
- **Routes**: New routes for schedule, notifications, history, settings views
|
- **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
|
- **Medium**: New Vue components, Pinia store, router routes
|
||||||
- **Pattern**: Following PlatformService interface pattern (like camera, filesystem methods) - all platforms implement, unsupported return null
|
- **Pattern**: Following PlatformService interface pattern (like camera, filesystem methods) - all platforms implement, unsupported return null
|
||||||
- **Integration**: Plugin API integration with error handling
|
- **Integration**: Plugin API integration with error handling
|
||||||
|
- **UI Integration**: AccountViewView modification with new notification section
|
||||||
|
|
||||||
#### Platform Impact
|
#### Platform Impact
|
||||||
- **Single Platform**: Capacitor-only (Android/iOS)
|
- **Single Platform**: Capacitor-only (Android/iOS)
|
||||||
@@ -43,6 +44,7 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in
|
|||||||
- Notification scheduling
|
- Notification scheduling
|
||||||
- Status checking
|
- Status checking
|
||||||
- Cross-platform validation (ensure web/electron unaffected)
|
- Cross-platform validation (ensure web/electron unaffected)
|
||||||
|
- AccountViewView UI integration
|
||||||
|
|
||||||
### Dependency Complexity
|
### Dependency Complexity
|
||||||
|
|
||||||
@@ -52,10 +54,13 @@ This plan outlines the integration of `@timesafari/daily-notification-plugin` in
|
|||||||
- Store creation (Pinia)
|
- Store creation (Pinia)
|
||||||
- Component dependencies (ActionCard, StatusCard)
|
- Component dependencies (ActionCard, StatusCard)
|
||||||
- Logger integration (replace console.* with project logger)
|
- Logger integration (replace console.* with project logger)
|
||||||
|
- AccountViewView modifications
|
||||||
|
- Settings schema updates
|
||||||
|
|
||||||
#### External Dependencies
|
#### External Dependencies
|
||||||
- **Medium**:
|
- **Medium**:
|
||||||
- `@timesafari/daily-notification-plugin` (external package)
|
- `@timesafari/daily-notification-plugin` (external package)
|
||||||
|
- `@capacitor/core` (already in project)
|
||||||
- Capacitor core APIs
|
- Capacitor core APIs
|
||||||
- Platform detection utilities
|
- 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
|
4. **Store State Management**: Notification state persistence
|
||||||
- **Mitigation**: Follow existing Pinia patterns in codebase
|
- **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
|
## Platform Analysis
|
||||||
@@ -250,7 +258,8 @@ src/views/
|
|||||||
├── ScheduleView.vue (new - notification scheduling)
|
├── ScheduleView.vue (new - notification scheduling)
|
||||||
├── NotificationsView.vue (new - view scheduled notifications)
|
├── NotificationsView.vue (new - view scheduled notifications)
|
||||||
├── NotificationHistoryView.vue (new - notification history)
|
├── NotificationHistoryView.vue (new - notification history)
|
||||||
└── NotificationSettingsView.vue (new - notification settings)
|
├── NotificationSettingsView.vue (new - notification settings)
|
||||||
|
└── AccountViewView.vue (existing - add Daily Notifications section)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Supporting Components
|
#### 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<boolean> {
|
||||||
|
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
|
||||||
|
<!-- New Daily Notifications section -->
|
||||||
|
<section
|
||||||
|
v-if="notificationsSupported"
|
||||||
|
id="sectionDailyNotifications"
|
||||||
|
class="bg-slate-100 rounded-md overflow-hidden px-4 py-4 mt-8 mb-8"
|
||||||
|
aria-labelledby="dailyNotificationsHeading"
|
||||||
|
>
|
||||||
|
<h2 id="dailyNotificationsHeading" class="mb-2 font-bold">
|
||||||
|
Daily Notifications
|
||||||
|
<button
|
||||||
|
class="text-slate-400 fa-fw cursor-pointer"
|
||||||
|
aria-label="Learn more about native notifications"
|
||||||
|
@click.stop="showNativeNotificationInfo"
|
||||||
|
>
|
||||||
|
<font-awesome icon="question-circle" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>Daily Notification</div>
|
||||||
|
<!-- Toggle switch -->
|
||||||
|
<div
|
||||||
|
class="relative ml-2 cursor-pointer"
|
||||||
|
role="switch"
|
||||||
|
:aria-checked="nativeNotificationEnabled"
|
||||||
|
@click="toggleNativeNotification()"
|
||||||
|
>
|
||||||
|
<!-- Custom toggle UI -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Show current time when enabled -->
|
||||||
|
<div v-if="nativeNotificationEnabled" class="mt-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span>Scheduled for: {{ nativeNotificationTime }}</span>
|
||||||
|
<button
|
||||||
|
class="text-blue-500 text-sm"
|
||||||
|
@click="editNativeNotificationTime()"
|
||||||
|
>
|
||||||
|
Edit Time
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Time Input ✅ **SELECTED: HTML5 Time Input**
|
||||||
|
|
||||||
|
**Decision**: Use HTML5 `<input type="time">` for native mobile experience
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<input
|
||||||
|
type="time"
|
||||||
|
v-model="nativeNotificationTimeStorage"
|
||||||
|
class="rounded border border-slate-400 px-2 py-2"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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 <input type="time">
|
||||||
|
// 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 `<input type="time">` 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 `<input type="time">` 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 Breakdown
|
||||||
|
|
||||||
### Phase 1: Foundation & Infrastructure
|
### Phase 1: Foundation & Infrastructure
|
||||||
@@ -344,10 +688,10 @@ src/stores/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: Core Components
|
### Phase 2: Core Components & AccountViewView Integration
|
||||||
|
|
||||||
**Complexity**: Medium
|
**Complexity**: Medium
|
||||||
**Goals**: Create reusable components and main views
|
**Goals**: Create reusable components, main views, and AccountViewView integration
|
||||||
|
|
||||||
#### Tasks
|
#### Tasks
|
||||||
1. **Reusable Components**
|
1. **Reusable Components**
|
||||||
@@ -370,24 +714,33 @@ src/stores/
|
|||||||
- Replace `console.*` with project logger
|
- Replace `console.*` with project logger
|
||||||
- Add loading states
|
- Add loading states
|
||||||
|
|
||||||
4. **AccountViewView Integration** ✅ **ACCEPTED: Option A**
|
4. **AccountViewView Integration** ✅ **ACCEPTED**
|
||||||
- Add separate "Daily Notifications" section
|
- 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 toggle switch for enabling/disabling notifications
|
||||||
- Add HTML5 time input for scheduling time
|
- Add HTML5 time input for scheduling time
|
||||||
- Integrate with PlatformService via PlatformServiceFactory
|
- Integrate with PlatformService via PlatformServiceFactory
|
||||||
- Save/load settings from `settings` table
|
- 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
|
#### Acceptance Criteria
|
||||||
- [ ] ActionCard and StatusCard components created
|
- [ ] ActionCard and StatusCard components created
|
||||||
- [ ] Home view shows notification diagnostics
|
- [ ] Home view shows notification diagnostics
|
||||||
- [ ] Schedule view allows notification scheduling
|
- [ ] 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
|
- [ ] Notification section checks PlatformService capabilities before showing
|
||||||
- [ ] Toggle and time input functional in AccountViewView
|
- [ ] Toggle and time input functional in AccountViewView
|
||||||
|
- [ ] Settings persist across app restarts
|
||||||
|
- [ ] Plugin state syncs with settings
|
||||||
- [ ] All logging uses project logger
|
- [ ] All logging uses project logger
|
||||||
- [ ] Error handling implemented
|
- [ ] Error handling implemented
|
||||||
- [ ] Loading states visible
|
- [ ] Loading states visible
|
||||||
|
- [ ] UI matches existing design patterns
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -436,11 +789,13 @@ src/stores/
|
|||||||
- Test permission requests
|
- Test permission requests
|
||||||
- Test status updates
|
- Test status updates
|
||||||
- Test native fetcher configuration
|
- Test native fetcher configuration
|
||||||
|
- Test AccountViewView integration on Capacitor
|
||||||
|
|
||||||
2. **Cross-Platform Validation**
|
2. **Cross-Platform Validation**
|
||||||
- Verify web build doesn't break
|
- Verify web build doesn't break
|
||||||
- Verify Electron build doesn't break
|
- Verify Electron build doesn't break
|
||||||
- Verify feature is hidden on non-Capacitor platforms
|
- Verify feature is hidden on non-Capacitor platforms
|
||||||
|
- Verify AccountViewView section hidden on web/electron
|
||||||
- Test graceful degradation
|
- Test graceful degradation
|
||||||
|
|
||||||
3. **Integration Testing**
|
3. **Integration Testing**
|
||||||
@@ -448,6 +803,7 @@ src/stores/
|
|||||||
- Test status checking workflow
|
- Test status checking workflow
|
||||||
- Test navigation between views
|
- Test navigation between views
|
||||||
- Test store state persistence
|
- Test store state persistence
|
||||||
|
- Test AccountViewView enable/disable/edit workflows
|
||||||
|
|
||||||
4. **Error Scenarios**
|
4. **Error Scenarios**
|
||||||
- Test plugin unavailable scenarios
|
- Test plugin unavailable scenarios
|
||||||
@@ -458,6 +814,7 @@ src/stores/
|
|||||||
#### Acceptance Criteria
|
#### Acceptance Criteria
|
||||||
- [ ] All Capacitor tests passing
|
- [ ] All Capacitor tests passing
|
||||||
- [ ] Web/Electron builds unaffected
|
- [ ] Web/Electron builds unaffected
|
||||||
|
- [ ] AccountViewView integration verified on all platforms
|
||||||
- [ ] Integration tests passing
|
- [ ] Integration tests passing
|
||||||
- [ ] Error scenarios handled gracefully
|
- [ ] Error scenarios handled gracefully
|
||||||
- [ ] Documentation updated
|
- [ ] Documentation updated
|
||||||
@@ -468,7 +825,7 @@ src/stores/
|
|||||||
|
|
||||||
### Milestone 1: Foundation Complete
|
### Milestone 1: Foundation Complete
|
||||||
**Success Criteria**:
|
**Success Criteria**:
|
||||||
- Factory service operational
|
- PlatformService interface extended
|
||||||
- Store created and tested
|
- Store created and tested
|
||||||
- Routes accessible
|
- Routes accessible
|
||||||
- No build regressions
|
- No build regressions
|
||||||
@@ -477,6 +834,7 @@ src/stores/
|
|||||||
**Success Criteria**:
|
**Success Criteria**:
|
||||||
- Home view shows diagnostics
|
- Home view shows diagnostics
|
||||||
- Schedule view functional
|
- Schedule view functional
|
||||||
|
- AccountViewView integration complete
|
||||||
- Plugin integration working
|
- Plugin integration working
|
||||||
- Logging standardized
|
- Logging standardized
|
||||||
|
|
||||||
@@ -502,24 +860,27 @@ src/stores/
|
|||||||
- Factory service platform detection
|
- Factory service platform detection
|
||||||
- Store actions and state management
|
- Store actions and state management
|
||||||
- Component rendering and interactions
|
- Component rendering and interactions
|
||||||
|
- AccountViewView notification section rendering
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
- Plugin API calls
|
- Plugin API calls
|
||||||
- Permission flows
|
- Permission flows
|
||||||
- Status updates
|
- Status updates
|
||||||
- Navigation between views
|
- Navigation between views
|
||||||
|
- AccountViewView enable/disable/edit workflows
|
||||||
|
|
||||||
### Platform Tests
|
### Platform Tests
|
||||||
- **Capacitor Android**: Notification scheduling, permissions, status
|
- **Capacitor Android**: Notification scheduling, permissions, status, AccountViewView UI
|
||||||
- **Capacitor iOS**: Notification scheduling, permissions, status
|
- **Capacitor iOS**: Notification scheduling, permissions, status, AccountViewView UI
|
||||||
- **Web**: Feature hidden, no errors
|
- **Web**: Feature hidden, no errors, AccountViewView section hidden
|
||||||
- **Electron**: Feature hidden, no errors
|
- **Electron**: Feature hidden, no errors, AccountViewView section hidden
|
||||||
|
|
||||||
### E2E Tests (Playwright)
|
### E2E Tests (Playwright)
|
||||||
- Full notification scheduling workflow
|
- Full notification scheduling workflow
|
||||||
- Permission request flow
|
- Permission request flow
|
||||||
- Status checking workflow
|
- Status checking workflow
|
||||||
- Error handling scenarios
|
- Error handling scenarios
|
||||||
|
- AccountViewView notification configuration workflow
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -537,6 +898,8 @@ src/stores/
|
|||||||
- Platform detection utilities
|
- Platform detection utilities
|
||||||
- Router configuration
|
- Router configuration
|
||||||
- Existing component patterns
|
- Existing component patterns
|
||||||
|
- AccountViewView component
|
||||||
|
- Settings schema and persistence
|
||||||
|
|
||||||
### Configuration Dependencies
|
### Configuration Dependencies
|
||||||
- **Active DID Management**: Use `$getActiveIdentity()` from `PlatformServiceMixin` (existing)
|
- **Active DID Management**: Use `$getActiveIdentity()` from `PlatformServiceMixin` (existing)
|
||||||
@@ -561,6 +924,7 @@ src/stores/
|
|||||||
- **Service Interface**: Abstract interface with platform implementations
|
- **Service Interface**: Abstract interface with platform implementations
|
||||||
- **Store Pattern**: Pinia store for state management
|
- **Store Pattern**: Pinia store for state management
|
||||||
- **Composition API vs Class**: Use provided code style (Composition API for HomeView, Class for ScheduleView)
|
- **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
|
### PlatformService Integration Strategy
|
||||||
|
|
||||||
@@ -615,6 +979,7 @@ await platformService.scheduleDailyNotification({
|
|||||||
- Use dynamic imports exclusively
|
- Use dynamic imports exclusively
|
||||||
- Test web/electron builds after each phase
|
- Test web/electron builds after each phase
|
||||||
- Ensure no static plugin imports
|
- Ensure no static plugin imports
|
||||||
|
- Verify AccountViewView section properly hidden
|
||||||
|
|
||||||
### Risk 4: Configuration Dependencies (RESOLVED)
|
### Risk 4: Configuration Dependencies (RESOLVED)
|
||||||
**Mitigation**:
|
**Mitigation**:
|
||||||
@@ -623,14 +988,22 @@ await platformService.scheduleDailyNotification({
|
|||||||
- **Use existing settings**: Get `apiServer` and `starredPlanHandleIds` from `$accountSettings()`
|
- **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
|
- **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
|
## Success Criteria Summary
|
||||||
|
|
||||||
- [ ] Plugin integrated using factory architecture
|
- [ ] Plugin integrated using PlatformService architecture
|
||||||
- [ ] Feature works on Capacitor (Android/iOS)
|
- [ ] Feature works on Capacitor (Android/iOS)
|
||||||
- [ ] Feature hidden/graceful on Web/Electron
|
- [ ] Feature hidden/graceful on Web/Electron
|
||||||
- [ ] All components created and functional
|
- [ ] All components created and functional
|
||||||
|
- [ ] AccountViewView integration complete and functional
|
||||||
- [ ] Store manages notification state
|
- [ ] Store manages notification state
|
||||||
- [ ] Router routes accessible
|
- [ ] Router routes accessible
|
||||||
- [ ] Logging standardized (no console.*)
|
- [ ] 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
|
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
|
4. **Set Up Store**: Create Pinia store for notification state
|
||||||
5. **Begin Phase 1 Implementation**: Start with foundation tasks
|
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/architectural_patterns.mdc` - Architecture patterns
|
||||||
- `.cursor/rules/app/timesafari_platforms.mdc` - Platform requirements
|
- `.cursor/rules/app/timesafari_platforms.mdc` - Platform requirements
|
||||||
- `src/services/QRScanner/QRScannerFactory.ts` - Factory pattern reference
|
- `src/services/QRScanner/QRScannerFactory.ts` - Factory pattern reference
|
||||||
|
- `src/views/AccountViewView.vue` - Target component for integration
|
||||||
|
|||||||
Reference in New Issue
Block a user