Web Mobile Features Python Samples

Web Python mobile-specific features examples including device info, network status, and vibration

💻 Device Information python

🟢 simple ⭐⭐⭐

Get device information including type, OS, browser, screen, and hardware capabilities using Python with JavaScript interop

⏱️ 20 min 🏷️ python, web, mobile features
Prerequisites: Basic Python, Pyodide, JavaScript interop
# Web Python Device Information Examples
# Using JavaScript interop for device detection in browser environment (Pyodide)

import js
from typing import Dict, Any, Optional

# 1. Device Info Manager
class DeviceInfoManager:
    def get_device_info(self) -> Dict[str, Any]:
        """
        Get basic device information from Navigator API

        Returns:
            dict: Device information
        """
        navigator = js.navigator

        return {
            'user_agent': str(navigator.userAgent),
            'platform': str(navigator.platform),
            'vendor': str(navigator.vendor),
            'language': str(navigator.language),
            'cookies_enabled': bool(navigator.cookieEnabled),
            'on_line': bool(navigator.onLine),
            'hardware_concurrency': getattr(navigator, 'hardwareConcurrency', 0),
            'device_memory': getattr(navigator, 'deviceMemory', 0),
            'max_touch_points': getattr(navigator, 'maxTouchPoints', 0)
        }

    def get_device_type(self) -> str:
        """
        Determine device type (desktop, mobile, tablet)

        Returns:
            str: Device type
        """
        user_agent = js.navigator.userAgent.lower()
        max_touch_points = getattr(js.navigator, 'maxTouchPoints', 0)

        # Check for mobile
        is_mobile = any(keyword in user_agent for keyword in
                       ['android', 'iphone', 'ipod', 'blackberry', 'iemobile', 'opera mini'])

        # Check for tablet
        is_tablet = (any(keyword in user_agent for keyword in ['ipad', 'android', 'tablet']) or
                     (max_touch_points > 0 and 'macintosh' in user_agent))

        if is_tablet:
            return 'tablet'
        elif is_mobile:
            return 'mobile'
        else:
            return 'desktop'

    def get_os_info(self) -> Dict[str, str]:
        """
        Get operating system information

        Returns:
            dict: OS name and version
        """
        user_agent = str(js.navigator.userAgent)
        name = 'Unknown'
        version = 'Unknown'

        if 'windows' in user_agent.lower():
            name = 'Windows'
            import re
            match = re.search(r'Windows NT (\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif 'macintosh' in user_agent.lower() or 'mac os x' in user_agent.lower():
            name = 'macOS'
            import re
            match = re.search(r'Mac OS X (\d+[._]\d+)', user_agent)
            if match:
                version = match.group(1).replace('_', '.')
        elif 'android' in user_agent.lower():
            name = 'Android'
            import re
            match = re.search(r'Android (\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif any(keyword in user_agent for keyword in ['iphone', 'ipad', 'ipod']):
            name = 'iOS'
            import re
            match = re.search(r'OS (\d+_\d+)', user_agent)
            if match:
                version = match.group(1).replace('_', '.')
        elif 'linux' in user_agent.lower():
            name = 'Linux'

        return {'name': name, 'version': version}

    def get_browser_info(self) -> Dict[str, str]:
        """
        Get browser information

        Returns:
            dict: Browser name and version
        """
        user_agent = str(js.navigator.userAgent)
        name = 'Unknown'
        version = 'Unknown'

        if 'chrome' in user_agent.lower() and 'edge' not in user_agent.lower() and 'opr' not in user_agent.lower():
            name = 'Chrome'
            import re
            match = re.search(r'Chrome\/(\d+\.\d+\.\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif 'safari' in user_agent.lower() and 'chrome' not in user_agent.lower():
            name = 'Safari'
            import re
            match = re.search(r'Version\/(\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif 'firefox' in user_agent.lower():
            name = 'Firefox'
            import re
            match = re.search(r'Firefox\/(\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif 'edge' in user_agent.lower():
            name = 'Edge'
            import re
            match = re.search(r'Edge\/(\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)
        elif 'opr' in user_agent.lower():
            name = 'Opera'
            import re
            match = re.search(r'OPR\/(\d+\.\d+)', user_agent)
            if match:
                version = match.group(1)

        return {'name': name, 'version': version}

    def get_screen_info(self) -> Dict[str, Any]:
        """
        Get screen information

        Returns:
            dict: Screen dimensions and properties
        """
        screen = js.screen
        window = js.window

        orientation = getattr(screen.orientation, 'type', 'unknown') if hasattr(screen, 'orientation') else 'unknown'

        return {
            'width': screen.width,
            'height': screen.height,
            'avail_width': screen.availWidth,
            'avail_height': screen.availHeight,
            'color_depth': screen.colorDepth,
            'pixel_depth': screen.pixelDepth,
            'orientation': str(orientation),
            'device_pixel_ratio': window.devicePixelRatio
        }

    def get_viewport_info(self) -> Dict[str, int]:
        """
        Get viewport information

        Returns:
            dict: Viewport dimensions and scroll position
        """
        window = js.window

        return {
            'width': window.innerWidth,
            'height': window.innerHeight,
            'scroll_x': window.scrollX,
            'scroll_y': window.scrollY
        }

    def is_touch_device(self) -> bool:
        """
        Check if device supports touch

        Returns:
            bool: True if touch is supported
        """
        return 'ontouchstart' in dir(js.window) or getattr(js.navigator, 'maxTouchPoints', 0) > 0

    def is_retina_display(self) -> bool:
        """
        Check if device has retina display

        Returns:
            bool: True if retina display
        """
        return js.window.devicePixelRatio > 1

    def check_webgl(self) -> bool:
        """
        Check if WebGL is supported

        Returns:
            bool: True if WebGL is supported
        """
        try:
            canvas = js.document.createElement('canvas')
            return bool(canvas.getContext('webgl') or canvas.getContext('experimental-webgl'))
        except:
            return False

    def get_complete_report(self) -> Dict[str, Any]:
        """
        Get complete device report

        Returns:
            dict: Complete device information
        """
        return {
            'device': {
                'type': self.get_device_type(),
                'info': self.get_device_info()
            },
            'os': self.get_os_info(),
            'browser': self.get_browser_info(),
            'screen': self.get_screen_info(),
            'viewport': self.get_viewport_info(),
            'capabilities': {
                'touch': self.is_touch_device(),
                'retina': self.is_retina_display(),
                'webgl': self.check_webgl(),
                'local_storage': self.check_local_storage(),
                'session_storage': self.check_session_storage()
            }
        }

    def check_local_storage(self) -> bool:
        """Check if localStorage is available"""
        try:
            js.window.localStorage.setItem('test', 'test')
            js.window.localStorage.removeItem('test')
            return True
        except:
            return False

    def check_session_storage(self) -> bool:
        """Check if sessionStorage is available"""
        try:
            js.window.sessionStorage.setItem('test', 'test')
            js.window.sessionStorage.removeItem('test')
            return True
        except:
            return False


# 2. Battery Manager
class BatteryManager:
    def __init__(self):
        self.battery = None

    async def initialize(self):
        """Initialize battery API"""
        if hasattr(js.navigator, 'getBattery'):
            self.battery = await js.navigator.getBattery()

    def is_supported(self) -> bool:
        """Check if battery API is supported"""
        return hasattr(js.navigator, 'getBattery')

    def get_battery_info(self) -> Optional[Dict[str, Any]]:
        """
        Get battery information

        Returns:
            dict or None: Battery information if available
        """
        if not self.battery:
            return None

        return {
            'charging': bool(self.battery.charging),
            'level': float(self.battery.level),
            'charging_time': float(self.battery.chargingTime),
            'discharging_time': float(self.battery.dischargingTime)
        }


# 3. Connection Manager
class ConnectionManager:
    def get_connection_info(self) -> Optional[Dict[str, Any]]:
        """
        Get connection information

        Returns:
            dict or None: Connection information if available
        """
        connection = getattr(js.navigator, 'connection', None) or                      getattr(js.navigator, 'mozConnection', None) or                      getattr(js.navigator, 'webkitConnection', None)

        if not connection:
            return None

        return {
            'effective_type': str(getattr(connection, 'effectiveType', 'unknown')),
            'downlink': float(getattr(connection, 'downlink', 0)),
            'rtt': int(getattr(connection, 'rtt', 0)),
            'save_data': bool(getattr(connection, 'saveData', False))
        }

    def is_slow_connection(self) -> bool:
        """Check if connection is slow"""
        info = self.get_connection_info()
        if not info:
            return False
        return info['effective_type'] in ['slow-2g', '2g']

    def is_fast_connection(self) -> bool:
        """Check if connection is fast"""
        info = self.get_connection_info()
        if not info:
            return False
        return info['effective_type'] == '4g'


# 4. Orientation Manager
class OrientationManager:
    def get_orientation(self) -> str:
        """
        Get current orientation

        Returns:
            str: 'portrait' or 'landscape'
        """
        window = js.window
        return 'portrait' if window.innerHeight > window.innerWidth else 'landscape'


# 5. Device Capability Detector
class DeviceCapabilityDetector:
    async def has_camera(self) -> bool:
        """Check if camera is available"""
        try:
            devices = await js.navigator.mediaDevices.enumerateDevices()
            return any(d.kind == 'videoinput' for d in devices)
        except:
            return False

    async def has_microphone(self) -> bool:
        """Check if microphone is available"""
        try:
            devices = await js.navigator.mediaDevices.enumerateDevices()
            return any(d.kind == 'audioinput' for d in devices)
        except:
            return False

    def has_geolocation(self) -> bool:
        """Check if geolocation is available"""
        return 'geolocation' in dir(js.navigator)

    def has_vibration(self) -> bool:
        """Check if vibration is supported"""
        return 'vibrate' in dir(js.navigator)

    def has_bluetooth(self) -> bool:
        """Check if bluetooth is available"""
        return 'bluetooth' in dir(js.navigator)

    def has_usb(self) -> bool:
        """Check if USB is available"""
        return 'usb' in dir(js.navigator)


# Usage Examples
async def demonstrate_device_info():
    print("=== Web Python Device Information Examples ===\n")

    device_manager = DeviceInfoManager()
    battery_manager = BatteryManager()
    connection_manager = ConnectionManager()
    orientation_manager = OrientationManager()
    capability_detector = DeviceCapabilityDetector()

    # 1. Basic device info
    print("--- 1. Device Info ---")
    device_info = device_manager.get_device_info()
    print(f"User Agent: {device_info['user_agent']}")
    print(f"Platform: {device_info['platform']}")
    print(f"Device Type: {device_manager.get_device_type()}")

    # 2. OS and browser
    print("\n--- 2. OS & Browser ---")
    os_info = device_manager.get_os_info()
    print(f"OS: {os_info['name']} {os_info['version']}")

    browser_info = device_manager.get_browser_info()
    print(f"Browser: {browser_info['name']} {browser_info['version']}")

    # 3. Screen info
    print("\n--- 3. Screen Info ---")
    screen_info = device_manager.get_screen_info()
    print(f"Screen: {screen_info['width']}x{screen_info['height']}")
    print(f"Available: {screen_info['avail_width']}x{screen_info['avail_height']}")
    print(f"Device Pixel Ratio: {screen_info['device_pixel_ratio']}")

    # 4. Capabilities
    print("\n--- 4. Capabilities ---")
    print(f"Touch Device: {device_manager.is_touch_device()}")
    print(f"Retina Display: {device_manager.is_retina_display()}")

    # 5. Battery
    print("\n--- 5. Battery ---")
    await battery_manager.initialize()
    battery_info = battery_manager.get_battery_info()
    if battery_info:
        print(f"Battery Level: {int(battery_info['level'] * 100)}%")
        print(f"Charging: {battery_info['charging']}")
    else:
        print("Battery API not supported")

    # 6. Connection
    print("\n--- 6. Connection ---")
    conn_info = connection_manager.get_connection_info()
    if conn_info:
        print(f"Connection Type: {conn_info['effective_type']}")
        print(f"Downlink: {conn_info['downlink']} Mbps")
        print(f"RTT: {conn_info['rtt']} ms")

    # 7. Capabilities detection
    print("\n--- 7. Device Capabilities ---")
    print(f"Camera: {await capability_detector.has_camera()}")
    print(f"Microphone: {await capability_detector.has_microphone()}")
    print(f"Geolocation: {capability_detector.has_geolocation()}")
    print(f"Vibration: {capability_detector.has_vibration()}")
    print(f"Bluetooth: {capability_detector.has_bluetooth()}")

    # 8. Complete report
    print("\n--- 8. Complete Report ---")
    report = device_manager.get_complete_report()
    print(str(report))

    print("\n=== All Device Information Examples Completed ===")

# Export functions
export = {
    'DeviceInfoManager': DeviceInfoManager,
    'BatteryManager': BatteryManager,
    'ConnectionManager': ConnectionManager,
    'OrientationManager': OrientationManager,
    'DeviceCapabilityDetector': DeviceCapabilityDetector,
    'demonstrate_device_info': demonstrate_device_info
}

💻 Network Status python

🟢 simple ⭐⭐⭐

Monitor network connectivity status with online/offline events and connection quality

⏱️ 20 min 🏷️ python, web, mobile features
Prerequisites: Basic Python, Pyodide, Network API
# Web Python Network Status Examples
# Monitoring network connectivity and connection quality

import js
from typing import Dict, Any, Callable, Optional

# 1. Network Status Monitor
class NetworkStatusMonitor:
    def __init__(self):
        self.is_online = bool(js.navigator.onLine)
        self.listeners = []

    def _handle_online(self):
        """Handle online event"""
        self.is_online = True
        self._notify_listeners(True)
        print("Network status: Online")

    def _handle_offline(self):
        """Handle offline event"""
        self.is_online = False
        self._notify_listeners(False)
        print("Network status: Offline")

    def _notify_listeners(self, online: bool):
        """Notify all listeners"""
        for listener in self.listeners:
            try:
                listener(online)
            except Exception as error:
                print(f"Error in network status listener: {error}")

    def is_currently_online(self) -> bool:
        """
        Get current online status

        Returns:
            bool: True if online
        """
        return self.is_online

    def add_listener(self, listener: Callable[[bool], None]):
        """
        Add status change listener

        Args:
            listener: Callback function
        """
        self.listeners.append(listener)

    def remove_listener(self, listener: Callable[[bool], None]):
        """
        Remove status change listener

        Args:
            listener: Callback function to remove
        """
        if listener in self.listeners:
            self.listeners.remove(listener)

    def initialize(self):
        """Initialize event listeners"""
        # Note: In Pyodide, you'd need to set up JavaScript event handlers
        # This is a simplified version
        pass


# 2. Connection Quality Monitor
class ConnectionQualityMonitor:
    def __init__(self):
        self.connection = getattr(js.navigator, 'connection', None) or                           getattr(js.navigator, 'mozConnection', None) or                           getattr(js.navigator, 'webkitConnection', None)
        self.listeners = []

    def get_connection_info(self) -> Optional[Dict[str, Any]]:
        """
        Get connection information

        Returns:
            dict or None: Connection info
        """
        if not self.connection:
            return None

        return {
            'effective_type': str(getattr(self.connection, 'effectiveType', 'unknown')),
            'downlink': float(getattr(self.connection, 'downlink', 0)),
            'rtt': int(getattr(self.connection, 'rtt', 0)),
            'save_data': bool(getattr(self.connection, 'saveData', False))
        }

    def is_slow_connection(self) -> bool:
        """
        Check if connection is slow

        Returns:
            bool: True if slow connection
        """
        info = self.get_connection_info()
        if not info:
            return False
        return info['effective_type'] in ['slow-2g', '2g', '3g']

    def is_fast_connection(self) -> bool:
        """
        Check if connection is fast

        Returns:
            bool: True if fast connection
        """
        info = self.get_connection_info()
        if not info:
            return False
        return info['effective_type'] == '4g'

    def get_quality_description(self) -> str:
        """
        Get connection quality description

        Returns:
            str: Quality description
        """
        info = self.get_connection_info()
        if not info:
            return 'Unknown'

        descriptions = {
            'slow-2g': 'Very Slow (2G)',
            '2g': 'Slow (2G)',
            '3g': 'Moderate (3G)',
            '4g': 'Fast (4G)'
        }

        return descriptions.get(info['effective_type'], 'Unknown')


# 3. Network Speed Tester
class NetworkSpeedTester:
    def __init__(self, test_url: str = 'https://www.google.com/favicon.ico'):
        self.test_url = test_url

    async def test_download_speed(self) -> Dict[str, float]:
        """
        Test download speed

        Returns:
            dict: Speed and latency in kbps and ms
        """
        import time
        start_time = time.time()

        try:
            response = await js.fetch(f"{self.test_url}?t={int(time.time() * 1000)}")
            blob = await response.blob()
            download_size = blob.size

            end_time = time.time()
            duration = end_time - start_time
            speed_kbps = ((download_size * 8) / duration) / 1000
            latency = (end_time - start_time) * 1000

            return {
                'speed_kbps': speed_kbps,
                'latency': latency
            }
        except Exception as error:
            print(f"Speed test failed: {error}")
            return {'speed_kbps': 0, 'latency': 0}

    async def test_latency(self) -> float:
        """
        Test latency (ping)

        Returns:
            float: Latency in ms
        """
        import time
        start = time.time()

        try:
            await js.fetch(f"{self.test_url}?t={int(time.time() * 1000)}", method='HEAD')
            return (time.time() - start) * 1000
        except:
            return -1

    async def test_average(self, iterations: int = 3) -> Dict[str, float]:
        """
        Test multiple times and get average

        Args:
            iterations: Number of test iterations

        Returns:
            dict: Average speed and latency
        """
        import time
        speeds = []
        latencies = []

        for i in range(iterations):
            result = await self.test_download_speed()
            speeds.append(result['speed_kbps'])
            latencies.append(result['latency'])

            # Wait between tests
            await asyncio(0.5)

        avg_speed_kbps = sum(speeds) / len(speeds)
        avg_latency = sum(latencies) / len(latencies)

        return {
            'avg_speed_kbps': avg_speed_kbps,
            'avg_latency': avg_latency
        }


# 4. Offline Manager
class OfflineManager:
    def __init__(self):
        self.network_monitor = NetworkStatusMonitor()
        self.offline_queue = []
        self.is_offline_mode = False

    def queue_request(self, url: str, options: Dict = None):
        """
        Add request to offline queue

        Args:
            url: Request URL
            options: Request options
        """
        self.offline_queue.append({'url': url, 'options': options or {}})
        print(f"Request queued: {url}")

    async def sync_offline_requests(self):
        """Sync offline requests when back online"""
        if not self.offline_queue:
            return

        print(f"Syncing {len(self.offline_queue)} offline requests...")

        queue = self.offline_queue.copy()
        self.offline_queue = []

        for request in queue:
            try:
                await js.fetch(request['url'], **request['options'])
                print(f"Synced: {request['url']}")
            except Exception as error:
                print(f"Failed to sync {request['url']}: {error}")
                # Re-queue failed requests
                self.queue_request(request['url'], request['options'])

    def is_offline(self) -> bool:
        """Check if currently in offline mode"""
        return self.is_offline_mode

    def get_queue_size(self) -> int:
        """Get offline queue size"""
        return len(self.offline_queue)

    def clear_queue(self):
        """Clear offline queue"""
        self.offline_queue = []


# 5. Network Health Checker
class NetworkHealthChecker:
    def __init__(self):
        self.connection_monitor = ConnectionQualityMonitor()
        self.speed_tester = NetworkSpeedTester()

    async def get_health_report(self) -> Dict[str, Any]:
        """
        Get comprehensive health report

        Returns:
            dict: Health report
        """
        online = bool(js.navigator.onLine)
        connection_info = self.connection_monitor.get_connection_info()
        speed_test = None
        health = 'poor'

        if online:
            speed_test = await self.speed_tester.test_download_speed()

            # Determine health based on speed and latency
            if speed_test['speed_kbps'] > 5000 and speed_test['latency'] < 50:
                health = 'excellent'
            elif speed_test['speed_kbps'] > 1000 and speed_test['latency'] < 100:
                health = 'good'
            elif speed_test['speed_kbps'] > 500 and speed_test['latency'] < 200:
                health = 'fair'
            else:
                health = 'poor'

        return {
            'online': online,
            'connection_info': connection_info,
            'speed_test': speed_test,
            'health': health
        }

    def quick_health_check(self) -> Dict[str, Any]:
        """
        Simple health check (quick)

        Returns:
            dict: Quick health status
        """
        online = bool(js.navigator.onLine)
        conn_info = self.connection_monitor.get_connection_info()

        estimated_quality = 'poor'
        if conn_info:
            if conn_info['effective_type'] == '4g' and conn_info['downlink'] >= 10:
                estimated_quality = 'good'
            elif conn_info['effective_type'] in ['3g', '4g']:
                estimated_quality = 'fair'

        return {
            'online': online,
            'connection_type': conn_info['effective_type'] if conn_info else 'unknown',
            'estimated_quality': estimated_quality
        }


# Helper function for asyncio
async def asyncio(delay: float):
    """Simple delay helper"""
    import asyncio
    await asyncio.sleep(delay)


# Usage Examples
async def demonstrate_network_status():
    print("=== Web Python Network Status Examples ===\n")

    network_monitor = NetworkStatusMonitor()
    connection_monitor = ConnectionQualityMonitor()
    speed_tester = NetworkSpeedTester()
    offline_manager = OfflineManager()
    health_checker = NetworkHealthChecker()

    # 1. Network status
    print("--- 1. Network Status ---")
    print(f"Currently Online: {network_monitor.is_currently_online()}")

    # 2. Connection quality
    print("\n--- 2. Connection Quality ---")
    conn_info = connection_monitor.get_connection_info()
    if conn_info:
        print(f"Effective Type: {conn_info['effective_type']}")
        print(f"Downlink: {conn_info['downlink']} Mbps")
        print(f"RTT: {conn_info['rtt']} ms")
        print(f"Quality Description: {connection_monitor.get_quality_description()}")
        print(f"Slow Connection: {connection_monitor.is_slow_connection()}")
        print(f"Fast Connection: {connection_monitor.is_fast_connection()}")

    # 3. Speed test
    print("\n--- 3. Speed Test ---")
    speed_result = await speed_tester.test_download_speed()
    print(f"Speed: {speed_result['speed_kbps']:.2f} kbps")
    print(f"Latency: {speed_result['latency']:.2f} ms")

    # 4. Average speed test
    print("\n--- 4. Average Speed Test ---")
    avg_result = await speed_tester.test_average(2)
    print(f"Average Speed: {avg_result['avg_speed_kbps']:.2f} kbps")
    print(f"Average Latency: {avg_result['avg_latency']:.2f} ms")

    # 5. Health check
    print("\n--- 5. Health Check ---")
    health_report = await health_checker.get_health_report()
    print(f"Health: {health_report['health']}")
    print(f"Online: {health_report['online']}")

    # 6. Quick health check
    print("\n--- 6. Quick Health Check ---")
    quick_health = health_checker.quick_health_check()
    print(f"Quick Health: {quick_health}")

    # 7. Offline manager
    print("\n--- 7. Offline Manager ---")
    print(f"Is Offline: {offline_manager.is_offline()}")
    print(f"Queue Size: {offline_manager.get_queue_size()}")

    print("\n=== All Network Status Examples Completed ===")

# Export functions
export = {
    'NetworkStatusMonitor': NetworkStatusMonitor,
    'ConnectionQualityMonitor': ConnectionQualityMonitor,
    'NetworkSpeedTester': NetworkSpeedTester,
    'OfflineManager': OfflineManager,
    'NetworkHealthChecker': NetworkHealthChecker,
    'demonstrate_network_status': demonstrate_network_status
}

💻 Vibration API python

🟢 simple ⭐⭐

Control device vibration for haptic feedback with patterns and timing

⏱️ 15 min 🏷️ python, web, mobile features
Prerequisites: Basic Python, Vibration API, JavaScript interop
# Web Python Vibration API Examples
# Using Vibration API for haptic feedback with JavaScript interop

import js
from typing import List, Dict, Any

# 1. Vibration Manager
class VibrationManager:
    def is_supported(self) -> bool:
        """
        Check if vibration is supported

        Returns:
            bool: True if supported
        """
        return hasattr(js.navigator, 'vibrate')

    def vibrate(self, duration: int) -> bool:
        """
        Vibrate for specified duration

        Args:
            duration: Duration in milliseconds

        Returns:
            bool: True if successful
        """
        if not self.is_supported():
            print("Vibration API not supported")
            return False

        return bool(js.navigator.vibrate(duration))

    def vibrate_pattern(self, pattern: List[int]) -> bool:
        """
        Vibrate with pattern

        Args:
            pattern: List of vibration durations (vibrate, pause, vibrate, ...)

        Returns:
            bool: True if successful
        """
        if not self.is_supported():
            print("Vibration API not supported")
            return False

        return bool(js.navigator.vibrate(pattern))

    def stop(self) -> bool:
        """
        Stop vibration

        Returns:
            bool: True if successful
        """
        if not self.is_supported():
            return False

        return bool(js.navigator.vibrate(0))


# 2. Haptic Feedback Patterns
class HapticFeedbackPatterns:
    def __init__(self):
        self.vibrate = VibrationManager()

    def tap(self):
        """Short tap feedback"""
        self.vibrate.vibrate(10)

    def medium_tap(self):
        """Medium tap feedback"""
        self.vibrate.vibrate(25)

    def strong_tap(self):
        """Strong tap feedback"""
        self.vibrate.vibrate(50)

    def success(self):
        """Success feedback"""
        self.vibrate.vibrate_pattern([50, 50, 50])

    def error(self):
        """Error feedback"""
        self.vibrate.vibrate_pattern([100, 50, 100, 50, 100])

    def warning(self):
        """Warning feedback"""
        self.vibrate.vibrate_pattern([50, 100, 50])

    def notification(self):
        """Notification feedback"""
        self.vibrate.vibrate_pattern([100, 50, 100])

    def confirmation(self):
        """Confirmation feedback (ask)"""
        self.vibrate.vibrate_pattern([30, 50, 30])

    def heartbeat(self):
        """Heartbeat pattern"""
        self.vibrate.vibrate_pattern([50, 50, 50, 200, 50, 50, 50, 200])

    def sos(self):
        """SOS pattern"""
        self.vibrate.vibrate_pattern([
            100, 50, 100, 50, 100, 200,
            200, 50, 200, 50, 200, 200,
            100, 50, 100, 50, 100, 200
        ])

    def ring(self, repeat: bool = False):
        """Ring pattern"""
        pattern = [1000, 500]
        self.vibrate.vibrate_pattern(pattern)

    def typing(self):
        """Typing feedback"""
        self.vibrate.vibrate(15)

    def delete(self):
        """Delete feedback"""
        self.vibrate.vibrate_pattern([50, 30, 50])

    def scroll_boundary(self):
        """Scroll boundary feedback"""
        self.vibrate.vibrate(25)

    def snap(self):
        """Snap feedback"""
        self.vibrate.vibrate_pattern([20, 30, 40])

    def brush(self):
        """Brush feedback"""
        self.vibrate.vibrate_pattern([10, 20, 10, 20, 10])


# 3. Vibration Sequencer
class VibrationSequencer:
    def __init__(self):
        self.vibrate = VibrationManager()
        self.sequences = {
            'dot': [30],
            'dash': [100],
            'dot-dot-dot': [30, 50, 30, 50, 30],
            'dash-dash-dash': [100, 50, 100, 50, 100],
            'dot-dash': [30, 50, 100],
            'dash-dot': [100, 50, 30]
        }

    def play(self, name: str) -> bool:
        """
        Play sequence by name

        Args:
            name: Sequence name

        Returns:
            bool: True if successful
        """
        pattern = self.sequences.get(name)
        if pattern:
            return self.vibrate.vibrate_pattern(pattern)
        return False

    def register_sequence(self, name: str, pattern: List[int]):
        """
        Register custom sequence

        Args:
            name: Sequence name
            pattern: Vibration pattern
        """
        self.sequences[name] = pattern

    def create_rhythm(self, beats: str) -> List[int]:
        """
        Create rhythm pattern from beat string

        Args:
            beats: Beat string (.=short, -=long, space=pause)

        Returns:
            list: Vibration pattern
        """
        pattern = []

        for char in beats:
            if char == '.':
                pattern.extend([30, 50])
            elif char == '-':
                pattern.extend([100, 50])
            elif char == ' ':
                pattern.extend([0, 200])

        # Remove trailing pause
        if len(pattern) > 1 and pattern[-1] == 0:
            pattern.pop()
            pattern.pop()

        return pattern

    def play_rhythm(self, beats: str) -> bool:
        """
        Play rhythm

        Args:
            beats: Beat string

        Returns:
            bool: True if successful
        """
        pattern = self.create_rhythm(beats)
        return self.vibrate.vibrate_pattern(pattern)


# 4. Notification Vibrations
class NotificationVibrations:
    def __init__(self):
        self.haptic = HapticFeedbackPatterns()

    def new_message(self):
        """New message vibration"""
        self.haptic.notification()

    def new_email(self):
        """New email vibration"""
        self.haptic.vibrate.vibrate_pattern([50, 100, 50, 100, 100, 100, 50, 200])

    def calendar_reminder(self):
        """Calendar reminder"""
        self.haptic.vibrate.vibrate_pattern([100, 50, 100, 50, 100, 200, 200])

    def alarm(self):
        """Alarm vibration"""
        self.haptic.vibrate.vibrate_pattern([500, 200, 500, 200])

    def phone_call(self):
        """Phone call"""
        self.haptic.ring()

    def missed_call(self):
        """Missed call"""
        self.haptic.vibrate.vibrate_pattern([100, 100, 100, 100, 100])


# 5. Game Feedback Vibrations
class GameFeedbackVibrations:
    def __init__(self):
        self.haptic = HapticFeedbackPatterns()

    def button_press(self):
        """Button press"""
        self.haptic.tap()

    def button_hold(self):
        """Button hold"""
        self.haptic.vibrate.vibrate_pattern([20, 10, 20])

    def hit(self, light: bool = False):
        """Hit feedback"""
        if light:
            self.haptic.tap()
        else:
            self.haptic.medium_tap()

    def critical_hit(self):
        """Critical hit"""
        self.haptic.vibrate.vibrate_pattern([50, 30, 100])

    def miss(self):
        """Miss feedback"""
        self.haptic.vibrate.vibrate(15)

    def explosion(self):
        """Explosion"""
        self.haptic.vibrate.vibrate_pattern([200, 50, 100, 50, 50])

    def power_up(self):
        """Power up"""
        self.haptic.vibrate.vibrate_pattern([30, 30, 50, 30, 70, 30, 100, 30, 150])

    def level_complete(self):
        """Level complete"""
        self.haptic.success()

    def game_over(self):
        """Game over"""
        self.haptic.error()

    def achievement(self):
        """Achievement unlocked"""
        self.haptic.vibrate.vibrate_pattern([
            50, 50, 50, 50, 50, 50,
            100, 50, 100, 50, 100, 50,
            200
        ])


# 6. Accessibility Vibrations
class AccessibilityVibrations:
    def __init__(self):
        self.haptic = HapticFeedbackPatterns()

    def tick(self):
        """Tick sound (for clock, timer)"""
        self.haptic.vibrate.vibrate(10)

    def tock(self):
        """Tock sound"""
        self.haptic.vibrate.vibrate(15)

    def hour_chime(self):
        """Hour chime"""
        self.haptic.vibrate.vibrate_pattern([100, 200, 100])

    def timer_complete(self):
        """Timer complete"""
        self.haptic.notification()

    def boundary_warning(self):
        """Boundary warning"""
        self.haptic.warning()

    def focus_reminder(self):
        """Focus reminder"""
        self.haptic.vibrate.vibrate_pattern([30, 100, 30])

    def step(self):
        """Step counter (each step)"""
        self.haptic.vibrate.vibrate(20)

    def goal_reached(self):
        """Goal reached"""
        self.haptic.success()

    def proximity_alert(self, level: int):
        """
        Proximity alert (getting closer)

        Args:
            level: Alert level (1-3)
        """
        patterns = {
            1: [20],
            2: [30, 100, 30],
            3: [50, 50, 50, 50]
        }
        self.haptic.vibrate.vibrate_pattern(patterns.get(level, [20]))


# 7. Vibration Composer
class VibrationComposer:
    def __init__(self):
        self.vibrate = VibrationManager()

    def compose(self, notes: List[Dict[str, Any]]):
        """
        Compose custom vibration from notes

        Args:
            notes: List of dicts with 'duration' and optional 'pause' keys
        """
        pattern = []

        for i, note in enumerate(notes):
            pattern.append(note['duration'])
            if i < len(notes) - 1:
                pattern.append(note.get('pause', 50))

        self.vibrate.vibrate_pattern(pattern)

    def compose_melody(self, notes: List[int], tempo: int = 200):
        """
        Compose melody

        Args:
            notes: List of note durations
            tempo: Time between notes in ms
        """
        pattern = []

        for i, note in enumerate(notes):
            pattern.append(note)
            if i < len(notes) - 1:
                pattern.append(tempo)

        self.vibrate.vibrate_pattern(pattern)

    def fade_in(self, max_duration: int, steps: int = 5):
        """
        Fade in effect

        Args:
            max_duration: Maximum vibration duration
            steps: Number of fade steps
        """
        pattern = []
        step_duration = max_duration / steps

        for i in range(1, steps + 1):
            pattern.extend([int(step_duration * i), 50])

        self.vibrate.vibrate_pattern(pattern)

    def fade_out(self, max_duration: int, steps: int = 5):
        """
        Fade out effect

        Args:
            max_duration: Maximum vibration duration
            steps: Number of fade steps
        """
        pattern = []
        step_duration = max_duration / steps

        for i in range(steps, 0, -1):
            pattern.extend([int(step_duration * i), 50])

        self.vibrate.vibrate_pattern(pattern)


# Usage Examples
async def demonstrate_vibration():
    print("=== Web Python Vibration API Examples ===\n")

    vibration_manager = VibrationManager()
    haptic_patterns = HapticFeedbackPatterns()
    sequencer = VibrationSequencer()
    game_feedback = GameFeedbackVibrations()
    composer = VibrationComposer()

    # 1. Check support
    print("--- 1. Vibration Support ---")
    print(f"Vibration Supported: {vibration_manager.is_supported()}")

    if not vibration_manager.is_supported():
        print("Vibration API is not supported on this device")
        return

    # 2. Basic vibration
    print("\n--- 2. Basic Vibration ---")
    print("Short vibration...")
    vibration_manager.vibrate(100)

    # 3. Haptic patterns
    print("\n--- 3. Haptic Patterns ---")
    print("Success pattern...")
    haptic_patterns.success()

    print("Error pattern...")
    haptic_patterns.error()

    print("Warning pattern...")
    haptic_patterns.warning()

    # 4. Sequencer
    print("\n--- 4. Sequencer ---")
    print("SOS pattern...")
    haptic_patterns.sos()

    # 5. Game feedback
    print("\n--- 5. Game Feedback ---")
    print("Hit...")
    game_feedback.hit()

    print("Critical hit...")
    game_feedback.critical_hit()

    print("Power up...")
    game_feedback.power_up()

    # 6. Composer
    print("\n--- 6. Vibration Composer ---")
    print("Composed melody...")
    composer.compose_melody([100, 150, 200, 150, 100], 150)

    print("\n=== All Vibration API Examples Completed ===")

# Export functions
export = {
    'VibrationManager': VibrationManager,
    'HapticFeedbackPatterns': HapticFeedbackPatterns,
    'VibrationSequencer': VibrationSequencer,
    'NotificationVibrations': NotificationVibrations,
    'GameFeedbackVibrations': GameFeedbackVibrations,
    'AccessibilityVibrations': AccessibilityVibrations,
    'VibrationComposer': VibrationComposer,
    'demonstrate_vibration': demonstrate_vibration
}