/** * Middleware for handling responsive API requests * Ensures backend responds appropriately to different device types */ export interface DeviceInfo { type: 'mobile' | 'tablet' | 'desktop'; userAgent: string; screenWidth?: number; screenHeight?: number; } /** * Detect device type from User-Agent and viewport */ export function detectDevice(userAgent: string, width?: number): DeviceInfo['type'] { const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i; const tabletRegex = /iPad|Android(?!.*Mobile)/i; if (width) { if (width < 768) return 'mobile'; if (width < 1024) return 'tablet'; return 'desktop'; } if (tabletRegex.test(userAgent)) return 'tablet'; if (mobileRegex.test(userAgent)) return 'mobile'; return 'desktop'; } /** * Optimize response payload based on device type * Reduces data transfer for mobile devices */ export function optimizePayload>( data: T, deviceType: DeviceInfo['type'] ): T { if (deviceType === 'mobile') { // Remove heavy fields for mobile const optimized = { ...data } as any; // Remove high-res images, use thumbnails instead if ('images' in data && Array.isArray(data.images)) { optimized.images = (data.images as any[]).map((img: any) => ({ ...img, url: img.thumbnail || img.url, highRes: undefined, })); } // Limit array sizes for mobile if ('items' in data && Array.isArray(data.items)) { optimized.items = (data.items as any[]).slice(0, 10); } return optimized; } return data; } /** * Add device info to API request headers */ export function addDeviceHeaders(headers: HeadersInit = {}): HeadersInit { const width = typeof window !== 'undefined' ? window.innerWidth : undefined; const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : ''; const deviceType = detectDevice(userAgent, width); return { ...headers, 'X-Device-Type': deviceType, 'X-Screen-Width': width?.toString() || '', 'X-User-Agent': userAgent, }; } /** * Adaptive pagination based on device */ export function getAdaptivePagination(deviceType: DeviceInfo['type']) { const limits = { mobile: 10, tablet: 20, desktop: 50, }; return { limit: limits[deviceType], offset: 0, }; } /** * Image quality based on device and connection */ export function getImageQuality(deviceType: DeviceInfo['type'], connectionType?: string): number { if (connectionType === 'slow-2g' || connectionType === '2g') return 30; if (deviceType === 'mobile') return 60; if (deviceType === 'tablet') return 80; return 90; }