Browse Source
- Add comprehensive guide explaining when to use the plugin with Capacitor - Clarify that plugin is only needed for Capacitor-based mobile apps - Provide platform detection and conditional loading examples - Add decision flowchart and matrix for easy understanding - Include integration checklist and common mistakes to avoid - Show how to check if Capacitor is installed and configured This clarifies that the plugin is only needed when TimeSafari PWA uses Capacitor for mobile app development, not for web-only PWAs.master
2 changed files with 744 additions and 0 deletions
@ -0,0 +1,492 @@ |
|||||
|
# DailyNotification Plugin - Capacitor Integration Guide |
||||
|
|
||||
|
**Author**: Matthew Raymer |
||||
|
**Version**: 1.0.0 |
||||
|
**Created**: 2025-10-08 06:24:57 UTC |
||||
|
|
||||
|
## Overview |
||||
|
|
||||
|
The DailyNotification plugin is **specifically designed for Capacitor-based mobile applications**. It provides native mobile functionality that is not available in web-only PWAs. This guide explains when and how to use the plugin in your TimeSafari PWA. |
||||
|
|
||||
|
## When to Use the Plugin |
||||
|
|
||||
|
### ✅ Use the Plugin When: |
||||
|
- **Capacitor is installed** in your TimeSafari PWA project |
||||
|
- **Building for mobile platforms** (Android, iOS) |
||||
|
- **Need native mobile features** like: |
||||
|
- Background notifications |
||||
|
- Native notification scheduling |
||||
|
- Background task execution |
||||
|
- Platform-specific notification channels |
||||
|
- Battery optimization handling |
||||
|
- Exact alarm permissions |
||||
|
|
||||
|
### ❌ Don't Use the Plugin When: |
||||
|
- **Web-only PWA** (no Capacitor) |
||||
|
- **Desktop-only Electron app** (though Electron support is available) |
||||
|
- **Server-side rendering** (SSR) |
||||
|
- **Static site generation** (SSG) |
||||
|
|
||||
|
## Integration Scenarios |
||||
|
|
||||
|
### Scenario 1: Web-Only PWA (No Plugin Needed) |
||||
|
|
||||
|
```typescript |
||||
|
// In your web-only TimeSafari PWA |
||||
|
// You continue using your existing code as-is |
||||
|
|
||||
|
private async loadNewStarredProjectChanges() { |
||||
|
if (this.activeDid && this.starredPlanHandleIds.length > 0) { |
||||
|
try { |
||||
|
const starredProjectChanges = await getStarredProjectsWithChanges( |
||||
|
this.axios, |
||||
|
this.apiServer, |
||||
|
this.activeDid, |
||||
|
this.starredPlanHandleIds, |
||||
|
this.lastAckedStarredPlanChangesJwtId, |
||||
|
); |
||||
|
this.numNewStarredProjectChanges = starredProjectChanges.data.length; |
||||
|
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit; |
||||
|
} catch (error) { |
||||
|
console.warn("[HomeView] Failed to load starred project changes:", error); |
||||
|
this.numNewStarredProjectChanges = 0; |
||||
|
this.newStarredProjectChangesHitLimit = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
**What happens:** |
||||
|
- Your existing code works perfectly in the browser |
||||
|
- No plugin integration needed |
||||
|
- No native mobile features (background notifications, etc.) |
||||
|
- Limited to web browser capabilities |
||||
|
|
||||
|
### Scenario 2: Capacitor-Based PWA (Plugin Recommended) |
||||
|
|
||||
|
```typescript |
||||
|
// In your Capacitor-based TimeSafari PWA |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
import { Capacitor } from '@capacitor/core'; |
||||
|
|
||||
|
class TimeSafariHomeView { |
||||
|
async initialize() { |
||||
|
// Check if running in Capacitor |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Initialize plugin for native mobile features |
||||
|
await this.setupDailyNotification(); |
||||
|
} else { |
||||
|
// Use existing web-only code |
||||
|
console.log('Running in web browser - using existing code'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async setupDailyNotification() { |
||||
|
// Only runs on native platforms (Android, iOS) |
||||
|
await DailyNotification.configure({ |
||||
|
timesafariConfig: { |
||||
|
activeDid: this.activeDid, |
||||
|
endpoints: { |
||||
|
projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween` |
||||
|
}, |
||||
|
starredProjectsConfig: { |
||||
|
enabled: true, |
||||
|
starredPlanHandleIds: this.starredPlanHandleIds, |
||||
|
lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId, |
||||
|
fetchInterval: '0 8 * * *' |
||||
|
} |
||||
|
}, |
||||
|
networkConfig: { |
||||
|
httpClient: this.axios, |
||||
|
baseURL: this.apiServer, |
||||
|
timeout: 30000 |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async loadNewStarredProjectChanges() { |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Use plugin-enhanced method on native platforms |
||||
|
await this.loadNewStarredProjectChangesNative(); |
||||
|
} else { |
||||
|
// Use existing web method in browser |
||||
|
await this.loadNewStarredProjectChangesWeb(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async loadNewStarredProjectChangesNative() { |
||||
|
// Plugin-enhanced method with native features |
||||
|
const starredProjectChanges = await this.integrationService.getStarredProjectsWithChanges( |
||||
|
this.activeDid, |
||||
|
this.starredPlanHandleIds, |
||||
|
this.lastAckedStarredPlanChangesJwtId |
||||
|
); |
||||
|
this.numNewStarredProjectChanges = starredProjectChanges.data.length; |
||||
|
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit; |
||||
|
} |
||||
|
|
||||
|
async loadNewStarredProjectChangesWeb() { |
||||
|
// Existing web-only method |
||||
|
const starredProjectChanges = await getStarredProjectsWithChanges( |
||||
|
this.axios, |
||||
|
this.apiServer, |
||||
|
this.activeDid, |
||||
|
this.starredPlanHandleIds, |
||||
|
this.lastAckedStarredPlanChangesJwtId, |
||||
|
); |
||||
|
this.numNewStarredProjectChanges = starredProjectChanges.data.length; |
||||
|
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit; |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Platform Detection |
||||
|
|
||||
|
### Check if Capacitor is Available |
||||
|
|
||||
|
```typescript |
||||
|
import { Capacitor } from '@capacitor/core'; |
||||
|
|
||||
|
// Check if running in Capacitor |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Use plugin for native mobile features |
||||
|
await this.setupDailyNotification(); |
||||
|
} else { |
||||
|
// Use existing web-only code |
||||
|
console.log('Running in web browser'); |
||||
|
} |
||||
|
|
||||
|
// Check specific platform |
||||
|
if (Capacitor.getPlatform() === 'android') { |
||||
|
// Android-specific configuration |
||||
|
} else if (Capacitor.getPlatform() === 'ios') { |
||||
|
// iOS-specific configuration |
||||
|
} else { |
||||
|
// Web browser |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Conditional Plugin Loading |
||||
|
|
||||
|
```typescript |
||||
|
// Only load plugin when needed |
||||
|
let DailyNotification: any = null; |
||||
|
let TimeSafariIntegrationService: any = null; |
||||
|
|
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Dynamically import plugin only on native platforms |
||||
|
const plugin = await import('@timesafari/daily-notification-plugin'); |
||||
|
DailyNotification = plugin.DailyNotification; |
||||
|
TimeSafariIntegrationService = plugin.TimeSafariIntegrationService; |
||||
|
} |
||||
|
|
||||
|
// Use plugin conditionally |
||||
|
if (DailyNotification) { |
||||
|
await DailyNotification.configure({...}); |
||||
|
} else { |
||||
|
// Use existing web-only code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Capacitor Configuration |
||||
|
|
||||
|
### 1. Install Capacitor (if not already installed) |
||||
|
|
||||
|
```bash |
||||
|
# Install Capacitor |
||||
|
npm install @capacitor/core @capacitor/cli |
||||
|
|
||||
|
# Initialize Capacitor |
||||
|
npx cap init |
||||
|
|
||||
|
# Add platforms |
||||
|
npx cap add android |
||||
|
npx cap add ios |
||||
|
``` |
||||
|
|
||||
|
### 2. Configure Capacitor for TimeSafari PWA |
||||
|
|
||||
|
```typescript |
||||
|
// capacitor.config.ts |
||||
|
import { CapacitorConfig } from '@capacitor/cli'; |
||||
|
|
||||
|
const config: CapacitorConfig = { |
||||
|
appId: 'app.timesafari', |
||||
|
appName: 'TimeSafari', |
||||
|
webDir: 'dist', |
||||
|
plugins: { |
||||
|
DailyNotification: { |
||||
|
// Plugin configuration |
||||
|
storage: 'tiered', |
||||
|
ttlSeconds: 1800, |
||||
|
enableETagSupport: true, |
||||
|
enableErrorHandling: true, |
||||
|
enablePerformanceOptimization: true |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
export default config; |
||||
|
``` |
||||
|
|
||||
|
### 3. Build and Sync |
||||
|
|
||||
|
```bash |
||||
|
# Build your PWA |
||||
|
npm run build |
||||
|
|
||||
|
# Sync with Capacitor |
||||
|
npx cap sync |
||||
|
|
||||
|
# Open in IDE |
||||
|
npx cap open android |
||||
|
npx cap open ios |
||||
|
``` |
||||
|
|
||||
|
## Platform-Specific Features |
||||
|
|
||||
|
### Android Features (Only with Plugin) |
||||
|
|
||||
|
```typescript |
||||
|
// Android-specific features |
||||
|
if (Capacitor.getPlatform() === 'android') { |
||||
|
// WorkManager for background tasks |
||||
|
// AlarmManager for exact notifications |
||||
|
// Notification channels |
||||
|
// Battery optimization handling |
||||
|
// Exact alarm permissions |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### iOS Features (Only with Plugin) |
||||
|
|
||||
|
```typescript |
||||
|
// iOS-specific features |
||||
|
if (Capacitor.getPlatform() === 'ios') { |
||||
|
// BGTaskScheduler for background tasks |
||||
|
// UNUserNotificationCenter for notifications |
||||
|
// Background App Refresh |
||||
|
// Provisional authorization |
||||
|
// Notification categories |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Web Features (Existing Code) |
||||
|
|
||||
|
```typescript |
||||
|
// Web browser features |
||||
|
if (!Capacitor.isNativePlatform()) { |
||||
|
// Service Worker (if implemented) |
||||
|
// Web Notifications API |
||||
|
// Local Storage |
||||
|
// IndexedDB |
||||
|
// Your existing web-only code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Integration Strategy |
||||
|
|
||||
|
### 1. Progressive Enhancement |
||||
|
|
||||
|
```typescript |
||||
|
class TimeSafariHomeView { |
||||
|
async initialize() { |
||||
|
// Always initialize with existing web code |
||||
|
await this.initializeWeb(); |
||||
|
|
||||
|
// Enhance with plugin if on native platform |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
await this.initializeNative(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async initializeWeb() { |
||||
|
// Your existing web-only initialization |
||||
|
console.log('Initialized web version'); |
||||
|
} |
||||
|
|
||||
|
async initializeNative() { |
||||
|
// Plugin-enhanced initialization |
||||
|
await this.setupDailyNotification(); |
||||
|
console.log('Initialized native version with plugin'); |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 2. Feature Detection |
||||
|
|
||||
|
```typescript |
||||
|
class TimeSafariHomeView { |
||||
|
private isNative = Capacitor.isNativePlatform(); |
||||
|
private hasPlugin = false; |
||||
|
|
||||
|
async initialize() { |
||||
|
if (this.isNative) { |
||||
|
try { |
||||
|
await this.setupDailyNotification(); |
||||
|
this.hasPlugin = true; |
||||
|
console.log('Plugin initialized successfully'); |
||||
|
} catch (error) { |
||||
|
console.warn('Plugin initialization failed, falling back to web mode'); |
||||
|
this.hasPlugin = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async loadNewStarredProjectChanges() { |
||||
|
if (this.hasPlugin) { |
||||
|
// Use plugin-enhanced method |
||||
|
await this.loadNewStarredProjectChangesNative(); |
||||
|
} else { |
||||
|
// Use existing web method |
||||
|
await this.loadNewStarredProjectChangesWeb(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 3. Graceful Degradation |
||||
|
|
||||
|
```typescript |
||||
|
class TimeSafariHomeView { |
||||
|
async loadNewStarredProjectChanges() { |
||||
|
try { |
||||
|
if (this.hasPlugin) { |
||||
|
// Try plugin-enhanced method first |
||||
|
await this.loadNewStarredProjectChangesNative(); |
||||
|
} else { |
||||
|
// Fall back to web method |
||||
|
await this.loadNewStarredProjectChangesWeb(); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
// If plugin fails, fall back to web method |
||||
|
console.warn('Plugin method failed, falling back to web method'); |
||||
|
await this.loadNewStarredProjectChangesWeb(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Build Configuration |
||||
|
|
||||
|
### 1. Package.json Scripts |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"scripts": { |
||||
|
"build": "vite build", |
||||
|
"build:web": "vite build", |
||||
|
"build:android": "vite build && npx cap sync android", |
||||
|
"build:ios": "vite build && npx cap sync ios", |
||||
|
"dev:web": "vite", |
||||
|
"dev:android": "vite && npx cap run android", |
||||
|
"dev:ios": "vite && npx cap run ios" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### 2. Environment Variables |
||||
|
|
||||
|
```bash |
||||
|
# .env |
||||
|
VITE_CAPACITOR_ENABLED=true |
||||
|
VITE_PLUGIN_ENABLED=true |
||||
|
|
||||
|
# .env.web (web-only build) |
||||
|
VITE_CAPACITOR_ENABLED=false |
||||
|
VITE_PLUGIN_ENABLED=false |
||||
|
``` |
||||
|
|
||||
|
### 3. Conditional Imports |
||||
|
|
||||
|
```typescript |
||||
|
// Only import plugin when needed |
||||
|
const loadPlugin = async () => { |
||||
|
if (import.meta.env.VITE_PLUGIN_ENABLED === 'true') { |
||||
|
return await import('@timesafari/daily-notification-plugin'); |
||||
|
} |
||||
|
return null; |
||||
|
}; |
||||
|
|
||||
|
const plugin = await loadPlugin(); |
||||
|
if (plugin) { |
||||
|
await plugin.DailyNotification.configure({...}); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Testing Strategy |
||||
|
|
||||
|
### 1. Web Testing |
||||
|
|
||||
|
```bash |
||||
|
# Test web-only version |
||||
|
npm run dev:web |
||||
|
# Test in browser - should use existing code |
||||
|
``` |
||||
|
|
||||
|
### 2. Native Testing |
||||
|
|
||||
|
```bash |
||||
|
# Test Android version |
||||
|
npm run dev:android |
||||
|
# Test on Android device/emulator - should use plugin |
||||
|
|
||||
|
# Test iOS version |
||||
|
npm run dev:ios |
||||
|
# Test on iOS device/simulator - should use plugin |
||||
|
``` |
||||
|
|
||||
|
### 3. Cross-Platform Testing |
||||
|
|
||||
|
```typescript |
||||
|
// Test both implementations |
||||
|
const testBothImplementations = async () => { |
||||
|
// Test web implementation |
||||
|
const webResult = await this.loadNewStarredProjectChangesWeb(); |
||||
|
|
||||
|
// Test native implementation (if available) |
||||
|
if (this.hasPlugin) { |
||||
|
const nativeResult = await this.loadNewStarredProjectChangesNative(); |
||||
|
|
||||
|
// Compare results |
||||
|
console.log('Web result:', webResult); |
||||
|
console.log('Native result:', nativeResult); |
||||
|
} |
||||
|
}; |
||||
|
``` |
||||
|
|
||||
|
## Common Questions |
||||
|
|
||||
|
### Q: Do I need to install the plugin for web-only PWAs? |
||||
|
**A:** No, the plugin is only needed for Capacitor-based mobile apps. Web-only PWAs continue using your existing code. |
||||
|
|
||||
|
### Q: What happens if I install the plugin but don't use Capacitor? |
||||
|
**A:** The plugin will not work in web browsers. You should use platform detection to only initialize the plugin on native platforms. |
||||
|
|
||||
|
### Q: Can I use the plugin in Electron? |
||||
|
**A:** Yes, the plugin supports Electron, but you need to configure it specifically for Electron. |
||||
|
|
||||
|
### Q: How do I handle different platforms? |
||||
|
**A:** Use `Capacitor.getPlatform()` to detect the platform and configure the plugin accordingly. |
||||
|
|
||||
|
### Q: What if the plugin fails to initialize? |
||||
|
**A:** Implement graceful degradation to fall back to your existing web-only code. |
||||
|
|
||||
|
## Conclusion |
||||
|
|
||||
|
The DailyNotification plugin is **only needed when using Capacitor** for mobile app development. For web-only PWAs, you continue using your existing TimeSafari code. The plugin provides native mobile features like background notifications, exact alarm scheduling, and platform-specific optimizations that are not available in web browsers. |
||||
|
|
||||
|
**Key Points:** |
||||
|
- ✅ **Use plugin with Capacitor** for mobile apps (Android, iOS) |
||||
|
- ❌ **Don't use plugin** for web-only PWAs |
||||
|
- 🔄 **Use platform detection** to conditionally load the plugin |
||||
|
- 🛡️ **Implement graceful degradation** to fall back to web code |
||||
|
- 🧪 **Test both implementations** to ensure compatibility |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Next Steps:** |
||||
|
1. Check if your TimeSafari PWA uses Capacitor |
||||
|
2. If yes, integrate the plugin with platform detection |
||||
|
3. If no, continue using your existing web-only code |
||||
|
4. Test both web and native implementations |
@ -0,0 +1,252 @@ |
|||||
|
# DailyNotification Plugin - Usage Decision Guide |
||||
|
|
||||
|
**Author**: Matthew Raymer |
||||
|
**Version**: 1.0.0 |
||||
|
**Created**: 2025-10-08 06:24:57 UTC |
||||
|
|
||||
|
## Quick Decision Flow |
||||
|
|
||||
|
``` |
||||
|
┌─────────────────────────────────────────────────────────────────────────────────┐ |
||||
|
│ TimeSafari PWA Project │ |
||||
|
├─────────────────────────────────────────────────────────────────────────────────┤ |
||||
|
│ │ |
||||
|
│ ┌─────────────────┐ │ |
||||
|
│ │ Does your │ │ |
||||
|
│ │ TimeSafari │ │ |
||||
|
│ │ PWA use │ │ |
||||
|
│ │ Capacitor? │ │ |
||||
|
│ └─────────────────┘ │ |
||||
|
│ │ │ |
||||
|
│ ▼ │ |
||||
|
│ ┌─────────────────┐ ┌─────────────────┐ │ |
||||
|
│ │ YES │ │ NO │ │ |
||||
|
│ │ │ │ │ │ |
||||
|
│ │ ┌─────────────┐│ │ ┌─────────────┐│ │ |
||||
|
│ │ │ Use ││ │ │ Don't ││ │ |
||||
|
│ │ │ Plugin ││ │ │ Use ││ │ |
||||
|
│ │ │ ││ │ │ Plugin ││ │ |
||||
|
│ │ │ ✅ Native ││ │ │ ││ │ |
||||
|
│ │ │ mobile ││ │ │ ❌ Web-only ││ │ |
||||
|
│ │ │ features ││ │ │ PWA ││ │ |
||||
|
│ │ │ ✅ Background││ │ │ ❌ No native││ │ |
||||
|
│ │ │ notifications││ │ │ features ││ │ |
||||
|
│ │ │ ✅ Platform ││ │ │ ❌ Use ││ │ |
||||
|
│ │ │ specific ││ │ │ existing ││ │ |
||||
|
│ │ │ optimizations││ │ │ code ││ │ |
||||
|
│ │ └─────────────┘│ │ └─────────────┘│ │ |
||||
|
│ └─────────────────┘ └─────────────────┘ │ |
||||
|
│ │ |
||||
|
└─────────────────────────────────────────────────────────────────────────────────┘ |
||||
|
``` |
||||
|
|
||||
|
## Detailed Decision Matrix |
||||
|
|
||||
|
| Scenario | Use Plugin? | Why? | What to Do | |
||||
|
|----------|-------------|------|------------| |
||||
|
| **Web-only PWA** | ❌ **NO** | Plugin requires Capacitor for native mobile features | Continue using your existing `loadNewStarredProjectChanges()` code | |
||||
|
| **Capacitor + Android** | ✅ **YES** | Plugin provides WorkManager, AlarmManager, notification channels | Integrate plugin with platform detection | |
||||
|
| **Capacitor + iOS** | ✅ **YES** | Plugin provides BGTaskScheduler, UNUserNotificationCenter | Integrate plugin with platform detection | |
||||
|
| **Capacitor + Electron** | ✅ **YES** | Plugin provides desktop notifications and background tasks | Integrate plugin with Electron-specific configuration | |
||||
|
| **Capacitor + Web** | ❌ **NO** | Web browser doesn't support native mobile features | Use existing web code, plugin won't work | |
||||
|
|
||||
|
## Code Examples |
||||
|
|
||||
|
### Scenario 1: Web-Only PWA (No Plugin) |
||||
|
|
||||
|
```typescript |
||||
|
// Your existing TimeSafari PWA code - NO CHANGES NEEDED |
||||
|
class TimeSafariHomeView { |
||||
|
private async loadNewStarredProjectChanges() { |
||||
|
if (this.activeDid && this.starredPlanHandleIds.length > 0) { |
||||
|
try { |
||||
|
const starredProjectChanges = await getStarredProjectsWithChanges( |
||||
|
this.axios, |
||||
|
this.apiServer, |
||||
|
this.activeDid, |
||||
|
this.starredPlanHandleIds, |
||||
|
this.lastAckedStarredPlanChangesJwtId, |
||||
|
); |
||||
|
this.numNewStarredProjectChanges = starredProjectChanges.data.length; |
||||
|
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit; |
||||
|
} catch (error) { |
||||
|
console.warn("[HomeView] Failed to load starred project changes:", error); |
||||
|
this.numNewStarredProjectChanges = 0; |
||||
|
this.newStarredProjectChangesHitLimit = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
**What happens:** |
||||
|
- Your existing code works perfectly in web browsers |
||||
|
- No plugin integration needed |
||||
|
- No native mobile features (background notifications, etc.) |
||||
|
- Limited to web browser capabilities |
||||
|
|
||||
|
### Scenario 2: Capacitor-Based PWA (Use Plugin) |
||||
|
|
||||
|
```typescript |
||||
|
// Your TimeSafari PWA with Capacitor - USE PLUGIN |
||||
|
import { Capacitor } from '@capacitor/core'; |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
class TimeSafariHomeView { |
||||
|
async initialize() { |
||||
|
// Check if running in Capacitor |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Initialize plugin for native mobile features |
||||
|
await this.setupDailyNotification(); |
||||
|
} else { |
||||
|
// Use existing web-only code |
||||
|
console.log('Running in web browser - using existing code'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async setupDailyNotification() { |
||||
|
// Only runs on native platforms (Android, iOS) |
||||
|
await DailyNotification.configure({ |
||||
|
timesafariConfig: { |
||||
|
activeDid: this.activeDid, |
||||
|
endpoints: { |
||||
|
projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween` |
||||
|
}, |
||||
|
starredProjectsConfig: { |
||||
|
enabled: true, |
||||
|
starredPlanHandleIds: this.starredPlanHandleIds, |
||||
|
lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId, |
||||
|
fetchInterval: '0 8 * * *' |
||||
|
} |
||||
|
}, |
||||
|
networkConfig: { |
||||
|
httpClient: this.axios, |
||||
|
baseURL: this.apiServer, |
||||
|
timeout: 30000 |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async loadNewStarredProjectChanges() { |
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
// Use plugin-enhanced method on native platforms |
||||
|
await this.loadNewStarredProjectChangesNative(); |
||||
|
} else { |
||||
|
// Use existing web method in browser |
||||
|
await this.loadNewStarredProjectChangesWeb(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
**What happens:** |
||||
|
- Plugin provides native mobile features (background notifications, etc.) |
||||
|
- Enhanced error handling and performance optimization |
||||
|
- Platform-specific optimizations (Android WorkManager, iOS BGTaskScheduler) |
||||
|
- Graceful fallback to web code when not on native platform |
||||
|
|
||||
|
## How to Check if You Need the Plugin |
||||
|
|
||||
|
### 1. Check if Capacitor is Installed |
||||
|
|
||||
|
```bash |
||||
|
# Check if Capacitor is in your package.json |
||||
|
npm list @capacitor/core |
||||
|
|
||||
|
# Or check your package.json file |
||||
|
cat package.json | grep capacitor |
||||
|
``` |
||||
|
|
||||
|
### 2. Check if Capacitor is Configured |
||||
|
|
||||
|
```bash |
||||
|
# Check if capacitor.config.ts exists |
||||
|
ls capacitor.config.ts |
||||
|
|
||||
|
# Or check if capacitor.config.js exists |
||||
|
ls capacitor.config.js |
||||
|
``` |
||||
|
|
||||
|
### 3. Check if Native Platforms are Added |
||||
|
|
||||
|
```bash |
||||
|
# Check if Android platform is added |
||||
|
ls android/ |
||||
|
|
||||
|
# Check if iOS platform is added |
||||
|
ls ios/ |
||||
|
``` |
||||
|
|
||||
|
### 4. Check in Your Code |
||||
|
|
||||
|
```typescript |
||||
|
// Add this to your TimeSafari PWA to check |
||||
|
import { Capacitor } from '@capacitor/core'; |
||||
|
|
||||
|
console.log('Platform:', Capacitor.getPlatform()); |
||||
|
console.log('Is Native:', Capacitor.isNativePlatform()); |
||||
|
console.log('Is Web:', Capacitor.getPlatform() === 'web'); |
||||
|
``` |
||||
|
|
||||
|
## Integration Checklist |
||||
|
|
||||
|
### ✅ If You Have Capacitor: |
||||
|
|
||||
|
- [ ] Install the DailyNotification plugin |
||||
|
- [ ] Add platform detection to your code |
||||
|
- [ ] Configure the plugin for your TimeSafari data |
||||
|
- [ ] Test on Android device/emulator |
||||
|
- [ ] Test on iOS device/simulator |
||||
|
- [ ] Test web fallback in browser |
||||
|
- [ ] Implement graceful degradation |
||||
|
|
||||
|
### ❌ If You Don't Have Capacitor: |
||||
|
|
||||
|
- [ ] Continue using your existing code |
||||
|
- [ ] No plugin integration needed |
||||
|
- [ ] No changes required |
||||
|
- [ ] Your existing `loadNewStarredProjectChanges()` works perfectly |
||||
|
|
||||
|
## Common Mistakes |
||||
|
|
||||
|
### ❌ Mistake 1: Installing Plugin Without Capacitor |
||||
|
|
||||
|
```typescript |
||||
|
// DON'T DO THIS - Plugin won't work in web browsers |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
// This will fail in web browsers |
||||
|
await DailyNotification.configure({...}); |
||||
|
``` |
||||
|
|
||||
|
### ❌ Mistake 2: Not Using Platform Detection |
||||
|
|
||||
|
```typescript |
||||
|
// DON'T DO THIS - Always tries to use plugin |
||||
|
await DailyNotification.configure({...}); // Fails in web browsers |
||||
|
``` |
||||
|
|
||||
|
### ✅ Correct Approach: Platform Detection |
||||
|
|
||||
|
```typescript |
||||
|
// DO THIS - Only use plugin on native platforms |
||||
|
import { Capacitor } from '@capacitor/core'; |
||||
|
|
||||
|
if (Capacitor.isNativePlatform()) { |
||||
|
await DailyNotification.configure({...}); |
||||
|
} else { |
||||
|
// Use existing web code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Summary |
||||
|
|
||||
|
**The DailyNotification plugin is ONLY needed when your TimeSafari PWA uses Capacitor for mobile app development.** |
||||
|
|
||||
|
- **Web-only PWA**: Continue using your existing code, no plugin needed |
||||
|
- **Capacitor-based PWA**: Use the plugin with platform detection for native mobile features |
||||
|
- **Always implement graceful degradation** to fall back to web code when needed |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Quick Answer**: If your TimeSafari PWA doesn't use Capacitor, you don't need the DailyNotification plugin. Your existing `loadNewStarredProjectChanges()` code works perfectly for web-only PWAs. |
Loading…
Reference in new issue