215 lines
6.0 KiB
TypeScript
215 lines
6.0 KiB
TypeScript
|
|
// Mobile detection and debugging utilities
|
||
|
|
|
||
|
|
export interface DeviceInfo {
|
||
|
|
isMobile: boolean;
|
||
|
|
isIOS: boolean;
|
||
|
|
isAndroid: boolean;
|
||
|
|
isTablet: boolean;
|
||
|
|
browser: string;
|
||
|
|
version: string;
|
||
|
|
userAgent: string;
|
||
|
|
cookieEnabled: boolean;
|
||
|
|
screenWidth: number;
|
||
|
|
screenHeight: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getDeviceInfo(): DeviceInfo {
|
||
|
|
if (typeof window === 'undefined') {
|
||
|
|
return {
|
||
|
|
isMobile: false,
|
||
|
|
isIOS: false,
|
||
|
|
isAndroid: false,
|
||
|
|
isTablet: false,
|
||
|
|
browser: 'Unknown',
|
||
|
|
version: 'Unknown',
|
||
|
|
userAgent: 'Server',
|
||
|
|
cookieEnabled: false,
|
||
|
|
screenWidth: 0,
|
||
|
|
screenHeight: 0
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const ua = navigator.userAgent;
|
||
|
|
|
||
|
|
// Mobile detection
|
||
|
|
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
|
||
|
|
const isIOS = /iPad|iPhone|iPod/.test(ua);
|
||
|
|
const isAndroid = /Android/.test(ua);
|
||
|
|
const isTablet = /iPad|Android(?=.*\bMobile\b)(?!.*\bMobile\b)/i.test(ua);
|
||
|
|
|
||
|
|
// Browser detection
|
||
|
|
let browser = 'Unknown';
|
||
|
|
let version = 'Unknown';
|
||
|
|
|
||
|
|
if (ua.includes('Chrome') && !ua.includes('Edge')) {
|
||
|
|
browser = 'Chrome';
|
||
|
|
const match = ua.match(/Chrome\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (ua.includes('Safari') && !ua.includes('Chrome')) {
|
||
|
|
browser = 'Safari';
|
||
|
|
const match = ua.match(/Version\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (ua.includes('Firefox')) {
|
||
|
|
browser = 'Firefox';
|
||
|
|
const match = ua.match(/Firefox\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (ua.includes('Edge')) {
|
||
|
|
browser = 'Edge';
|
||
|
|
const match = ua.match(/Edge\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
isMobile,
|
||
|
|
isIOS,
|
||
|
|
isAndroid,
|
||
|
|
isTablet,
|
||
|
|
browser,
|
||
|
|
version,
|
||
|
|
userAgent: ua,
|
||
|
|
cookieEnabled: navigator.cookieEnabled,
|
||
|
|
screenWidth: window.screen.width,
|
||
|
|
screenHeight: window.screen.height
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function logDeviceInfo(label: string = 'Device Info'): void {
|
||
|
|
if (typeof window === 'undefined') return;
|
||
|
|
|
||
|
|
const info = getDeviceInfo();
|
||
|
|
|
||
|
|
console.group(`📱 ${label}`);
|
||
|
|
console.log('Mobile:', info.isMobile);
|
||
|
|
console.log('iOS:', info.isIOS);
|
||
|
|
console.log('Android:', info.isAndroid);
|
||
|
|
console.log('Tablet:', info.isTablet);
|
||
|
|
console.log('Browser:', `${info.browser} ${info.version}`);
|
||
|
|
console.log('Cookies Enabled:', info.cookieEnabled);
|
||
|
|
console.log('Screen:', `${info.screenWidth}x${info.screenHeight}`);
|
||
|
|
console.log('User Agent:', info.userAgent);
|
||
|
|
|
||
|
|
// Additional debugging info
|
||
|
|
console.log('Viewport:', `${window.innerWidth}x${window.innerHeight}`);
|
||
|
|
console.log('Device Pixel Ratio:', window.devicePixelRatio);
|
||
|
|
console.log('Online:', navigator.onLine);
|
||
|
|
console.log('Language:', navigator.language);
|
||
|
|
console.log('Platform:', navigator.platform);
|
||
|
|
|
||
|
|
// Cookie testing
|
||
|
|
try {
|
||
|
|
document.cookie = 'test=1; path=/';
|
||
|
|
const canSetCookie = document.cookie.includes('test=1');
|
||
|
|
console.log('Can Set Cookies:', canSetCookie);
|
||
|
|
if (canSetCookie) {
|
||
|
|
document.cookie = 'test=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.log('Cookie Test Error:', error);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.groupEnd();
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isMobileDevice(): boolean {
|
||
|
|
return getDeviceInfo().isMobile;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isIOSDevice(): boolean {
|
||
|
|
return getDeviceInfo().isIOS;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isAndroidDevice(): boolean {
|
||
|
|
return getDeviceInfo().isAndroid;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getMobileBrowser(): string {
|
||
|
|
const info = getDeviceInfo();
|
||
|
|
return `${info.browser} ${info.version}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Enhanced mobile login debugging
|
||
|
|
export function debugMobileLogin(context: string): void {
|
||
|
|
if (!isMobileDevice()) return;
|
||
|
|
|
||
|
|
console.group(`🔐 Mobile Login Debug - ${context}`);
|
||
|
|
logDeviceInfo('Current Device');
|
||
|
|
|
||
|
|
// Check for known mobile issues
|
||
|
|
const info = getDeviceInfo();
|
||
|
|
const issues: string[] = [];
|
||
|
|
|
||
|
|
if (info.isIOS && info.browser === 'Safari' && parseInt(info.version) < 14) {
|
||
|
|
issues.push('Safari < 14: Cookie issues with SameSite');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (info.isAndroid && info.browser === 'Chrome' && parseInt(info.version) < 80) {
|
||
|
|
issues.push('Chrome < 80: SameSite cookie support limited');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!info.cookieEnabled) {
|
||
|
|
issues.push('Cookies disabled in browser');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (info.screenWidth < 375) {
|
||
|
|
issues.push('Small screen may affect layout');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (issues.length > 0) {
|
||
|
|
console.warn('⚠️ Potential Issues:', issues);
|
||
|
|
} else {
|
||
|
|
console.log('✅ No known compatibility issues detected');
|
||
|
|
}
|
||
|
|
|
||
|
|
console.groupEnd();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Network debugging
|
||
|
|
export function debugNetworkConditions(): void {
|
||
|
|
if (typeof navigator === 'undefined') return;
|
||
|
|
|
||
|
|
console.group('🌐 Network Conditions');
|
||
|
|
console.log('Online:', navigator.onLine);
|
||
|
|
|
||
|
|
// @ts-ignore - connection API is experimental
|
||
|
|
if (navigator.connection) {
|
||
|
|
// @ts-ignore
|
||
|
|
const conn = navigator.connection;
|
||
|
|
console.log('Connection Type:', conn.effectiveType);
|
||
|
|
console.log('Downlink:', conn.downlink, 'Mbps');
|
||
|
|
console.log('RTT:', conn.rtt, 'ms');
|
||
|
|
console.log('Save Data:', conn.saveData);
|
||
|
|
} else {
|
||
|
|
console.log('Network API not available');
|
||
|
|
}
|
||
|
|
|
||
|
|
console.groupEnd();
|
||
|
|
}
|
||
|
|
|
||
|
|
// PWA debugging
|
||
|
|
export function debugPWACapabilities(): void {
|
||
|
|
if (typeof window === 'undefined') return;
|
||
|
|
|
||
|
|
console.group('📱 PWA Capabilities');
|
||
|
|
console.log('Service Worker:', 'serviceWorker' in navigator);
|
||
|
|
console.log('Web App Manifest:', 'onbeforeinstallprompt' in window);
|
||
|
|
console.log('Standalone Mode:', window.matchMedia('(display-mode: standalone)').matches);
|
||
|
|
console.log('Full Screen API:', 'requestFullscreen' in document.documentElement);
|
||
|
|
console.log('Notification API:', 'Notification' in window);
|
||
|
|
console.log('Push API:', 'PushManager' in window);
|
||
|
|
console.groupEnd();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Complete mobile debugging suite
|
||
|
|
export function runMobileDiagnostics(): void {
|
||
|
|
if (!isMobileDevice()) {
|
||
|
|
console.log('📱 Not a mobile device, skipping mobile diagnostics');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
console.group('🔍 Mobile Diagnostics Suite');
|
||
|
|
logDeviceInfo();
|
||
|
|
debugNetworkConditions();
|
||
|
|
debugPWACapabilities();
|
||
|
|
console.groupEnd();
|
||
|
|
}
|