Exemples de Fonctionnalités Mobile Web TypeScript

Exemples de fonctionnalités mobile Web TypeScript incluant les informations sur l'appareil, le statut du réseau et la vibration

Key Facts

Category
TypeScript
Items
3
Format Families
sample

Sample Overview

Exemples de fonctionnalités mobile Web TypeScript incluant les informations sur l'appareil, le statut du réseau et la vibration This sample set belongs to TypeScript and can be used to test related workflows inside Elysia Tools.

💻 Informations sur l'Appareil typescript

🟢 simple ⭐⭐⭐

Obtenir les informations sur l'appareil y compris le type, le système d'exploitation, le navigateur, l'écran et les capacités matérielles

⏱️ 20 min 🏷️ typescript, web, mobile features
Prerequisites: Basic TypeScript, Navigator API, Screen API
// Web TypeScript Device Information Examples
// Using Navigator API and Screen API for device detection

// 1. Device Info Manager
class DeviceInfoManager {
  // Get basic device info
  getDeviceInfo(): {
    userAgent: string;
    platform: string;
    vendor: string;
    language: string;
    cookiesEnabled: boolean;
    onLine: boolean;
    hardwareConcurrency: number;
    deviceMemory: number;
    maxTouchPoints: number;
  } {
    const nav = navigator as any;

    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform,
      vendor: navigator.vendor,
      language: navigator.language,
      cookiesEnabled: navigator.cookieEnabled,
      onLine: navigator.onLine,
      hardwareConcurrency: navigator.hardwareConcurrency || 0,
      deviceMemory: nav.deviceMemory || 0,
      maxTouchPoints: navigator.maxTouchPoints || 0
    };
  }

  // Get device type
  getDeviceType(): 'desktop' | 'mobile' | 'tablet' {
    const userAgent = navigator.userAgent.toLowerCase();
    const maxTouchPoints = navigator.maxTouchPoints || 0;

    // Check for mobile
    const isMobile = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);

    // Check for tablet
    const isTablet = /ipad|android(?!.*mobile)|tablet/i.test(userAgent) ||
                     (maxTouchPoints > 0 && /macintosh/i.test(userAgent));

    if (isTablet) return 'tablet';
    if (isMobile) return 'mobile';
    return 'desktop';
  }

  // Get OS information
  getOSInfo(): {
    name: string;
    version: string;
  } {
    const userAgent = navigator.userAgent;
    let name = 'Unknown';
    let version = 'Unknown';

    if (/windows/i.test(userAgent)) {
      name = 'Windows';
      const match = userAgent.match(/Windows NT (\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/macintosh|mac os x/i.test(userAgent)) {
      name = 'macOS';
      const match = userAgent.match(/Mac OS X (\d+[._]\d+)/);
      if (match) version = match[1].replace(/_/g, '.');
    } else if (/android/i.test(userAgent)) {
      name = 'Android';
      const match = userAgent.match(/Android (\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/iphone|ipad|ipod/i.test(userAgent)) {
      name = 'iOS';
      const match = userAgent.match(/OS (\d+_\d+)/);
      if (match) version = match[1].replace(/_/g, '.');
    } else if (/linux/i.test(userAgent)) {
      name = 'Linux';
    }

    return { name, version };
  }

  // Get browser info
  getBrowserInfo(): {
    name: string;
    version: string;
  } {
    const userAgent = navigator.userAgent;
    let name = 'Unknown';
    let version = 'Unknown';

    if (/chrome/i.test(userAgent) && !/edge|opr/i.test(userAgent)) {
      name = 'Chrome';
      const match = userAgent.match(/Chrome\/(\d+\.\d+\.\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/safari/i.test(userAgent) && !/chrome/i.test(userAgent)) {
      name = 'Safari';
      const match = userAgent.match(/Version\/(\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/firefox/i.test(userAgent)) {
      name = 'Firefox';
      const match = userAgent.match(/Firefox\/(\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/edge/i.test(userAgent)) {
      name = 'Edge';
      const match = userAgent.match(/Edge\/(\d+\.\d+)/);
      if (match) version = match[1];
    } else if (/opr/i.test(userAgent)) {
      name = 'Opera';
      const match = userAgent.match(/OPR\/(\d+\.\d+)/);
      if (match) version = match[1];
    }

    return { name, version };
  }

  // Get screen info
  getScreenInfo(): {
    width: number;
    height: number;
    availWidth: number;
    availHeight: number;
    colorDepth: number;
    pixelDepth: number;
    orientation: string;
    devicePixelRatio: number;
  } {
    const screen = window.screen;
    const orientation = (screen.orientation?.type || 'unknown');

    return {
      width: screen.width,
      height: screen.height,
      availWidth: screen.availWidth,
      availHeight: screen.availHeight,
      colorDepth: screen.colorDepth,
      pixelDepth: screen.pixelDepth,
      orientation,
      devicePixelRatio: window.devicePixelRatio
    };
  }

  // Get viewport info
  getViewportInfo(): {
    width: number;
    height: number;
    scrollX: number;
    scrollY: number;
  } {
    return {
      width: window.innerWidth,
      height: window.innerHeight,
      scrollX: window.scrollX,
      scrollY: window.scrollY
    };
  }

  // Check if touch device
  isTouchDevice(): boolean {
    return 'ontouchstart' in window ||
           navigator.maxTouchPoints > 0 ||
           (navigator as any).msMaxTouchPoints > 0;
  }

  // Check if retina display
  isRetinaDisplay(): boolean {
    return window.devicePixelRatio > 1;
  }

  // Get complete device report
  getCompleteReport(): {
    device: any;
    os: any;
    browser: any;
    screen: any;
    viewport: any;
    capabilities: any;
  } {
    return {
      device: {
        type: this.getDeviceType(),
        info: this.getDeviceInfo()
      },
      os: this.getOSInfo(),
      browser: this.getBrowserInfo(),
      screen: this.getScreenInfo(),
      viewport: this.getViewportInfo(),
      capabilities: {
        touch: this.isTouchDevice(),
        retina: this.isRetinaDisplay(),
        webGL: this.checkWebGL(),
        webWorker: 'Worker' in window,
        serviceWorker: 'serviceWorker' in navigator,
        localStorage: this.checkLocalStorage(),
        sessionStorage: this.checkSessionStorage()
      }
    };
  }

  private checkWebGL(): boolean {
    try {
      const canvas = document.createElement('canvas');
      return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
    } catch {
      return false;
    }
  }

  private checkLocalStorage(): boolean {
    try {
      localStorage.setItem('test', 'test');
      localStorage.removeItem('test');
      return true;
    } catch {
      return false;
    }
  }

  private checkSessionStorage(): boolean {
    try {
      sessionStorage.setItem('test', 'test');
      sessionStorage.removeItem('test');
      return true;
    } catch {
      return false;
    }
  }
}

// 2. Battery Manager
class DeviceBatteryManager {
  private battery: any = null;

  // Initialize battery API
  async initialize(): Promise<void> {
    if ('getBattery' in navigator) {
      this.battery = await (navigator as any).getBattery();
    }
  }

  // Check if battery API is supported
  isSupported(): boolean {
    return 'getBattery' in navigator;
  }

  // Get battery info
  getBatteryInfo(): {
    charging: boolean;
    level: number;
    chargingTime: number;
    dischargingTime: number;
  } | null {
    if (!this.battery) {
      return null;
    }

    return {
      charging: this.battery.charging,
      level: this.battery.level,
      chargingTime: this.battery.chargingTime,
      dischargingTime: this.battery.dischargingTime
    };
  }

  // Add battery change listener
  addChangeListener(callback: (info: any) => void): void {
    if (this.battery) {
      this.battery.addEventListener('levelchange', () => callback(this.getBatteryInfo()));
      this.battery.addEventListener('chargingchange', () => callback(this.getBatteryInfo()));
      this.battery.addEventListener('chargingtimechange', () => callback(this.getBatteryInfo()));
      this.battery.addEventListener('dischargingtimechange', () => callback(this.getBatteryInfo()));
    }
  }
}

// 3. Memory Manager
class MemoryManager {
  // Get memory info (Chrome only)
  getMemoryInfo(): {
    jsHeapSizeLimit: number;
    totalJSHeapSize: number;
    usedJSHeapSize: number;
  } | null {
    const performance = (window as any).performance;
    if (performance && performance.memory) {
      return {
        jsHeapSizeLimit: performance.memory.jsHeapSizeLimit,
        totalJSHeapSize: performance.memory.totalJSHeapSize,
        usedJSHeapSize: performance.memory.usedJSHeapSize
      };
    }
    return null;
  }

  // Get memory usage percentage
  getMemoryUsage(): number | null {
    const memory = this.getMemoryInfo();
    if (!memory) return null;

    return (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100;
  }

  // Format bytes to readable string
  formatBytes(bytes: number): string {
    const mb = bytes / (1024 * 1024);
    return mb.toFixed(2) + ' MB';
  }
}

// 4. Connection Manager
class ConnectionManager {
  // Get connection info
  getConnectionInfo(): {
    effectiveType: string;
    downlink: number;
    rtt: number;
    saveData: boolean;
  } | null {
    const connection = (navigator as any).connection || (navigator as any).mozConnection || (navigator as any).webkitConnection;

    if (!connection) {
      return null;
    }

    return {
      effectiveType: connection.effectiveType || 'unknown',
      downlink: connection.downlink || 0,
      rtt: connection.rtt || 0,
      saveData: connection.saveData || false
    };
  }

  // Check if slow connection
  isSlowConnection(): boolean {
    const info = this.getConnectionInfo();
    if (!info) return false;

    return info.effectiveType === 'slow-2g' || info.effectiveType === '2g';
  }

  // Check if fast connection
  isFastConnection(): boolean {
    const info = this.getConnectionInfo();
    if (!info) return false;

    return info.effectiveType === '4g';
  }
}

// 5. Orientation Manager
class OrientationManager {
  // Get current orientation
  getOrientation(): 'portrait' | 'landscape' {
    return window.innerHeight > window.innerWidth ? 'portrait' : 'landscape';
  }

  // Lock orientation (experimental)
  async lockOrientation(orientation: 'portrait' | 'landscape'): Promise<boolean> {
    try {
      if ((screen.orientation as any).lock) {
        await screen.orientation.lock(orientation);
        return true;
      }
      return false;
    } catch {
      return false;
    }
  }

  // Unlock orientation
  unlockOrientation(): void {
    if ((screen.orientation as any).unlock) {
      screen.orientation.unlock();
    }
  }

  // Add orientation change listener
  addChangeListener(callback: (orientation: 'portrait' | 'landscape') => void): void {
    window.addEventListener('orientationchange', () => {
      callback(this.getOrientation());
    });

    window.addEventListener('resize', () => {
      callback(this.getOrientation());
    });
  }
}

// 6. Device Capability Detector
class DeviceCapabilityDetector {
  // Check for camera support
  async hasCamera(): Promise<boolean> {
    try {
      const devices = await navigator.mediaDevices.enumerateDevices();
      return devices.some(device => device.kind === 'videoinput');
    } catch {
      return false;
    }
  }

  // Check for microphone support
  async hasMicrophone(): Promise<boolean> {
    try {
      const devices = await navigator.mediaDevices.enumerateDevices();
      return devices.some(device => device.kind === 'audioinput');
    } catch {
      return false;
    }
  }

  // Check for geolocation support
  hasGeolocation(): boolean {
    return 'geolocation' in navigator;
  }

  // Check for vibration support
  hasVibration(): boolean {
    return 'vibrate' in navigator;
  }

  // Check for Bluetooth support
  hasBluetooth(): boolean {
    return 'bluetooth' in navigator;
  }

  // Check for USB support
  hasUSB(): boolean {
    return 'usb' in navigator;
  }

  // Get all capabilities
  async getAllCapabilities(): Promise<{
    camera: boolean;
    microphone: boolean;
    geolocation: boolean;
    vibration: boolean;
    bluetooth: boolean;
    usb: boolean;
    touch: boolean;
    webGL: boolean;
  }> {
    return {
      camera: await this.hasCamera(),
      microphone: await this.hasMicrophone(),
      geolocation: this.hasGeolocation(),
      vibration: this.hasVibration(),
      bluetooth: this.hasBluetooth(),
      usb: this.hasUSB(),
      touch: 'ontouchstart' in window,
      webGL: this.checkWebGL()
    };
  }

  private checkWebGL(): boolean {
    try {
      const canvas = document.createElement('canvas');
      return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
    } catch {
      return false;
    }
  }
}

// Usage Examples
async function demonstrateDeviceInfo() {
  console.log('=== Web TypeScript Device Information Examples ===\n');

  const deviceManager = new DeviceInfoManager();
  const batteryManager = new DeviceBatteryManager();
  const memoryManager = new MemoryManager();
  const connectionManager = new ConnectionManager();
  const orientationManager = new OrientationManager();
  const capabilityDetector = new DeviceCapabilityDetector();

  // 1. Basic device info
  console.log('--- 1. Device Info ---');
  const deviceInfo = deviceManager.getDeviceInfo();
  console.log('User Agent:', deviceInfo.userAgent);
  console.log('Platform:', deviceInfo.platform);
  console.log('Device Type:', deviceManager.getDeviceType());

  // 2. OS and browser
  console.log('\n--- 2. OS & Browser ---');
  const osInfo = deviceManager.getOSInfo();
  console.log('OS:', `${osInfo.name} ${osInfo.version}`);

  const browserInfo = deviceManager.getBrowserInfo();
  console.log('Browser:', `${browserInfo.name} ${browserInfo.version}`);

  // 3. Screen info
  console.log('\n--- 3. Screen Info ---');
  const screenInfo = deviceManager.getScreenInfo();
  console.log(`Screen: ${screenInfo.width}x${screenInfo.height}`);
  console.log(`Available: ${screenInfo.availWidth}x${screenInfo.availHeight}`);
  console.log(`Device Pixel Ratio: ${screenInfo.devicePixelRatio}`);

  // 4. Capabilities
  console.log('\n--- 4. Capabilities ---');
  console.log('Touch Device:', deviceManager.isTouchDevice());
  console.log('Retina Display:', deviceManager.isRetinaDisplay());

  // 5. Battery
  console.log('\n--- 5. Battery ---');
  await batteryManager.initialize();
  const batteryInfo = batteryManager.getBatteryInfo();
  if (batteryInfo) {
    console.log(`Battery Level: ${Math.round(batteryInfo.level * 100)}%`);
    console.log(`Charging: ${batteryInfo.charging}`);
  } else {
    console.log('Battery API not supported');
  }

  // 6. Memory
  console.log('\n--- 6. Memory ---');
  const memoryInfo = memoryManager.getMemoryInfo();
  if (memoryInfo) {
    console.log(`Used Memory: ${memoryManager.formatBytes(memoryInfo.usedJSHeapSize)}`);
    console.log(`Memory Limit: ${memoryManager.formatBytes(memoryInfo.jsHeapSizeLimit)}`);
    console.log(`Memory Usage: ${memoryManager.getMemoryUsage()?.toFixed(2)}%`);
  }

  // 7. Connection
  console.log('\n--- 7. Connection ---');
  const connInfo = connectionManager.getConnectionInfo();
  if (connInfo) {
    console.log(`Connection Type: ${connInfo.effectiveType}`);
    console.log(`Downlink: ${connInfo.downlink} Mbps`);
    console.log(`RTT: ${connInfo.rtt} ms`);
  }

  // 8. Capabilities detection
  console.log('\n--- 8. Device Capabilities ---');
  const capabilities = await capabilityDetector.getAllCapabilities();
  console.log('Camera:', capabilities.camera);
  console.log('Microphone:', capabilities.microphone);
  console.log('Geolocation:', capabilities.geolocation);
  console.log('Vibration:', capabilities.vibration);
  console.log('Bluetooth:', capabilities.bluetooth);

  // 9. Complete report
  console.log('\n--- 9. Complete Report ---');
  const report = deviceManager.getCompleteReport();
  console.log(JSON.stringify(report, null, 2));

  console.log('\n=== All Device Information Examples Completed ===');
}

// Export functions
export { DeviceInfoManager, DeviceBatteryManager, MemoryManager, ConnectionManager, OrientationManager, DeviceCapabilityDetector };
export { demonstrateDeviceInfo };

💻 Statut du Réseau typescript

🟢 simple ⭐⭐⭐

Surveiller l'état de la connectivité réseau avec des événements en ligne/hors ligne et la qualité de connexion

⏱️ 20 min 🏷️ typescript, web, mobile features
Prerequisites: Basic TypeScript, Network API, Navigator API
// Web TypeScript Network Status Examples
// Monitoring network connectivity and connection quality

// 1. Network Status Monitor
class NetworkStatusMonitor {
  private isOnline: boolean = navigator.onLine;
  private listeners: Array<(online: boolean) => void> = [];

  constructor() {
    this.initialize();
  }

  // Initialize event listeners
  private initialize(): void {
    window.addEventListener('online', this.handleOnline);
    window.addEventListener('offline', this.handleOffline);
  }

  // Handle online event
  private handleOnline = (): void => {
    this.isOnline = true;
    this.notifyListeners(true);
    console.log('Network status: Online');
  };

  // Handle offline event
  private handleOffline = (): void => {
    this.isOnline = false;
    this.notifyListeners(false);
    console.log('Network status: Offline');
  };

  // Notify all listeners
  private notifyListeners(online: boolean): void {
    this.listeners.forEach(listener => {
      try {
        listener(online);
      } catch (error) {
        console.error('Error in network status listener:', error);
      }
    });
  }

  // Get current status
  isCurrentlyOnline(): boolean {
    return this.isOnline;
  }

  // Add status change listener
  addListener(listener: (online: boolean) => void): void {
    this.listeners.push(listener);
  }

  // Remove status change listener
  removeListener(listener: (online: boolean) => void): void {
    const index = this.listeners.indexOf(listener);
    if (index > -1) {
      this.listeners.splice(index, 1);
    }
  }

  // Cleanup
  destroy(): void {
    window.removeEventListener('online', this.handleOnline);
    window.removeEventListener('offline', this.handleOffline);
    this.listeners = [];
  }
}

// 2. Connection Quality Monitor
class ConnectionQualityMonitor {
  private connection: any = null;
  private listeners: Array<(info: any) => void> = [];

  constructor() {
    this.initialize();
  }

  // Initialize connection monitoring
  private initialize(): void {
    this.connection = (navigator as any).connection ||
                     (navigator as any).mozConnection ||
                     (navigator as any).webkitConnection;

    if (this.connection) {
      this.connection.addEventListener('change', this.handleChange);
    }
  }

  // Handle connection change
  private handleChange = (): void => {
    const info = this.getConnectionInfo();
    this.notifyListeners(info);
    console.log('Connection quality changed:', info);
  };

  // Notify all listeners
  private notifyListeners(info: any): void {
    this.listeners.forEach(listener => {
      try {
        listener(info);
      } catch (error) {
        console.error('Error in connection quality listener:', error);
      }
    });
  }

  // Get connection info
  getConnectionInfo(): {
    effectiveType: string;
    downlink: number;
    rtt: number;
    saveData: boolean;
  } | null {
    if (!this.connection) {
      return null;
    }

    return {
      effectiveType: this.connection.effectiveType || 'unknown',
      downlink: this.connection.downlink || 0,
      rtt: this.connection.rtt || 0,
      saveData: this.connection.saveData || false
    };
  }

  // Check if slow connection
  isSlowConnection(): boolean {
    const info = this.getConnectionInfo();
    if (!info) return false;

    const slowTypes = ['slow-2g', '2g', '3g'];
    return slowTypes.includes(info.effectiveType);
  }

  // Check if fast connection
  isFastConnection(): boolean {
    const info = this.getConnectionInfo();
    if (!info) return false;

    return info.effectiveType === '4g';
  }

  // Get connection quality description
  getQualityDescription(): string {
    const info = this.getConnectionInfo();
    if (!info) return 'Unknown';

    const descriptions: Record<string, string> = {
      'slow-2g': 'Very Slow (2G)',
      '2g': 'Slow (2G)',
      '3g': 'Moderate (3G)',
      '4g': 'Fast (4G)'
    };

    return descriptions[info.effectiveType] || 'Unknown';
  }

  // Add change listener
  addChangeListener(listener: (info: any) => void): void {
    this.listeners.push(listener);
  }

  // Remove change listener
  removeChangeListener(listener: (info: any) => void): void {
    const index = this.listeners.indexOf(listener);
    if (index > -1) {
      this.listeners.splice(index, 1);
    }
  }

  // Cleanup
  destroy(): void {
    if (this.connection) {
      this.connection.removeEventListener('change', this.handleChange);
    }
    this.listeners = [];
  }
}

// 3. Network Speed Tester
class NetworkSpeedTester {
  private testUrl: string;

  constructor(testUrl: string = 'https://www.google.com/favicon.ico') {
    this.testUrl = testUrl;
  }

  // Test download speed
  async testDownloadSpeed(): Promise<{
    speedKbps: number;
    latency: number;
  }> {
    const startTime = performance.now();
    let downloadSize = 0;

    try {
      const response = await fetch(this.testUrl + '?t=' + Date.now());
      const blob = await response.blob();
      downloadSize = blob.size;

      const endTime = performance.now();
      const duration = (endTime - startTime) / 1000; // Convert to seconds
      const speedKbps = ((downloadSize * 8) / duration) / 1000; // Convert to kbps
      const latency = endTime - startTime;

      return { speedKbps, latency };
    } catch (error) {
      console.error('Speed test failed:', error);
      return { speedKbps: 0, latency: 0 };
    }
  }

  // Test latency (ping)
  async testLatency(): Promise<number> {
    const start = performance.now();

    try {
      await fetch(this.testUrl + '?t=' + Date.now(), { method: 'HEAD' });
      return performance.now() - start;
    } catch {
      return -1;
    }
  }

  // Test multiple times and get average
  async testAverage(iterations: number = 3): Promise<{
    avgSpeedKbps: number;
    avgLatency: number;
  }> {
    const speeds: number[] = [];
    const latencies: number[] = [];

    for (let i = 0; i < iterations; i++) {
      const result = await this.testDownloadSpeed();
      speeds.push(result.speedKbps);
      latencies.push(result.latency);

      // Wait a bit between tests
      await new Promise(resolve => setTimeout(resolve, 500));
    }

    const avgSpeedKbps = speeds.reduce((a, b) => a + b, 0) / speeds.length;
    const avgLatency = latencies.reduce((a, b) => a + b, 0) / latencies.length;

    return { avgSpeedKbps, avgLatency };
  }
}

// 4. Offline Manager
class OfflineManager {
  private networkMonitor: NetworkStatusMonitor;
  private offlineQueue: Array<{ url: string; options: RequestInit }> = [];
  private isOfflineMode: boolean = false;

  constructor() {
    this.networkMonitor = new NetworkStatusMonitor();
    this.initialize();
  }

  // Initialize offline manager
  private initialize(): void {
    this.networkMonitor.addListener((online) => {
      this.isOfflineMode = !online;

      if (online) {
        this.syncOfflineRequests();
      }
    });
  }

  // Add request to offline queue
  queueRequest(url: string, options: RequestInit = {}): void {
    this.offlineQueue.push({ url, options });
    console.log(`Request queued: ${url}`);
  }

  // Sync offline requests when back online
  private async syncOfflineRequests(): Promise<void> {
    if (this.offlineQueue.length === 0) {
      return;
    }

    console.log(`Syncing ${this.offlineQueue.length} offline requests...`);

    const queue = [...this.offlineQueue];
    this.offlineQueue = [];

    for (const request of queue) {
      try {
        await fetch(request.url, request.options);
        console.log(`Synced: ${request.url}`);
      } catch (error) {
        console.error(`Failed to sync ${request.url}:`, error);
        // Re-queue failed requests
        this.queueRequest(request.url, request.options);
      }
    }
  }

  // Check if currently in offline mode
  isOffline(): boolean {
    return this.isOfflineMode;
  }

  // Get offline queue size
  getQueueSize(): number {
    return this.offlineQueue.length;
  }

  // Clear offline queue
  clearQueue(): void {
    this.offlineQueue = [];
  }
}

// 5. Network Health Checker
class NetworkHealthChecker {
  private connectionMonitor: ConnectionQualityMonitor;
  private speedTester: NetworkSpeedTester;

  constructor() {
    this.connectionMonitor = new ConnectionQualityMonitor();
    this.speedTester = new NetworkSpeedTester();
  }

  // Get comprehensive health report
  async getHealthReport(): Promise<{
    online: boolean;
    connectionInfo: any;
    speedTest: {
      speedKbps: number;
      latency: number;
    } | null;
    health: 'excellent' | 'good' | 'fair' | 'poor';
  }> {
    const online = navigator.onLine;
    const connectionInfo = this.connectionMonitor.getConnectionInfo();
    let speedTest = null;
    let health: 'excellent' | 'good' | 'fair' | 'poor' = 'poor';

    if (online) {
      speedTest = await this.speedTester.testDownloadSpeed();

      // Determine health based on speed and latency
      if (speedTest.speedKbps > 5000 && speedTest.latency < 50) {
        health = 'excellent';
      } else if (speedTest.speedKbps > 1000 && speedTest.latency < 100) {
        health = 'good';
      } else if (speedTest.speedKbps > 500 && speedTest.latency < 200) {
        health = 'fair';
      } else {
        health = 'poor';
      }
    }

    return {
      online,
      connectionInfo,
      speedTest,
      health
    };
  }

  // Simple health check (quick)
  quickHealthCheck(): {
    online: boolean;
    connectionType: string;
    estimatedQuality: 'good' | 'fair' | 'poor';
  } {
    const online = navigator.onLine;
    const connInfo = this.connectionMonitor.getConnectionInfo();

    let estimatedQuality: 'good' | 'fair' | 'poor' = 'poor';

    if (connInfo) {
      if (connInfo.effectiveType === '4g' && connInfo.downlink >= 10) {
        estimatedQuality = 'good';
      } else if (connInfo.effectiveType === '3g' || connInfo.effectiveType === '4g') {
        estimatedQuality = 'fair';
      }
    }

    return {
      online,
      connectionType: connInfo?.effectiveType || 'unknown',
      estimatedQuality
    };
  }
}

// 6. Network Usage Tracker
class NetworkUsageTracker {
  private requests: Map<string, number> = new Map();

  // Track request
  trackRequest(url: string, size: number): void {
    const current = this.requests.get(url) || 0;
    this.requests.set(url, current + size);
  }

  // Get total usage
  getTotalUsage(): number {
    let total = 0;
    for (const size of this.requests.values()) {
      total += size;
    }
    return total;
  }

  // Get usage by URL pattern
  getUsageByPattern(pattern: RegExp): number {
    let total = 0;
    for (const [url, size] of this.requests) {
      if (pattern.test(url)) {
        total += size;
      }
    }
    return total;
  }

  // Get top consumers
  getTopConsumers(limit: number = 10): Array<{ url: string; size: number }> {
    const consumers = Array.from(this.requests.entries())
      .map(([url, size]) => ({ url, size }))
      .sort((a, b) => b.size - a.size)
      .slice(0, limit);

    return consumers;
  }

  // Clear tracking data
  clear(): void {
    this.requests.clear();
  }

  // Get usage in readable format
  getUsageReport(): {
    totalBytes: number;
    totalMB: number;
    topConsumers: Array<{ url: string; size: number; sizeKB: number }>;
  } {
    const totalBytes = this.getTotalUsage();
    const topConsumers = this.getTopConsumers(10);

    return {
      totalBytes,
      totalMB: totalBytes / (1024 * 1024),
      topConsumers: topConsumers.map(c => ({
        ...c,
        sizeKB: c.size / 1024
      }))
    };
  }
}

// Usage Examples
async function demonstrateNetworkStatus() {
  console.log('=== Web TypeScript Network Status Examples ===\n');

  const networkMonitor = new NetworkStatusMonitor();
  const connectionMonitor = new ConnectionQualityMonitor();
  const speedTester = new NetworkSpeedTester();
  const offlineManager = new OfflineManager();
  const healthChecker = new NetworkHealthChecker();

  // 1. Network status
  console.log('--- 1. Network Status ---');
  console.log('Currently Online:', networkMonitor.isCurrentlyOnline());

  // Add listener
  networkMonitor.addListener((online) => {
    console.log(`Status changed: ${online ? 'Online' : 'Offline'}`);
  });

  // 2. Connection quality
  console.log('\n--- 2. Connection Quality ---');
  const connInfo = connectionMonitor.getConnectionInfo();
  if (connInfo) {
    console.log('Effective Type:', connInfo.effectiveType);
    console.log('Downlink:', connInfo.downlink, 'Mbps');
    console.log('RTT:', connInfo.rtt, 'ms');
    console.log('Quality Description:', connectionMonitor.getQualityDescription());
    console.log('Slow Connection:', connectionMonitor.isSlowConnection());
    console.log('Fast Connection:', connectionMonitor.isFastConnection());
  }

  // 3. Speed test
  console.log('\n--- 3. Speed Test ---');
  const speedResult = await speedTester.testDownloadSpeed();
  console.log(`Speed: ${speedResult.speedKbps.toFixed(2)} kbps`);
  console.log(`Latency: ${speedResult.latency.toFixed(2)} ms`);

  // 4. Average speed test
  console.log('\n--- 4. Average Speed Test ---');
  const avgResult = await speedTester.testAverage(2);
  console.log(`Average Speed: ${avgResult.avgSpeedKbps.toFixed(2)} kbps`);
  console.log(`Average Latency: ${avgResult.avgLatency.toFixed(2)} ms`);

  // 5. Health check
  console.log('\n--- 5. Health Check ---');
  const healthReport = await healthChecker.getHealthReport();
  console.log('Health:', healthReport.health);
  console.log('Online:', healthReport.online);

  // 6. Quick health check
  console.log('\n--- 6. Quick Health Check ---');
  const quickHealth = healthChecker.quickHealthCheck();
  console.log('Quick Health:', quickHealth);

  // 7. Offline manager
  console.log('\n--- 7. Offline Manager ---');
  console.log('Is Offline:', offlineManager.isOffline());
  console.log('Queue Size:', offlineManager.getQueueSize());

  console.log('\n=== All Network Status Examples Completed ===');
}

// Export functions
export { NetworkStatusMonitor, ConnectionQualityMonitor, NetworkSpeedTester, OfflineManager, NetworkHealthChecker, NetworkUsageTracker };
export { demonstrateNetworkStatus };

💻 Vibration typescript

🟢 simple ⭐⭐

Contrôler la vibration de l'appareil pour le retour haptique avec des modèles et un timing

⏱️ 15 min 🏷️ typescript, web, mobile features
Prerequisites: Basic TypeScript, Vibration API
// Web TypeScript Vibration API Examples
// Using Vibration API for haptic feedback

// 1. Vibration Manager
class VibrationManager {
  // Check if vibration is supported
  isSupported(): boolean {
    return 'vibrate' in navigator;
  }

  // Vibrate for specified duration
  vibrate(duration: number): boolean {
    if (!this.isSupported()) {
      console.warn('Vibration API not supported');
      return false;
    }

    return navigator.vibrate(duration);
  }

  // Vibrate with pattern
  vibratePattern(pattern: number[]): boolean {
    if (!this.isSupported()) {
      console.warn('Vibration API not supported');
      return false;
    }

    return navigator.vibrate(pattern);
  }

  // Stop vibration
  stop(): boolean {
    if (!this.isSupported()) {
      return false;
    }

    return navigator.vibrate(0);
  }
}

// 2. Haptic Feedback Patterns
class HapticFeedbackPatterns {
  private vibrate: VibrationManager;

  constructor() {
    this.vibrate = new VibrationManager();
  }

  // Short tap feedback
  tap(): void {
    this.vibrate.vibrate(10);
  }

  // Medium tap feedback
  mediumTap(): void {
    this.vibrate.vibrate(25);
  }

  // Strong tap feedback
  strongTap(): void {
    this.vibrate.vibrate(50);
  }

  // Success feedback
  success(): void {
    this.vibrate.vibratePattern([50, 50, 50]);
  }

  // Error feedback
  error(): void {
    this.vibrate.vibratePattern([100, 50, 100, 50, 100]);
  }

  // Warning feedback
  warning(): void {
    this.vibrate.vibratePattern([50, 100, 50]);
  }

  // Notification feedback
  notification(): void {
    this.vibrate.vibratePattern([100, 50, 100]);
  }

  // Confirmation feedback (ask)
  confirmation(): void {
    this.vibrate.vibratePattern([30, 50, 30]);
  }

  // Heartbeat pattern
  heartbeat(): void {
    this.vibrate.vibratePattern([50, 50, 50, 200, 50, 50, 50, 200]);
  }

  // SOS pattern
  sos(): void {
    this.vibrate.vibratePattern([
      100, 50, 100, 50, 100, 200,
      200, 50, 200, 50, 200, 200,
      100, 50, 100, 50, 100, 200
    ]);
  }

  // Ring pattern
  ring(repeat: boolean = false): void {
    const pattern = [1000, 500];

    if (repeat && this.vibrate.isSupported()) {
      // Note: Continuous vibration needs to be handled carefully
      this.vibrate.vibratePattern(pattern);
    } else {
      this.vibrate.vibratePattern(pattern);
    }
  }

  // Typing feedback
  typing(): void {
    this.vibrate.vibrate(15);
  }

  // Delete feedback
  delete(): void {
    this.vibrate.vibratePattern([50, 30, 50]);
  }

  // Scroll boundary feedback
  scrollBoundary(): void {
    this.vibrate.vibrate(25);
  }

  // Snap feedback
  snap(): void {
    this.vibrate.vibratePattern([20, 30, 40]);
  }

  // Brush feedback
  brush(): void {
    this.vibrate.vibratePattern([10, 20, 10, 20, 10]);
  }
}

// 3. Vibration Sequencer
class VibrationSequencer {
  private vibrate: VibrationManager;
  private sequences: Map<string, number[]> = new Map();

  constructor() {
    this.vibrate = new VibrationManager();
    this.initializeDefaultSequences();
  }

  // Initialize default sequences
  private initializeDefaultSequences(): void {
    this.sequences.set('dot', [30]);
    this.sequences.set('dash', [100]);
    this.sequences.set('dot-dot-dot', [30, 50, 30, 50, 30]);
    this.sequences.set('dash-dash-dash', [100, 50, 100, 50, 100]);
    this.sequences.set('dot-dash', [30, 50, 100]);
    this.sequences.set('dash-dot', [100, 50, 30]);
  }

  // Play sequence by name
  play(name: string): boolean {
    const pattern = this.sequences.get(name);

    if (pattern) {
      return this.vibrate.vibratePattern(pattern);
    }

    return false;
  }

  // Register custom sequence
  registerSequence(name: string, pattern: number[]): void {
    this.sequences.set(name, pattern);
  }

  // Play sequence with delay
  playDelayed(name: string, delay: number): void {
    setTimeout(() => {
      this.play(name);
    }, delay);
  }

  // Play sequences in sequence
  playSequence(names: string[], delay: number = 500): void {
    names.forEach((name, index) => {
      this.playDelayed(name, index * delay);
    });
  }

  // Create rhythm pattern
  createRhythm(beats: string): number[] {
    const pattern: number[] = [];

    for (const char of beats) {
      if (char === '.') {
        pattern.push(30, 50);
      } else if (char === '-') {
        pattern.push(100, 50);
      } else if (char === ' ') {
        pattern.push(0, 200);
      }
    }

    // Remove trailing pause
    if (pattern.length > 0 && pattern[pattern.length - 1] === 0) {
      pattern.pop();
      pattern.pop();
    }

    return pattern;
  }

  // Play rhythm
  playRhythm(beats: string): boolean {
    const pattern = this.createRhythm(beats);
    return this.vibrate.vibratePattern(pattern);
  }
}

// 4. Notification Vibrations
class NotificationVibrations {
  private haptic: HapticFeedbackPatterns;

  constructor() {
    this.haptic = new HapticFeedbackPatterns();
  }

  // New message vibration
  newMessage(): void {
    this.haptic.notification();
  }

  // New email vibration
  newEmail(): void {
    this.haptic.vibratePattern([50, 100, 50, 100, 100, 100, 50, 200]);
  }

  // Calendar reminder
  calendarReminder(): void {
    this.haptic.vibratePattern([100, 50, 100, 50, 100, 200, 200]);
  }

  // Alarm vibration
  alarm(): void {
    // Repeating pattern - would need interval in real implementation
    this.haptic.vibratePattern([500, 200, 500, 200]);
  }

  // Phone call
  phoneCall(): void {
    this.haptic.ring(true);
  }

  // Missed call
  missedCall(): void {
    this.haptic.vibratePattern([100, 100, 100, 100, 100]);
  }
}

// 5. Game Feedback Vibrations
class GameFeedbackVibrations {
  private haptic: HapticFeedbackPatterns;

  constructor() {
    this.haptic = new HapticFeedbackPatterns();
  }

  // Button press
  buttonPress(): void {
    this.haptic.tap();
  }

  // Button hold
  buttonHold(): void {
    this.haptic.vibratePattern([20, 10, 20]);
  }

  // Hit feedback
  hit(light: boolean = false): void {
    if (light) {
      this.haptic.tap();
    } else {
      this.haptic.mediumTap();
    }
  }

  // Critical hit
  criticalHit(): void {
    this.haptic.vibratePattern([50, 30, 100]);
  }

  // Miss feedback
  miss(): void {
    this.haptic.vibrate(15);
  }

  // Explosion
  explosion(): void {
    this.haptic.vibratePattern([200, 50, 100, 50, 50]);
  }

  // Power-up
  powerUp(): void {
    this.haptic.vibratePattern([30, 30, 50, 30, 70, 30, 100, 30, 150]);
  }

  // Level complete
  levelComplete(): void {
    this.haptic.success();
  }

  // Game over
  gameOver(): void {
    this.haptic.error();
  }

  // Achievement unlocked
  achievement(): void {
    this.haptic.vibratePattern([
      50, 50, 50, 50, 50, 50,
      100, 50, 100, 50, 100, 50,
      200
    ]);
  }
}

// 6. Accessibility Vibrations
class AccessibilityVibrations {
  private haptic: HapticFeedbackPatterns;

  constructor() {
    this.haptic = new HapticFeedbackPatterns();
  }

  // Tick sound (for clock, timer)
  tick(): void {
    this.haptic.vibrate(10);
  }

  // Tock sound
  tock(): void {
    this.haptic.vibrate(15);
  }

  // Hour chime
  hourChime(): void {
    this.haptic.vibratePattern([100, 200, 100]);
  }

  // Timer complete
  timerComplete(): void {
    this.haptic.notification();
  }

  // Boundary warning
  boundaryWarning(): void {
    this.haptic.warning();
  }

  // Focus reminder
  focusReminder(): void {
    this.haptic.vibratePattern([30, 100, 30]);
  }

  // Step counter (each step)
  step(): void {
    this.haptic.vibrate(20);
  }

  // Goal reached
  goalReached(): void {
    this.haptic.success();
  }

  // Distance warning (getting closer)
  proximityAlert(level: 1 | 2 | 3): void {
    switch (level) {
      case 1:
        this.haptic.vibrate(20);
        break;
      case 2:
        this.haptic.vibratePattern([30, 100, 30]);
        break;
      case 3:
        this.haptic.vibratePattern([50, 50, 50, 50]);
        break;
    }
  }
}

// 7. Vibration Composer
class VibrationComposer {
  private vibrate: VibrationManager;

  constructor() {
    this.vibrate = new VibrationManager();
  }

  // Compose custom vibration from notes
  compose(notes: Array<{ duration: number; pause?: number }>): void {
    const pattern: number[] = [];

    for (let i = 0; i < notes.length; i++) {
      const note = notes[i];
      pattern.push(note.duration);

      if (i < notes.length - 1) {
        pattern.push(note.pause || 50);
      }
    }

    this.vibrate.vibratePattern(pattern);
  }

  // Compose melody
  composeMelody(notes: number[], tempo: number = 200): void {
    const pattern: number[] = [];

    for (let i = 0; i < notes.length; i++) {
      pattern.push(notes[i]);

      if (i < notes.length - 1) {
        pattern.push(tempo);
      }
    }

    this.vibrate.vibratePattern(pattern);
  }

  // Fade in/out
  fadeIn(maxDuration: number, steps: number = 5): void {
    const pattern: number[] = [];
    const stepDuration = maxDuration / steps;

    for (let i = 1; i <= steps; i++) {
      pattern.push(stepDuration * i, 50);
    }

    this.vibrate.vibratePattern(pattern);
  }

  fadeOut(maxDuration: number, steps: number = 5): void {
    const pattern: number[] = [];
    const stepDuration = maxDuration / steps;

    for (let i = steps; i >= 1; i--) {
      pattern.push(stepDuration * i, 50);
    }

    this.vibrate.vibratePattern(pattern);
  }

  // Ramping vibration
  ramp(startDuration: number, endDuration: number, steps: number = 5): void {
    const pattern: number[] = [];
    const increment = (endDuration - startDuration) / (steps - 1);

    for (let i = 0; i < steps; i++) {
      const duration = startDuration + (increment * i);
      pattern.push(duration, 50);
    }

    this.vibrate.vibratePattern(pattern);
  }
}

// Usage Examples
async function demonstrateVibration() {
  console.log('=== Web TypeScript Vibration API Examples ===\n');

  const vibrationManager = new VibrationManager();
  const hapticPatterns = new HapticFeedbackPatterns();
  const sequencer = new VibrationSequencer();
  const gameFeedback = new GameFeedbackVibrations();
  const composer = new VibrationComposer();

  // 1. Check support
  console.log('--- 1. Vibration Support ---');
  console.log('Vibration Supported:', vibrationManager.isSupported());

  if (!vibrationManager.isSupported()) {
    console.log('Vibration API is not supported on this device');
    return;
  }

  // 2. Basic vibration
  console.log('\n--- 2. Basic Vibration ---');
  console.log('Short vibration...');
  vibrationManager.vibrate(100);
  await new Promise(resolve => setTimeout(resolve, 500));

  // 3. Haptic patterns
  console.log('\n--- 3. Haptic Patterns ---');
  console.log('Success pattern...');
  hapticPatterns.success();
  await new Promise(resolve => setTimeout(resolve, 1000));

  console.log('Error pattern...');
  hapticPatterns.error();
  await new Promise(resolve => setTimeout(resolve, 1000));

  console.log('Warning pattern...');
  hapticPatterns.warning();
  await new Promise(resolve => setTimeout(resolve, 1000));

  // 4. Sequencer
  console.log('\n--- 4. Sequencer ---');
  console.log('SOS pattern...');
  hapticPatterns.sos();
  await new Promise(resolve => setTimeout(resolve, 2000));

  // 5. Game feedback
  console.log('\n--- 5. Game Feedback ---');
  console.log('Hit...');
  gameFeedback.hit();
  await new Promise(resolve => setTimeout(resolve, 300));

  console.log('Critical hit...');
  gameFeedback.criticalHit();
  await new Promise(resolve => setTimeout(resolve, 500));

  console.log('Power up...');
  gameFeedback.powerUp();
  await new Promise(resolve => setTimeout(resolve, 1000));

  // 6. Composer
  console.log('\n--- 6. Vibration Composer ---');
  console.log('Composed melody...');
  composer.composeMelody([100, 150, 200, 150, 100], 150);
  await new Promise(resolve => setTimeout(resolve, 1500));

  console.log('\n=== All Vibration API Examples Completed ===');
}

// Export functions
export { VibrationManager, HapticFeedbackPatterns, VibrationSequencer, NotificationVibrations, GameFeedbackVibrations, AccessibilityVibrations, VibrationComposer };
export { demonstrateVibration };