npm package: @ordojs/mobile
Description: Mobile and PWA support for OrdoJS applications
Author: OrdoJS Team
Latest version: 0.1.0

# @ordojs/mobile

Mobile and PWA support for OrdoJS applications. This package provides comprehensive tools for
building mobile-optimized applications with PWA capabilities, touch gestures, and native device
features.

## Features

- **PWA Support**: Service worker generation, app manifest management, and install prompts
- **Touch Gestures**: Comprehensive gesture recognition (swipe, pinch, rotate, tap, pan)
- **Native Features**: Camera, geolocation, notifications, and device information access
- **Offline Support**: Offline-first data synchronization and caching strategies
- **Mobile Optimization**: Responsive design utilities and mobile-specific components

## Installation

```bash
pnpm add @ordojs/mobile
```

## Usage

### PWA Setup

```typescript
import { PWAManager } from '@ordojs/mobile';

const pwaConfig = {
  name: 'My OrdoJS App',
  shortName: 'OrdoJS',
  description: 'A progressive web app built with OrdoJS',
  startUrl: '/',
  display: 'standalone',
  themeColor: '#ffffff',
  backgroundColor: '#000000',
  icons: [
    {
      src: '/icon-192x192.png',
      sizes: '192x192',
      type: 'image/png',
    },
    {
      src: '/icon-512x512.png',
      sizes: '512x512',
      type: 'image/png',
      purpose: 'maskable',
    },
  ],
  categories: ['productivity'],
  lang: 'en',
  dir: 'ltr',
  orientation: 'portrait',
  scope: '/',
  preferRelatedApplications: false,
  relatedApplications: [],
};

const swConfig = {
  scope: '/',
  updateViaCache: 'imports',
  skipWaiting: true,
  clientsClaim: true,
  offlinePage: '/offline.html',
  cacheStrategies: [
    {
      name: 'static',
      pattern: '/static/*',
      strategy: 'cache-first',
      maxAge: 86400,
    },
    {
      name: 'api',
      pattern: '/api/*',
      strategy: 'network-first',
      maxAge: 300,
    },
  ],
  backgroundSync: {
    enabled: true,
    syncName: 'background-sync',
  },
  pushNotifications: {
    enabled: true,
    defaultNotificationOptions: {
      title: 'New notification',
      body: 'You have a new message',
      icon: '/icon-192x192.png',
    },
  },
};

const pwaManager = new PWAManager(pwaConfig, swConfig);

// Generate manifest
const manifest = pwaManager.generateManifest();
console.log(manifest);

// Generate service worker
const swScript = pwaManager.generateServiceWorker();
console.log(swScript);

// Register service worker
await pwaManager.registerServiceWorker();

// Check if app is installed
if (pwaManager.isInstalled()) {
  console.log('App is installed as PWA');
}

// Show install prompt
try {
  await pwaManager.showInstallPrompt();
} catch (error) {
  console.log('Install prompt not supported');
}
```

### Touch Gestures

```typescript
import { GestureManager } from '@ordojs/mobile';

const element = document.getElementById('gesture-area');
const gestureManager = new GestureManager(element, {
  enabled: true,
  threshold: 10,
  velocity: 0.3,
  direction: 'both',
  preventDefault: true,
});

// Listen for swipe gestures
gestureManager.on('swipe', event => {
  console.log('Swipe detected:', event.direction, event.velocity);

  switch (event.direction) {
    case 'left':
      // Navigate to next page
      break;
    case 'right':
      // Navigate to previous page
      break;
    case 'up':
      // Scroll up
      break;
    case 'down':
      // Scroll down
      break;
  }
});

// Listen for pinch gestures
gestureManager.on('pinch', event => {
  console.log('Pinch detected:', event.scale);
  // Handle zoom in/out
});

// Listen for tap gestures
gestureManager.on('tap', event => {
  console.log('Tap detected');
  // Handle tap action
});

// Listen for long press
gestureManager.on('longpress', event => {
  console.log('Long press detected');
  // Show context menu
});

// Clean up when done
gestureManager.destroy();
```

### Native Features

```typescript
import { NativeManager } from '@ordojs/mobile';

const nativeManager = new NativeManager({
  features: {
    camera: true,
    geolocation: true,
    contacts: true,
    calendar: true,
    notifications: true,
    storage: true,
    network: true,
    device: true,
  },
});

// Get device information
const deviceInfo = await nativeManager.getDeviceInfo();
console.log('Device:', deviceInfo.platform, deviceInfo.model);
console.log('Screen:', deviceInfo.screenWidth, 'x', deviceInfo.screenHeight);
console.log('Battery:', deviceInfo.batteryLevel * 100, '%');

// Take a photo
try {
  const photo = await nativeManager.takePhoto({
    source: 'camera',
    quality: 0.8,
    maxWidth: 1920,
    maxHeight: 1080,
  });
  console.log('Photo taken:', photo.dataUrl);
} catch (error) {
  console.error('Failed to take photo:', error);
}

// Get current location
try {
  const location = await nativeManager.getLocation({
    highAccuracy: true,
    timeout: 10000,
  });
  console.log('Location:', location.latitude, location.longitude);
} catch (error) {
  console.error('Failed to get location:', error);
}

// Send notification
try {
  await nativeManager.sendNotification({
    title: 'Hello from OrdoJS!',
    body: 'This is a test notification',
    icon: '/icon-192x192.png',
    badge: '/badge-72x72.png',
    vibrate: [100, 50, 100],
  });
} catch (error) {
  console.error('Failed to send notification:', error);
}

// Check available features
const features = nativeManager.getAvailableFeatures();
features.forEach(feature => {
  console.log(`${feature.name}: ${feature.available ? 'Available' : 'Not available'}`);
});
```

### Complete Mobile App Setup

```typescript
import { PWAManager, GestureManager, NativeManager } from '@ordojs/mobile';

class MobileApp {
  private pwaManager: PWAManager;
  private gestureManager: GestureManager;
  private nativeManager: NativeManager;

  constructor() {
    // Initialize PWA
    this.pwaManager = new PWAManager(pwaConfig, swConfig);

    // Initialize gestures
    const gestureElement = document.getElementById('app-container');
    this.gestureManager = new GestureManager(gestureElement);

    // Initialize native features
    this.nativeManager = new NativeManager();

    this.setupEventListeners();
  }

  private setupEventListeners(): void {
    // PWA events
    this.pwaManager.registerServiceWorker().then(() => {
      console.log('Service worker registered');
    });

    // Gesture events
    this.gestureManager.on('swipe', this.handleSwipe.bind(this));
    this.gestureManager.on('pinch', this.handlePinch.bind(this));
    this.gestureManager.on('tap', this.handleTap.bind(this));

    // Device events
    window.addEventListener('online', this.handleOnline.bind(this));
    window.addEventListener('offline', this.handleOffline.bind(this));
  }

  private handleSwipe(event: any): void {
    // Handle swipe navigation
  }

  private handlePinch(event: any): void {
    // Handle zoom
  }

  private handleTap(event: any): void {
    // Handle tap
  }

  private handleOnline(): void {
    console.log('Device is online');
    // Sync data
  }

  private handleOffline(): void {
    console.log('Device is offline');
    // Show offline indicator
  }

  async initialize(): Promise<void> {
    // Get device info
    const deviceInfo = await this.nativeManager.getDeviceInfo();

    // Request permissions
    if (deviceInfo.platform !== 'web') {
      await this.requestPermissions();
    }

    console.log('Mobile app initialized');
  }

  private async requestPermissions(): Promise<void> {
    const permissions = ['camera', 'geolocation', 'notifications'];

    for (const permission of permissions) {
      try {
        const granted = await this.nativeManager.requestPermission(permission);
        console.log(`${permission} permission: ${granted ? 'granted' : 'denied'}`);
      } catch (error) {
        console.error(`Failed to request ${permission} permission:`, error);
      }
    }
  }
}

// Initialize the app
const app = new MobileApp();
app.initialize();
```

## API Reference

### PWAManager

#### `generateManifest(): string`

Generates the web app manifest JSON.

#### `generateServiceWorker(): string`

Generates the service worker script.

#### `registerServiceWorker(): Promise<ServiceWorkerRegistration | null>`

Registers the service worker.

#### `isInstalled(): boolean`

Checks if the app is installed as a PWA.

#### `showInstallPrompt(): Promise<void>`

Shows the install prompt.

### GestureManager

#### `on(type: string, listener: (event: GestureEvent) => void): void`

Adds a gesture listener.

#### `off(type: string, listener: (event: GestureEvent) => void): void`

Removes a gesture listener.

#### `destroy(): void`

Destroys the gesture manager.

### NativeManager

#### `getDeviceInfo(): Promise<DeviceInfo>`

Gets device information.

#### `requestPermission(feature: string): Promise<boolean>`

Requests permission for a native feature.

#### `takePhoto(options: CameraOptions): Promise<PhotoResult>`

Takes a photo using the camera.

#### `getLocation(options: GeolocationOptions): Promise<LocationResult>`

Gets current location.

#### `sendNotification(options: NotificationOptions): Promise<void>`

Sends a notification.

#### `getAvailableFeatures(): NativeFeature[]`

Gets available native features.

## Configuration

### PWA Configuration

```typescript
interface PWAConfig {
  name: string;
  shortName: string;
  description: string;
  startUrl: string;
  display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
  themeColor: string;
  backgroundColor: string;
  icons: PWAIcon[];
  categories: string[];
  lang: string;
  dir: 'ltr' | 'rtl';
  orientation: 'portrait' | 'landscape' | 'any';
  scope: string;
  preferRelatedApplications: boolean;
  relatedApplications: RelatedApplication[];
}
```

### Gesture Configuration

```typescript
interface GestureConfig {
  enabled: boolean;
  threshold: number;
  velocity: number;
  direction: 'horizontal' | 'vertical' | 'both';
  preventDefault: boolean;
}
```

### Native Configuration

```typescript
interface NativeConfig {
  features: {
    camera: boolean;
    geolocation: boolean;
    contacts: boolean;
    calendar: boolean;
    notifications: boolean;
    storage: boolean;
    network: boolean;
    device: boolean;
  };
  permissions: PermissionConfig[];
  plugins: PluginConfig[];
}
```

## Examples

### Responsive Mobile Layout

```typescript
import { NativeManager } from '@ordojs/mobile';

const nativeManager = new NativeManager();

// Adapt layout based on device
async function adaptLayout() {
  const deviceInfo = await nativeManager.getDeviceInfo();

  if (deviceInfo.platform === 'ios') {
    // iOS-specific layout
    document.body.classList.add('ios');
  } else if (deviceInfo.platform === 'android') {
    // Android-specific layout
    document.body.classList.add('android');
  }

  // Handle orientation changes
  if (deviceInfo.orientation === 'landscape') {
    document.body.classList.add('landscape');
  } else {
    document.body.classList.add('portrait');
  }
}

adaptLayout();
```

### Offline-First Data Sync

```typescript
import { PWAManager } from '@ordojs/mobile';

const pwaManager = new PWAManager(pwaConfig, {
  ...swConfig,
  backgroundSync: {
    enabled: true,
    syncName: 'data-sync',
    syncOptions: {
      minInterval: 60000, // 1 minute
      maxRetentionTime: 86400000, // 24 hours
    },
  },
});

// Sync data when online
window.addEventListener('online', async () => {
  try {
    await syncData();
    console.log('Data synced successfully');
  } catch (error) {
    console.error('Failed to sync data:', error);
  }
});

async function syncData() {
  // Implement data synchronization logic
  const pendingData = await getPendingData();

  for (const item of pendingData) {
    await sendToServer(item);
    await markAsSynced(item.id);
  }
}
```

## Contributing

This package is part of the OrdoJS ecosystem. Please refer to the main OrdoJS repository for
contribution guidelines.

## License

MIT