feat: add platform-specific configuration and build system
- Add Android configuration with notification channels and WorkManager - Add iOS configuration with BGTaskScheduler and notification categories - Add platform-specific build scripts and bundle size checking - Add API change detection and type checksum validation - Add release notes generation and chaos testing scripts - Add Vite configuration for TimeSafari-specific builds - Add Android notification channels XML configuration - Update package.json with new build scripts and dependencies Platforms: Android (WorkManager + SQLite), iOS (BGTaskScheduler + Core Data), Electron (Desktop notifications)
This commit is contained in:
357
src/android/timesafari-android-config.ts
Normal file
357
src/android/timesafari-android-config.ts
Normal file
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
* TimeSafari Android Configuration
|
||||
*
|
||||
* Provides TimeSafari-specific Android platform configuration including
|
||||
* notification channels, permissions, and battery optimization settings.
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* TimeSafari Android Configuration Interface
|
||||
*/
|
||||
export interface TimeSafariAndroidConfig {
|
||||
/**
|
||||
* Notification channel configuration
|
||||
*/
|
||||
notificationChannels: NotificationChannelConfig[];
|
||||
|
||||
/**
|
||||
* Permission requirements
|
||||
*/
|
||||
permissions: AndroidPermission[];
|
||||
|
||||
/**
|
||||
* Battery optimization settings
|
||||
*/
|
||||
batteryOptimization: BatteryOptimizationConfig;
|
||||
|
||||
/**
|
||||
* Doze and App Standby settings
|
||||
*/
|
||||
powerManagement: PowerManagementConfig;
|
||||
|
||||
/**
|
||||
* WorkManager constraints
|
||||
*/
|
||||
workManagerConstraints: WorkManagerConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Channel Configuration
|
||||
*/
|
||||
export interface NotificationChannelConfig {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
importance: 'low' | 'default' | 'high' | 'max';
|
||||
enableLights: boolean;
|
||||
enableVibration: boolean;
|
||||
lightColor: string;
|
||||
sound: string | null;
|
||||
showBadge: boolean;
|
||||
bypassDnd: boolean;
|
||||
lockscreenVisibility: 'public' | 'private' | 'secret';
|
||||
}
|
||||
|
||||
/**
|
||||
* Android Permission Configuration
|
||||
*/
|
||||
export interface AndroidPermission {
|
||||
name: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
runtime: boolean;
|
||||
category: 'notification' | 'alarm' | 'network' | 'storage' | 'system';
|
||||
}
|
||||
|
||||
/**
|
||||
* Battery Optimization Configuration
|
||||
*/
|
||||
export interface BatteryOptimizationConfig {
|
||||
exemptPackages: string[];
|
||||
whitelistRequestMessage: string;
|
||||
optimizationCheckInterval: number; // minutes
|
||||
fallbackBehavior: 'graceful' | 'aggressive' | 'disabled';
|
||||
}
|
||||
|
||||
/**
|
||||
* Power Management Configuration
|
||||
*/
|
||||
export interface PowerManagementConfig {
|
||||
dozeModeHandling: 'ignore' | 'adapt' | 'request_whitelist';
|
||||
appStandbyHandling: 'ignore' | 'adapt' | 'request_whitelist';
|
||||
backgroundRestrictions: 'ignore' | 'adapt' | 'request_whitelist';
|
||||
adaptiveBatteryHandling: 'ignore' | 'adapt' | 'request_whitelist';
|
||||
}
|
||||
|
||||
/**
|
||||
* WorkManager Constraints Configuration
|
||||
*/
|
||||
export interface WorkManagerConstraints {
|
||||
networkType: 'not_required' | 'connected' | 'unmetered' | 'not_roaming' | 'metered';
|
||||
requiresBatteryNotLow: boolean;
|
||||
requiresCharging: boolean;
|
||||
requiresDeviceIdle: boolean;
|
||||
requiresStorageNotLow: boolean;
|
||||
backoffPolicy: 'linear' | 'exponential';
|
||||
backoffDelay: number; // milliseconds
|
||||
maxRetries: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default TimeSafari Android Configuration
|
||||
*/
|
||||
export const DEFAULT_TIMESAFARI_ANDROID_CONFIG: TimeSafariAndroidConfig = {
|
||||
notificationChannels: [
|
||||
{
|
||||
id: 'timesafari_community_updates',
|
||||
name: 'TimeSafari Community Updates',
|
||||
description: 'Daily updates from your TimeSafari community including new offers, project updates, and trust network activities',
|
||||
importance: 'default',
|
||||
enableLights: true,
|
||||
enableVibration: true,
|
||||
lightColor: '#2196F3',
|
||||
sound: 'default',
|
||||
showBadge: true,
|
||||
bypassDnd: false,
|
||||
lockscreenVisibility: 'public'
|
||||
},
|
||||
{
|
||||
id: 'timesafari_project_notifications',
|
||||
name: 'TimeSafari Project Notifications',
|
||||
description: 'Notifications about starred projects, funding updates, and project milestones',
|
||||
importance: 'high',
|
||||
enableLights: true,
|
||||
enableVibration: true,
|
||||
lightColor: '#4CAF50',
|
||||
sound: 'default',
|
||||
showBadge: true,
|
||||
bypassDnd: false,
|
||||
lockscreenVisibility: 'public'
|
||||
},
|
||||
{
|
||||
id: 'timesafari_trust_network',
|
||||
name: 'TimeSafari Trust Network',
|
||||
description: 'Trust network activities, endorsements, and community recommendations',
|
||||
importance: 'default',
|
||||
enableLights: true,
|
||||
enableVibration: false,
|
||||
lightColor: '#FF9800',
|
||||
sound: null,
|
||||
showBadge: true,
|
||||
bypassDnd: false,
|
||||
lockscreenVisibility: 'public'
|
||||
},
|
||||
{
|
||||
id: 'timesafari_system',
|
||||
name: 'TimeSafari System',
|
||||
description: 'System notifications, authentication updates, and plugin status messages',
|
||||
importance: 'low',
|
||||
enableLights: false,
|
||||
enableVibration: false,
|
||||
lightColor: '#9E9E9E',
|
||||
sound: null,
|
||||
showBadge: false,
|
||||
bypassDnd: false,
|
||||
lockscreenVisibility: 'private'
|
||||
},
|
||||
{
|
||||
id: 'timesafari_reminders',
|
||||
name: 'TimeSafari Reminders',
|
||||
description: 'Personal reminders and daily check-ins for your TimeSafari activities',
|
||||
importance: 'default',
|
||||
enableLights: true,
|
||||
enableVibration: true,
|
||||
lightColor: '#9C27B0',
|
||||
sound: 'default',
|
||||
showBadge: true,
|
||||
bypassDnd: false,
|
||||
lockscreenVisibility: 'public'
|
||||
}
|
||||
],
|
||||
|
||||
permissions: [
|
||||
{
|
||||
name: 'android.permission.POST_NOTIFICATIONS',
|
||||
description: 'Allow TimeSafari to show notifications',
|
||||
required: true,
|
||||
runtime: true,
|
||||
category: 'notification'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.SCHEDULE_EXACT_ALARM',
|
||||
description: 'Allow TimeSafari to schedule exact alarms for notifications',
|
||||
required: true,
|
||||
runtime: true,
|
||||
category: 'alarm'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.USE_EXACT_ALARM',
|
||||
description: 'Allow TimeSafari to use exact alarms',
|
||||
required: false,
|
||||
runtime: false,
|
||||
category: 'alarm'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.WAKE_LOCK',
|
||||
description: 'Allow TimeSafari to keep device awake for background tasks',
|
||||
required: true,
|
||||
runtime: false,
|
||||
category: 'system'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.RECEIVE_BOOT_COMPLETED',
|
||||
description: 'Allow TimeSafari to restart notifications after device reboot',
|
||||
required: true,
|
||||
runtime: false,
|
||||
category: 'system'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.INTERNET',
|
||||
description: 'Allow TimeSafari to fetch community data and send callbacks',
|
||||
required: true,
|
||||
runtime: false,
|
||||
category: 'network'
|
||||
},
|
||||
{
|
||||
name: 'android.permission.ACCESS_NETWORK_STATE',
|
||||
description: 'Allow TimeSafari to check network connectivity',
|
||||
required: true,
|
||||
runtime: false,
|
||||
category: 'network'
|
||||
}
|
||||
],
|
||||
|
||||
batteryOptimization: {
|
||||
exemptPackages: ['com.timesafari.dailynotification'],
|
||||
whitelistRequestMessage: 'TimeSafari needs to run in the background to deliver your daily community updates and notifications. Please whitelist TimeSafari from battery optimization.',
|
||||
optimizationCheckInterval: 60, // 1 hour
|
||||
fallbackBehavior: 'graceful'
|
||||
},
|
||||
|
||||
powerManagement: {
|
||||
dozeModeHandling: 'request_whitelist',
|
||||
appStandbyHandling: 'request_whitelist',
|
||||
backgroundRestrictions: 'request_whitelist',
|
||||
adaptiveBatteryHandling: 'request_whitelist'
|
||||
},
|
||||
|
||||
workManagerConstraints: {
|
||||
networkType: 'connected',
|
||||
requiresBatteryNotLow: false,
|
||||
requiresCharging: false,
|
||||
requiresDeviceIdle: false,
|
||||
requiresStorageNotLow: true,
|
||||
backoffPolicy: 'exponential',
|
||||
backoffDelay: 30000, // 30 seconds
|
||||
maxRetries: 3
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TimeSafari Android Configuration Manager
|
||||
*/
|
||||
export class TimeSafariAndroidConfigManager {
|
||||
private config: TimeSafariAndroidConfig;
|
||||
|
||||
constructor(config?: Partial<TimeSafariAndroidConfig>) {
|
||||
this.config = { ...DEFAULT_TIMESAFARI_ANDROID_CONFIG, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification channel configuration
|
||||
*/
|
||||
getNotificationChannel(channelId: string): NotificationChannelConfig | undefined {
|
||||
return this.config.notificationChannels.find(channel => channel.id === channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notification channels
|
||||
*/
|
||||
getAllNotificationChannels(): NotificationChannelConfig[] {
|
||||
return this.config.notificationChannels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get required permissions
|
||||
*/
|
||||
getRequiredPermissions(): AndroidPermission[] {
|
||||
return this.config.permissions.filter(permission => permission.required);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get runtime permissions
|
||||
*/
|
||||
getRuntimePermissions(): AndroidPermission[] {
|
||||
return this.config.permissions.filter(permission => permission.runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get permissions by category
|
||||
*/
|
||||
getPermissionsByCategory(category: string): AndroidPermission[] {
|
||||
return this.config.permissions.filter(permission => permission.category === category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get battery optimization configuration
|
||||
*/
|
||||
getBatteryOptimizationConfig(): BatteryOptimizationConfig {
|
||||
return this.config.batteryOptimization;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get power management configuration
|
||||
*/
|
||||
getPowerManagementConfig(): PowerManagementConfig {
|
||||
return this.config.powerManagement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WorkManager constraints
|
||||
*/
|
||||
getWorkManagerConstraints(): WorkManagerConstraints {
|
||||
return this.config.workManagerConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration
|
||||
*/
|
||||
updateConfig(updates: Partial<TimeSafariAndroidConfig>): void {
|
||||
this.config = { ...this.config, ...updates };
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate configuration
|
||||
*/
|
||||
validateConfig(): { valid: boolean; errors: string[] } {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Validate notification channels
|
||||
if (this.config.notificationChannels.length === 0) {
|
||||
errors.push('At least one notification channel must be configured');
|
||||
}
|
||||
|
||||
// Validate permissions
|
||||
const requiredPermissions = this.getRequiredPermissions();
|
||||
if (requiredPermissions.length === 0) {
|
||||
errors.push('At least one required permission must be configured');
|
||||
}
|
||||
|
||||
// Validate WorkManager constraints
|
||||
if (this.config.workManagerConstraints.maxRetries < 0) {
|
||||
errors.push('WorkManager maxRetries must be non-negative');
|
||||
}
|
||||
|
||||
if (this.config.workManagerConstraints.backoffDelay < 0) {
|
||||
errors.push('WorkManager backoffDelay must be non-negative');
|
||||
}
|
||||
|
||||
return {
|
||||
valid: errors.length === 0,
|
||||
errors
|
||||
};
|
||||
}
|
||||
}
|
||||
537
src/ios/timesafari-ios-config.ts
Normal file
537
src/ios/timesafari-ios-config.ts
Normal file
@@ -0,0 +1,537 @@
|
||||
/**
|
||||
* TimeSafari iOS Configuration
|
||||
*
|
||||
* Provides TimeSafari-specific iOS platform configuration including
|
||||
* notification categories, background tasks, and permission handling.
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* TimeSafari iOS Configuration Interface
|
||||
*/
|
||||
export interface TimeSafariIOSConfig {
|
||||
/**
|
||||
* Notification categories configuration
|
||||
*/
|
||||
notificationCategories: NotificationCategoryConfig[];
|
||||
|
||||
/**
|
||||
* Background task configuration
|
||||
*/
|
||||
backgroundTasks: BackgroundTaskConfig[];
|
||||
|
||||
/**
|
||||
* Permission configuration
|
||||
*/
|
||||
permissions: IOSPermission[];
|
||||
|
||||
/**
|
||||
* Background App Refresh settings
|
||||
*/
|
||||
backgroundAppRefresh: BackgroundAppRefreshConfig;
|
||||
|
||||
/**
|
||||
* Notification center settings
|
||||
*/
|
||||
notificationCenter: NotificationCenterConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Category Configuration
|
||||
*/
|
||||
export interface NotificationCategoryConfig {
|
||||
identifier: string;
|
||||
actions: NotificationActionConfig[];
|
||||
intentIdentifiers: string[];
|
||||
hiddenPreviewsBodyPlaceholder: string;
|
||||
categorySummaryFormat: string;
|
||||
options: NotificationCategoryOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Action Configuration
|
||||
*/
|
||||
export interface NotificationActionConfig {
|
||||
identifier: string;
|
||||
title: string;
|
||||
options: NotificationActionOptions;
|
||||
textInputButtonTitle?: string;
|
||||
textInputPlaceholder?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task Configuration
|
||||
*/
|
||||
export interface BackgroundTaskConfig {
|
||||
identifier: string;
|
||||
name: string;
|
||||
description: string;
|
||||
estimatedDuration: number; // seconds
|
||||
requiresNetworkConnectivity: boolean;
|
||||
requiresExternalPower: boolean;
|
||||
priority: 'low' | 'default' | 'high';
|
||||
}
|
||||
|
||||
/**
|
||||
* iOS Permission Configuration
|
||||
*/
|
||||
export interface IOSPermission {
|
||||
type: 'notifications' | 'backgroundAppRefresh' | 'backgroundProcessing';
|
||||
description: string;
|
||||
required: boolean;
|
||||
provisional: boolean;
|
||||
options: NotificationPermissionOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background App Refresh Configuration
|
||||
*/
|
||||
export interface BackgroundAppRefreshConfig {
|
||||
enabled: boolean;
|
||||
allowedInLowPowerMode: boolean;
|
||||
allowedInBackground: boolean;
|
||||
minimumInterval: number; // seconds
|
||||
maximumDuration: number; // seconds
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Center Configuration
|
||||
*/
|
||||
export interface NotificationCenterConfig {
|
||||
delegateClassName: string;
|
||||
categories: string[];
|
||||
settings: NotificationCenterSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Category Options
|
||||
*/
|
||||
export interface NotificationCategoryOptions {
|
||||
customDismissAction: boolean;
|
||||
allowInCarPlay: boolean;
|
||||
allowAnnouncement: boolean;
|
||||
showTitle: boolean;
|
||||
showSubtitle: boolean;
|
||||
showBody: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Action Options
|
||||
*/
|
||||
export interface NotificationActionOptions {
|
||||
foreground: boolean;
|
||||
destructive: boolean;
|
||||
authenticationRequired: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Permission Options
|
||||
*/
|
||||
export interface NotificationPermissionOptions {
|
||||
alert: boolean;
|
||||
badge: boolean;
|
||||
sound: boolean;
|
||||
carPlay: boolean;
|
||||
criticalAlert: boolean;
|
||||
provisional: boolean;
|
||||
providesAppNotificationSettings: boolean;
|
||||
announcement: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Center Settings
|
||||
*/
|
||||
export interface NotificationCenterSettings {
|
||||
authorizationStatus: 'notDetermined' | 'denied' | 'authorized' | 'provisional';
|
||||
alertSetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
badgeSetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
soundSetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
carPlaySetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
criticalAlertSetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
providesAppNotificationSettings: boolean;
|
||||
announcementSetting: 'notSupported' | 'disabled' | 'enabled';
|
||||
}
|
||||
|
||||
/**
|
||||
* Default TimeSafari iOS Configuration
|
||||
*/
|
||||
export const DEFAULT_TIMESAFARI_IOS_CONFIG: TimeSafariIOSConfig = {
|
||||
notificationCategories: [
|
||||
{
|
||||
identifier: 'TIMESAFARI_COMMUNITY_UPDATE',
|
||||
actions: [
|
||||
{
|
||||
identifier: 'VIEW_OFFERS',
|
||||
title: 'View Offers',
|
||||
options: {
|
||||
foreground: true,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'VIEW_PROJECTS',
|
||||
title: 'View Projects',
|
||||
options: {
|
||||
foreground: true,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'DISMISS',
|
||||
title: 'Dismiss',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
}
|
||||
],
|
||||
intentIdentifiers: [],
|
||||
hiddenPreviewsBodyPlaceholder: 'New TimeSafari community update available',
|
||||
categorySummaryFormat: '%u more community updates',
|
||||
options: {
|
||||
customDismissAction: true,
|
||||
allowInCarPlay: false,
|
||||
allowAnnouncement: true,
|
||||
showTitle: true,
|
||||
showSubtitle: true,
|
||||
showBody: true
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'TIMESAFARI_PROJECT_UPDATE',
|
||||
actions: [
|
||||
{
|
||||
identifier: 'VIEW_PROJECT',
|
||||
title: 'View Project',
|
||||
options: {
|
||||
foreground: true,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'STAR_PROJECT',
|
||||
title: 'Star Project',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'DISMISS',
|
||||
title: 'Dismiss',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
}
|
||||
],
|
||||
intentIdentifiers: [],
|
||||
hiddenPreviewsBodyPlaceholder: 'New project update available',
|
||||
categorySummaryFormat: '%u more project updates',
|
||||
options: {
|
||||
customDismissAction: true,
|
||||
allowInCarPlay: false,
|
||||
allowAnnouncement: true,
|
||||
showTitle: true,
|
||||
showSubtitle: true,
|
||||
showBody: true
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'TIMESAFARI_TRUST_NETWORK',
|
||||
actions: [
|
||||
{
|
||||
identifier: 'VIEW_ENDORSEMENT',
|
||||
title: 'View Endorsement',
|
||||
options: {
|
||||
foreground: true,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'DISMISS',
|
||||
title: 'Dismiss',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
}
|
||||
],
|
||||
intentIdentifiers: [],
|
||||
hiddenPreviewsBodyPlaceholder: 'New trust network activity',
|
||||
categorySummaryFormat: '%u more trust network updates',
|
||||
options: {
|
||||
customDismissAction: true,
|
||||
allowInCarPlay: false,
|
||||
allowAnnouncement: false,
|
||||
showTitle: true,
|
||||
showSubtitle: true,
|
||||
showBody: true
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'TIMESAFARI_REMINDER',
|
||||
actions: [
|
||||
{
|
||||
identifier: 'COMPLETE_TASK',
|
||||
title: 'Complete Task',
|
||||
options: {
|
||||
foreground: true,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'SNOOZE',
|
||||
title: 'Snooze 1 Hour',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
},
|
||||
{
|
||||
identifier: 'DISMISS',
|
||||
title: 'Dismiss',
|
||||
options: {
|
||||
foreground: false,
|
||||
destructive: false,
|
||||
authenticationRequired: false
|
||||
}
|
||||
}
|
||||
],
|
||||
intentIdentifiers: [],
|
||||
hiddenPreviewsBodyPlaceholder: 'TimeSafari reminder',
|
||||
categorySummaryFormat: '%u more reminders',
|
||||
options: {
|
||||
customDismissAction: true,
|
||||
allowInCarPlay: true,
|
||||
allowAnnouncement: true,
|
||||
showTitle: true,
|
||||
showSubtitle: true,
|
||||
showBody: true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
backgroundTasks: [
|
||||
{
|
||||
identifier: 'com.timesafari.dailynotification.fetch',
|
||||
name: 'TimeSafari Content Fetch',
|
||||
description: 'Fetch daily community content and project updates',
|
||||
estimatedDuration: 30,
|
||||
requiresNetworkConnectivity: true,
|
||||
requiresExternalPower: false,
|
||||
priority: 'default'
|
||||
},
|
||||
{
|
||||
identifier: 'com.timesafari.dailynotification.notify',
|
||||
name: 'TimeSafari Notification Delivery',
|
||||
description: 'Deliver scheduled notifications to user',
|
||||
estimatedDuration: 10,
|
||||
requiresNetworkConnectivity: false,
|
||||
requiresExternalPower: false,
|
||||
priority: 'high'
|
||||
}
|
||||
],
|
||||
|
||||
permissions: [
|
||||
{
|
||||
type: 'notifications',
|
||||
description: 'Allow TimeSafari to send notifications about community updates and project activities',
|
||||
required: true,
|
||||
provisional: true,
|
||||
options: {
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
carPlay: false,
|
||||
criticalAlert: false,
|
||||
provisional: true,
|
||||
providesAppNotificationSettings: true,
|
||||
announcement: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'backgroundAppRefresh',
|
||||
description: 'Allow TimeSafari to refresh content in the background',
|
||||
required: true,
|
||||
provisional: false,
|
||||
options: {
|
||||
alert: false,
|
||||
badge: false,
|
||||
sound: false,
|
||||
carPlay: false,
|
||||
criticalAlert: false,
|
||||
provisional: false,
|
||||
providesAppNotificationSettings: false,
|
||||
announcement: false
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'backgroundProcessing',
|
||||
description: 'Allow TimeSafari to process background tasks',
|
||||
required: true,
|
||||
provisional: false,
|
||||
options: {
|
||||
alert: false,
|
||||
badge: false,
|
||||
sound: false,
|
||||
carPlay: false,
|
||||
criticalAlert: false,
|
||||
provisional: false,
|
||||
providesAppNotificationSettings: false,
|
||||
announcement: false
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
backgroundAppRefresh: {
|
||||
enabled: true,
|
||||
allowedInLowPowerMode: false,
|
||||
allowedInBackground: true,
|
||||
minimumInterval: 300, // 5 minutes
|
||||
maximumDuration: 30 // 30 seconds
|
||||
},
|
||||
|
||||
notificationCenter: {
|
||||
delegateClassName: 'TimeSafariNotificationCenterDelegate',
|
||||
categories: [
|
||||
'TIMESAFARI_COMMUNITY_UPDATE',
|
||||
'TIMESAFARI_PROJECT_UPDATE',
|
||||
'TIMESAFARI_TRUST_NETWORK',
|
||||
'TIMESAFARI_REMINDER'
|
||||
],
|
||||
settings: {
|
||||
authorizationStatus: 'notDetermined',
|
||||
alertSetting: 'enabled',
|
||||
badgeSetting: 'enabled',
|
||||
soundSetting: 'enabled',
|
||||
carPlaySetting: 'disabled',
|
||||
criticalAlertSetting: 'disabled',
|
||||
providesAppNotificationSettings: true,
|
||||
announcementSetting: 'enabled'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TimeSafari iOS Configuration Manager
|
||||
*/
|
||||
export class TimeSafariIOSConfigManager {
|
||||
private config: TimeSafariIOSConfig;
|
||||
|
||||
constructor(config?: Partial<TimeSafariIOSConfig>) {
|
||||
this.config = { ...DEFAULT_TIMESAFARI_IOS_CONFIG, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification category configuration
|
||||
*/
|
||||
getNotificationCategory(categoryId: string): NotificationCategoryConfig | undefined {
|
||||
return this.config.notificationCategories.find(category => category.identifier === categoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notification categories
|
||||
*/
|
||||
getAllNotificationCategories(): NotificationCategoryConfig[] {
|
||||
return this.config.notificationCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get background task configuration
|
||||
*/
|
||||
getBackgroundTask(taskId: string): BackgroundTaskConfig | undefined {
|
||||
return this.config.backgroundTasks.find(task => task.identifier === taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all background tasks
|
||||
*/
|
||||
getAllBackgroundTasks(): BackgroundTaskConfig[] {
|
||||
return this.config.backgroundTasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get required permissions
|
||||
*/
|
||||
getRequiredPermissions(): IOSPermission[] {
|
||||
return this.config.permissions.filter(permission => permission.required);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get provisional permissions
|
||||
*/
|
||||
getProvisionalPermissions(): IOSPermission[] {
|
||||
return this.config.permissions.filter(permission => permission.provisional);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get background app refresh configuration
|
||||
*/
|
||||
getBackgroundAppRefreshConfig(): BackgroundAppRefreshConfig {
|
||||
return this.config.backgroundAppRefresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notification center configuration
|
||||
*/
|
||||
getNotificationCenterConfig(): NotificationCenterConfig {
|
||||
return this.config.notificationCenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration
|
||||
*/
|
||||
updateConfig(updates: Partial<TimeSafariIOSConfig>): void {
|
||||
this.config = { ...this.config, ...updates };
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate configuration
|
||||
*/
|
||||
validateConfig(): { valid: boolean; errors: string[] } {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Validate notification categories
|
||||
if (this.config.notificationCategories.length === 0) {
|
||||
errors.push('At least one notification category must be configured');
|
||||
}
|
||||
|
||||
// Validate background tasks
|
||||
if (this.config.backgroundTasks.length === 0) {
|
||||
errors.push('At least one background task must be configured');
|
||||
}
|
||||
|
||||
// Validate permissions
|
||||
const requiredPermissions = this.getRequiredPermissions();
|
||||
if (requiredPermissions.length === 0) {
|
||||
errors.push('At least one required permission must be configured');
|
||||
}
|
||||
|
||||
// Validate background app refresh
|
||||
if (this.config.backgroundAppRefresh.minimumInterval < 0) {
|
||||
errors.push('Background app refresh minimum interval must be non-negative');
|
||||
}
|
||||
|
||||
if (this.config.backgroundAppRefresh.maximumDuration < 0) {
|
||||
errors.push('Background app refresh maximum duration must be non-negative');
|
||||
}
|
||||
|
||||
return {
|
||||
valid: errors.length === 0,
|
||||
errors
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user