UNPKG

@ordojs/mobile

Version:

Mobile and PWA support for OrdoJS applications

1 lines 18.6 kB
{"version":3,"sources":["../src/native.ts"],"names":["NativeManager","config","feature","info","userAgent","connection","battery","error","nativeFeature","track","resolve","options","reject","input","event","file","reader","position","newConfig"],"mappings":"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","file":"native.mjs","sourcesContent":["import type { DeviceInfo, NativeConfig, NativeFeature } from './types';\n\nexport class NativeManager {\n private config: NativeConfig;\n private features: Map<string, NativeFeature> = new Map();\n\n constructor(config: Partial<NativeConfig> = {}) {\n this.config = {\n features: {\n camera: true,\n geolocation: true,\n contacts: true,\n calendar: true,\n notifications: true,\n storage: true,\n network: true,\n device: true\n },\n permissions: [],\n plugins: [],\n ...config\n };\n\n this.initializeFeatures();\n }\n\n /**\n * Initializes available native features\n */\n private initializeFeatures(): void {\n // Camera\n if (this.config.features.camera) {\n this.features.set('camera', {\n name: 'Camera',\n available: this.isFeatureAvailable('camera'),\n permission: 'camera',\n description: 'Access device camera for photo/video capture'\n });\n }\n\n // Geolocation\n if (this.config.features.geolocation) {\n this.features.set('geolocation', {\n name: 'Geolocation',\n available: this.isFeatureAvailable('geolocation'),\n permission: 'geolocation',\n description: 'Access device location services'\n });\n }\n\n // Contacts\n if (this.config.features.contacts) {\n this.features.set('contacts', {\n name: 'Contacts',\n available: this.isFeatureAvailable('contacts'),\n permission: 'contacts',\n description: 'Access device contacts'\n });\n }\n\n // Calendar\n if (this.config.features.calendar) {\n this.features.set('calendar', {\n name: 'Calendar',\n available: this.isFeatureAvailable('calendar'),\n permission: 'calendar',\n description: 'Access device calendar'\n });\n }\n\n // Notifications\n if (this.config.features.notifications) {\n this.features.set('notifications', {\n name: 'Notifications',\n available: this.isFeatureAvailable('notifications'),\n permission: 'notifications',\n description: 'Send push notifications'\n });\n }\n\n // Storage\n if (this.config.features.storage) {\n this.features.set('storage', {\n name: 'Storage',\n available: this.isFeatureAvailable('storage'),\n description: 'Access device storage'\n });\n }\n\n // Network\n if (this.config.features.network) {\n this.features.set('network', {\n name: 'Network',\n available: this.isFeatureAvailable('network'),\n description: 'Access network information'\n });\n }\n\n // Device\n if (this.config.features.device) {\n this.features.set('device', {\n name: 'Device',\n available: this.isFeatureAvailable('device'),\n description: 'Access device information'\n });\n }\n }\n\n /**\n * Checks if a feature is available\n */\n private isFeatureAvailable(feature: string): boolean {\n if (typeof window === 'undefined') return false;\n\n switch (feature) {\n case 'camera':\n return 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices;\n case 'geolocation':\n return 'geolocation' in navigator;\n case 'contacts':\n return 'contacts' in navigator || 'ContactsManager' in window;\n case 'calendar':\n return 'Calendar' in window;\n case 'notifications':\n return 'Notification' in window;\n case 'storage':\n return 'localStorage' in window || 'indexedDB' in window;\n case 'network':\n return 'connection' in navigator || 'onLine' in navigator;\n case 'device':\n return 'deviceMemory' in navigator || 'hardwareConcurrency' in navigator;\n default:\n return false;\n }\n }\n\n /**\n * Gets device information\n */\n async getDeviceInfo(): Promise<DeviceInfo> {\n const info: DeviceInfo = {\n platform: 'web',\n version: '',\n model: '',\n manufacturer: '',\n screenWidth: window.screen.width,\n screenHeight: window.screen.height,\n pixelRatio: window.devicePixelRatio || 1,\n orientation: window.screen.width > window.screen.height ? 'landscape' : 'portrait',\n isOnline: navigator.onLine,\n connectionType: 'unknown',\n batteryLevel: 0,\n isCharging: false\n };\n\n // Detect platform\n const userAgent = navigator.userAgent.toLowerCase();\n if (userAgent.includes('iphone') || userAgent.includes('ipad')) {\n info.platform = 'ios';\n } else if (userAgent.includes('android')) {\n info.platform = 'android';\n }\n\n // Get connection type\n if ('connection' in navigator) {\n const connection = (navigator as any).connection;\n if (connection) {\n info.connectionType = connection.effectiveType || 'unknown';\n }\n }\n\n // Get battery information\n if ('getBattery' in navigator) {\n try {\n const battery = await (navigator as any).getBattery();\n info.batteryLevel = battery.level;\n info.isCharging = battery.charging;\n } catch (error) {\n console.warn('Battery API not available:', error);\n }\n }\n\n return info;\n }\n\n /**\n * Requests permission for a feature\n */\n async requestPermission(feature: string): Promise<boolean> {\n const nativeFeature = this.features.get(feature);\n if (!nativeFeature) {\n throw new Error(`Feature ${feature} not found`);\n }\n\n if (!nativeFeature.available) {\n throw new Error(`Feature ${feature} not available on this device`);\n }\n\n switch (feature) {\n case 'camera':\n return this.requestCameraPermission();\n case 'geolocation':\n return this.requestGeolocationPermission();\n case 'notifications':\n return this.requestNotificationPermission();\n default:\n return true; // Assume granted for other features\n }\n }\n\n /**\n * Requests camera permission\n */\n private async requestCameraPermission(): Promise<boolean> {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n stream.getTracks().forEach(track => track.stop());\n return true;\n } catch (error) {\n console.error('Camera permission denied:', error);\n return false;\n }\n }\n\n /**\n * Requests geolocation permission\n */\n private async requestGeolocationPermission(): Promise<boolean> {\n return new Promise((resolve) => {\n navigator.geolocation.getCurrentPosition(\n () => resolve(true),\n () => resolve(false),\n { timeout: 5000 }\n );\n });\n }\n\n /**\n * Requests notification permission\n */\n private async requestNotificationPermission(): Promise<boolean> {\n if ('Notification' in window) {\n const permission = await Notification.requestPermission();\n return permission === 'granted';\n }\n return false;\n }\n\n /**\n * Takes a photo using the camera\n */\n async takePhoto(options: CameraOptions = {}): Promise<PhotoResult> {\n if (!this.features.get('camera')?.available) {\n throw new Error('Camera not available');\n }\n\n const hasPermission = await this.requestPermission('camera');\n if (!hasPermission) {\n throw new Error('Camera permission denied');\n }\n\n return new Promise((resolve, reject) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = 'image/*';\n input.capture = options.source === 'camera' ? 'camera' : undefined as any;\n\n input.onchange = (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = () => {\n resolve({\n dataUrl: reader.result as string,\n file,\n width: 0, // Would need to load image to get dimensions\n height: 0\n });\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n } else {\n reject(new Error('No file selected'));\n }\n };\n\n input.click();\n });\n }\n\n /**\n * Gets current location\n */\n async getLocation(options: GeolocationOptions = {}): Promise<LocationResult> {\n if (!this.features.get('geolocation')?.available) {\n throw new Error('Geolocation not available');\n }\n\n const hasPermission = await this.requestPermission('geolocation');\n if (!hasPermission) {\n throw new Error('Geolocation permission denied');\n }\n\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n (position) => {\n resolve({\n latitude: position.coords.latitude,\n longitude: position.coords.longitude,\n accuracy: position.coords.accuracy,\n altitude: position.coords.altitude ?? undefined,\n heading: position.coords.heading ?? undefined,\n speed: position.coords.speed ?? undefined,\n timestamp: position.timestamp\n });\n },\n (error) => {\n reject(new Error(`Geolocation error: ${error.message}`));\n },\n {\n enableHighAccuracy: options.highAccuracy || false,\n timeout: options.timeout || 10000,\n maximumAge: options.maximumAge || 60000\n }\n );\n });\n }\n\n /**\n * Sends a notification\n */\n async sendNotification(options: NotificationOptions): Promise<void> {\n if (!this.features.get('notifications')?.available) {\n throw new Error('Notifications not available');\n }\n\n const hasPermission = await this.requestPermission('notifications');\n if (!hasPermission) {\n throw new Error('Notification permission denied');\n }\n\n if ('Notification' in window) {\n new Notification(options.title, options);\n }\n }\n\n /**\n * Gets available features\n */\n getAvailableFeatures(): NativeFeature[] {\n return Array.from(this.features.values());\n }\n\n\n\n /**\n * Updates the configuration\n */\n updateConfig(newConfig: Partial<NativeConfig>): void {\n this.config = { ...this.config, ...newConfig };\n this.initializeFeatures();\n }\n\n /**\n * Gets the current configuration\n */\n getConfig(): NativeConfig {\n return { ...this.config };\n }\n}\n\n// Additional types for native features\nexport interface CameraOptions {\n source?: 'camera' | 'gallery';\n quality?: number;\n maxWidth?: number;\n maxHeight?: number;\n}\n\nexport interface PhotoResult {\n dataUrl: string;\n file: File;\n width: number;\n height: number;\n}\n\nexport interface GeolocationOptions {\n highAccuracy?: boolean;\n timeout?: number;\n maximumAge?: number;\n}\n\nexport interface LocationResult {\n latitude: number;\n longitude: number;\n accuracy: number;\n altitude?: number | undefined;\n heading?: number | undefined;\n speed?: number | undefined;\n timestamp: number;\n}\n\nexport interface NotificationOptions {\n title: string;\n body?: string;\n icon?: string;\n badge?: string;\n tag?: string;\n data?: any;\n requireInteraction?: boolean;\n silent?: boolean;\n vibrate?: number[];\n actions?: NotificationAction[];\n}\n\nexport interface NotificationAction {\n action: string;\n title: string;\n icon?: string;\n}\n"]}