Add responsive design
This commit is contained in:
103
src/middleware/responsiveAPI.ts
Normal file
103
src/middleware/responsiveAPI.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 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<T extends Record<string, any>>(
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user