Files
daily-notification-plugin/src/web.ts
T

644 lines
16 KiB
TypeScript

/**
* Daily Notification Plugin - Web Implementation
*
* Web platform implementation for Capacitor Daily Notification Plugin.
*
* **Note:** Daily notifications are not supported on web platforms.
* This implementation provides clear error messages for all methods.
*
* @author Matthew Raymer
* @version 1.3.1
*/
import type {
DailyNotificationPlugin,
PermissionState,
Schedule,
ScheduleWithStatus,
CreateScheduleInput,
Config,
CreateConfigInput,
Callback,
CreateCallbackInput,
History,
HistoryStats,
PendingNotificationsResult,
DeliveredNotificationsResult,
NotificationCenterSettingsSnapshot,
NotificationPermissionStatus,
BackgroundTaskStatus,
} from './definitions';
import { DailyNotificationError, ErrorCode } from './core/errors';
/**
* Web implementation of DailyNotificationPlugin
*
* All methods throw errors indicating that daily notifications
* are not supported on web platforms.
*/
export class DailyNotificationWeb implements DailyNotificationPlugin {
private throwNotSupported(): never {
throw new DailyNotificationError(
ErrorCode.NOT_SUPPORTED,
'Daily notifications are not supported on web platforms. Please use this plugin on iOS or Android.',
{
guidance: 'Use native iOS or Android implementation for this feature',
platform: 'web'
}
);
}
async configure(): Promise<void> {
this.throwNotSupported();
}
async configureNativeFetcher(): Promise<void> {
this.throwNotSupported();
}
async maintainRollingWindow(): Promise<void> {
this.throwNotSupported();
}
async getRollingWindowStats(): Promise<{
stats: string;
maintenanceNeeded: boolean;
timeUntilNextMaintenance: number;
}> {
this.throwNotSupported();
}
async getExactAlarmStatus(): Promise<{
supported: boolean;
enabled: boolean;
canSchedule: boolean;
fallbackWindow: string;
}> {
this.throwNotSupported();
}
async requestExactAlarmPermission(): Promise<void> {
this.throwNotSupported();
}
async openExactAlarmSettings(): Promise<void> {
this.throwNotSupported();
}
async getRebootRecoveryStatus(): Promise<{
inProgress: boolean;
lastRecoveryTime: number;
timeSinceLastRecovery: number;
recoveryNeeded: boolean;
}> {
this.throwNotSupported();
}
async scheduleDailyNotification(): Promise<void> {
this.throwNotSupported();
}
async isAlarmScheduled(): Promise<{ scheduled: boolean; triggerAtMillis: number }> {
this.throwNotSupported();
}
async getNextAlarmTime(): Promise<{ scheduled: boolean; triggerAtMillis?: number }> {
this.throwNotSupported();
}
async testAlarm(): Promise<{ scheduled: boolean; secondsFromNow: number; triggerAtMillis: number }> {
this.throwNotSupported();
}
async getLastNotification(): Promise<null> {
this.throwNotSupported();
}
async cancelAllNotifications(): Promise<void> {
this.throwNotSupported();
}
async clearApiNotifications(): Promise<void> {
this.throwNotSupported();
}
async getNotificationStatus(): Promise<{
isEnabled?: boolean;
isScheduled?: boolean;
lastNotificationTime: number | Promise<number>;
nextNotificationTime: number | Promise<number>;
pending?: number;
settings: Record<string, unknown>;
error?: string;
}> {
this.throwNotSupported();
}
async updateSettings(): Promise<void> {
this.throwNotSupported();
}
async getBatteryStatus(): Promise<{
level: number;
isCharging: boolean;
powerState: number;
isOptimizationExempt: boolean;
}> {
this.throwNotSupported();
}
async requestBatteryOptimizationExemption(): Promise<void> {
this.throwNotSupported();
}
async setAdaptiveScheduling(): Promise<void> {
this.throwNotSupported();
}
async getPowerState(): Promise<{
powerState: number;
isOptimizationExempt: boolean;
}> {
this.throwNotSupported();
}
async checkPermissions(): Promise<{
status?: string;
granted?: boolean;
notifications: PermissionState;
backgroundRefresh?: PermissionState;
alert?: boolean;
badge?: boolean;
sound?: boolean;
lockScreen?: boolean;
carPlay?: boolean;
}> {
this.throwNotSupported();
}
async requestPermissions(): Promise<{
status?: string;
granted?: boolean;
notifications: PermissionState;
backgroundRefresh?: PermissionState;
alert?: boolean;
badge?: boolean;
sound?: boolean;
lockScreen?: boolean;
carPlay?: boolean;
}> {
this.throwNotSupported();
}
async checkPermissionStatus(): Promise<{
notificationsEnabled: boolean;
exactAlarmEnabled: boolean;
wakeLockEnabled: boolean;
allPermissionsGranted: boolean;
}> {
this.throwNotSupported();
}
async requestNotificationPermissions(): Promise<{
status?: string;
granted?: boolean;
notifications: PermissionState;
backgroundRefresh?: PermissionState;
alert?: boolean;
badge?: boolean;
sound?: boolean;
lockScreen?: boolean;
carPlay?: boolean;
}> {
this.throwNotSupported();
}
async getPendingNotifications(): Promise<PendingNotificationsResult> {
this.throwNotSupported();
}
async getDeliveredNotifications(): Promise<DeliveredNotificationsResult> {
this.throwNotSupported();
}
async getNotificationSettings(): Promise<NotificationCenterSettingsSnapshot> {
this.throwNotSupported();
}
async getNotificationPermissionStatus(): Promise<NotificationPermissionStatus> {
this.throwNotSupported();
}
async requestNotificationPermission(): Promise<{ granted: boolean }> {
this.throwNotSupported();
}
async getBackgroundTaskStatus(): Promise<BackgroundTaskStatus> {
this.throwNotSupported();
}
async openNotificationSettings(): Promise<void> {
this.throwNotSupported();
}
async openBackgroundAppRefreshSettings(): Promise<void> {
this.throwNotSupported();
}
async isChannelEnabled(): Promise<{ enabled: boolean; channelId: string }> {
this.throwNotSupported();
}
async openChannelSettings(): Promise<void> {
this.throwNotSupported();
}
async checkStatus(): Promise<{
isEnabled?: boolean;
isScheduled?: boolean;
lastNotificationTime: number | Promise<number>;
nextNotificationTime: number | Promise<number>;
pending?: number;
settings: Record<string, unknown>;
error?: string;
}> {
this.throwNotSupported();
}
async scheduleContentFetch(): Promise<void> {
this.throwNotSupported();
}
async scheduleUserNotification(): Promise<void> {
this.throwNotSupported();
}
async scheduleDualNotification(): Promise<void> {
this.throwNotSupported();
}
async getDualScheduleStatus(): Promise<{
contentFetch: {
isEnabled: boolean;
isScheduled: boolean;
lastFetchTime?: number;
nextFetchTime?: number;
lastFetchResult?: {
success: boolean;
data?: Record<string, unknown>;
timestamp: number;
contentAge: number;
error?: string;
retryCount: number;
metadata?: Record<string, unknown>;
};
pendingFetches: number;
};
userNotification: {
isEnabled: boolean;
isScheduled: boolean;
lastNotificationTime?: number;
nextNotificationTime?: number;
pendingNotifications: number;
};
relationship: {
isLinked: boolean;
contentAvailable: boolean;
lastLinkTime?: number;
};
overall: {
isActive: boolean;
lastActivity: number;
errorCount: number;
successRate: number;
};
}> {
this.throwNotSupported();
}
async updateDualScheduleConfig(): Promise<void> {
this.throwNotSupported();
}
async cancelDualSchedule(): Promise<void> {
this.throwNotSupported();
}
async pauseDualSchedule(): Promise<void> {
this.throwNotSupported();
}
async resumeDualSchedule(): Promise<void> {
this.throwNotSupported();
}
async getContentCache(): Promise<Record<string, unknown>> {
this.throwNotSupported();
}
async clearContentCache(): Promise<void> {
this.throwNotSupported();
}
async getContentHistory(): Promise<Array<{
success: boolean;
data?: Record<string, unknown>;
timestamp: number;
contentAge: number;
error?: string;
retryCount: number;
metadata?: Record<string, unknown>;
}>> {
this.throwNotSupported();
}
async registerCallback(): Promise<void> {
this.throwNotSupported();
}
async unregisterCallback(): Promise<void> {
this.throwNotSupported();
}
async getRegisteredCallbacks(): Promise<string[]> {
this.throwNotSupported();
}
async getSchedules(_options?: { kind?: 'fetch' | 'notify'; enabled?: boolean }): Promise<{ schedules: Schedule[] }> {
this.throwNotSupported();
}
async getSchedulesWithStatus(_options?: { kind?: 'fetch' | 'notify'; enabled?: boolean }): Promise<{ schedules: ScheduleWithStatus[] }> {
this.throwNotSupported();
}
async getSchedule(_id: string): Promise<Schedule | null> {
this.throwNotSupported();
}
async createSchedule(_schedule: CreateScheduleInput): Promise<Schedule> {
// Web stub: no timing needed (throws immediately)
this.throwNotSupported();
}
async updateSchedule(_id: string, _updates: unknown): Promise<Schedule> {
// Web stub: no timing needed (throws immediately)
this.throwNotSupported();
}
async deleteSchedule(_id: string): Promise<void> {
// Web stub: no timing needed (throws immediately)
this.throwNotSupported();
}
/**
* Get current plugin state (development only)
* @internal
*/
async getDebugState(): Promise<{
schedules: Schedule[];
configs: Config[];
callbacks: Callback[];
metrics: {
eventCount: number;
successRate: number;
avgFetchTime: number;
avgNotifyTime: number;
};
}> {
// Web implementation: debug methods not supported
throw new DailyNotificationError(
ErrorCode.NOT_SUPPORTED,
'Debug methods not available on web platform',
{
guidance: 'Use native iOS or Android implementation for debug features',
platform: 'web'
}
);
}
async enableSchedule(_id: string, _enabled: boolean): Promise<void> {
this.throwNotSupported();
}
async calculateNextRunTime(_schedule: string): Promise<number> {
this.throwNotSupported();
}
async getContentCacheById(_options?: { id?: string }): Promise<{
id: string;
fetchedAt: number;
ttlSeconds: number;
payload: string;
meta?: string;
} | null> {
this.throwNotSupported();
}
async getLatestContentCache(): Promise<{
id: string;
fetchedAt: number;
ttlSeconds: number;
payload: string;
meta?: string;
} | null> {
this.throwNotSupported();
}
async getContentCacheHistory(_limit?: number): Promise<{ history: Array<{
id: string;
fetchedAt: number;
ttlSeconds: number;
payload: string;
meta?: string;
}> }> {
this.throwNotSupported();
}
async saveContentCache(_content: unknown): Promise<{
id: string;
fetchedAt: number;
ttlSeconds: number;
payload: string;
meta?: string;
}> {
this.throwNotSupported();
}
async clearContentCacheEntries(_options?: { olderThan?: number }): Promise<void> {
this.throwNotSupported();
}
async getConfig(_key: string, _options?: { timesafariDid?: string }): Promise<Config | null> {
this.throwNotSupported();
}
async getAllConfigs(_options?: { timesafariDid?: string; configType?: string }): Promise<{ configs: Config[] }> {
this.throwNotSupported();
}
async setConfig(_config: CreateConfigInput): Promise<Config> {
this.throwNotSupported();
}
async updateConfig(_key: string, _value: string, _options?: { timesafariDid?: string }): Promise<Config> {
this.throwNotSupported();
}
async deleteConfig(_key: string, _options?: { timesafariDid?: string }): Promise<void> {
this.throwNotSupported();
}
async getCallbacks(_options?: { enabled?: boolean }): Promise<{ callbacks: Callback[] }> {
this.throwNotSupported();
}
async getCallback(_id: string): Promise<Callback | null> {
this.throwNotSupported();
}
async registerCallbackConfig(_callback: CreateCallbackInput): Promise<Callback> {
this.throwNotSupported();
}
async updateCallback(_id: string, _updates: unknown): Promise<Callback> {
this.throwNotSupported();
}
async deleteCallback(_id: string): Promise<void> {
this.throwNotSupported();
}
async enableCallback(_id: string, _enabled: boolean): Promise<void> {
this.throwNotSupported();
}
async getHistoryStats(): Promise<HistoryStats> {
this.throwNotSupported();
}
async getHistory(_options?: { since?: number; kind?: 'fetch' | 'notify' | 'callback'; limit?: number }): Promise<{ history: History[] }> {
this.throwNotSupported();
}
async setActiveDidFromHost(_activeDid: string): Promise<void> {
this.throwNotSupported();
}
onActiveDidChange(_callback: (newActiveDid: string) => Promise<void>): void {
this.throwNotSupported();
}
setJsContentFetcher(_fetcher: unknown): void {
this.throwNotSupported();
}
async refreshAuthenticationForNewIdentity(_activeDid: string): Promise<void> {
this.throwNotSupported();
}
async clearCacheForNewIdentity(): Promise<void> {
this.throwNotSupported();
}
async updateBackgroundTaskIdentity(_activeDid: string): Promise<void> {
this.throwNotSupported();
}
async updateStarredPlans(_options: { planIds: string[] }): Promise<{
success: boolean;
planIdsCount: number;
updatedAt: number;
}> {
this.throwNotSupported();
}
async getStarredPlans(): Promise<{
planIds: string[];
count: number;
updatedAt: number;
}> {
this.throwNotSupported();
}
async triggerImmediateFetch(): Promise<{
success: boolean;
message: string;
}> {
this.throwNotSupported();
}
async scheduleDailyReminder(_options: unknown): Promise<void> {
this.throwNotSupported();
}
async cancelDailyReminder(_reminderId: string): Promise<void> {
this.throwNotSupported();
}
async getScheduledReminders(): Promise<Array<{
id: string;
title: string;
body: string;
time: string;
sound: boolean;
vibration: boolean;
priority: 'low' | 'normal' | 'high';
repeatDaily: boolean;
timezone?: string;
isScheduled: boolean;
createdAt: number;
}>> {
this.throwNotSupported();
}
async updateDailyReminder(_reminderId: string, _options: unknown): Promise<void> {
this.throwNotSupported();
}
async enableNativeFetcher(_enable: boolean): Promise<{
enabled: boolean;
registered: boolean;
}> {
this.throwNotSupported();
}
async setPolicy(_policy: unknown): Promise<void> {
this.throwNotSupported();
}
async coordinateBackgroundTasks(): Promise<void> {
this.throwNotSupported();
}
async handleAppLifecycleEvent(_event: unknown): Promise<void> {
this.throwNotSupported();
}
async getCoordinationStatus(): Promise<{
platform: 'android' | 'ios' | 'electron';
coordinationActive: boolean;
coordinationPaused: boolean;
autoSync?: boolean;
appBackgrounded?: boolean;
appHidden?: boolean;
visibilityState?: DocumentVisibilityState;
focused?: boolean;
lastActiveDidChange?: number;
lastCoordinationTimestamp?: number;
lastAppBackgrounded?: number;
lastAppForegrounded?: number;
lastCoordinationSuccess?: number;
lastCoordinationFailure?: number;
coordinationErrors?: string[];
}> {
this.throwNotSupported();
}
}
// Export singleton instance
const DailyNotification = new DailyNotificationWeb();
export { DailyNotification };