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