134 lines
3.5 KiB
TypeScript
134 lines
3.5 KiB
TypeScript
|
|
/**
|
||
|
|
* Browser compatibility checking utilities
|
||
|
|
*/
|
||
|
|
|
||
|
|
export interface BrowserCompatibility {
|
||
|
|
isSupported: boolean;
|
||
|
|
missingFeatures: string[];
|
||
|
|
warnings: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if all required browser features are supported
|
||
|
|
*/
|
||
|
|
export function checkBrowserCompatibility(): BrowserCompatibility {
|
||
|
|
const missingFeatures: string[] = [];
|
||
|
|
const warnings: string[] = [];
|
||
|
|
|
||
|
|
// Check if running in browser
|
||
|
|
if (typeof window === 'undefined') {
|
||
|
|
return {
|
||
|
|
isSupported: true,
|
||
|
|
missingFeatures: [],
|
||
|
|
warnings: [],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check Web Audio API
|
||
|
|
if (!window.AudioContext && !(window as any).webkitAudioContext) {
|
||
|
|
missingFeatures.push('Web Audio API');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check IndexedDB
|
||
|
|
if (!window.indexedDB) {
|
||
|
|
missingFeatures.push('IndexedDB');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check localStorage
|
||
|
|
try {
|
||
|
|
localStorage.setItem('test', 'test');
|
||
|
|
localStorage.removeItem('test');
|
||
|
|
} catch (e) {
|
||
|
|
missingFeatures.push('LocalStorage');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check Canvas API
|
||
|
|
const canvas = document.createElement('canvas');
|
||
|
|
if (!canvas.getContext || !canvas.getContext('2d')) {
|
||
|
|
missingFeatures.push('Canvas API');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check MediaDevices API (for recording)
|
||
|
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||
|
|
warnings.push('Microphone recording not supported (requires HTTPS or localhost)');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check File API
|
||
|
|
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
|
||
|
|
missingFeatures.push('File API');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check AudioWorklet support (optional)
|
||
|
|
if (window.AudioContext && !AudioContext.prototype.hasOwnProperty('audioWorklet')) {
|
||
|
|
warnings.push('AudioWorklet not supported (some features may have higher latency)');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check OfflineAudioContext
|
||
|
|
if (!window.OfflineAudioContext && !(window as any).webkitOfflineAudioContext) {
|
||
|
|
missingFeatures.push('OfflineAudioContext (required for audio processing)');
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
isSupported: missingFeatures.length === 0,
|
||
|
|
missingFeatures,
|
||
|
|
warnings,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get user-friendly browser name
|
||
|
|
*/
|
||
|
|
export function getBrowserInfo(): { name: string; version: string } {
|
||
|
|
// Check if running in browser
|
||
|
|
if (typeof window === 'undefined' || typeof navigator === 'undefined') {
|
||
|
|
return { name: 'Unknown', version: 'Unknown' };
|
||
|
|
}
|
||
|
|
|
||
|
|
const userAgent = navigator.userAgent;
|
||
|
|
let name = 'Unknown';
|
||
|
|
let version = 'Unknown';
|
||
|
|
|
||
|
|
if (userAgent.indexOf('Chrome') > -1 && userAgent.indexOf('Edg') === -1) {
|
||
|
|
name = 'Chrome';
|
||
|
|
const match = userAgent.match(/Chrome\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (userAgent.indexOf('Edg') > -1) {
|
||
|
|
name = 'Edge';
|
||
|
|
const match = userAgent.match(/Edg\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (userAgent.indexOf('Firefox') > -1) {
|
||
|
|
name = 'Firefox';
|
||
|
|
const match = userAgent.match(/Firefox\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
} else if (userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1) {
|
||
|
|
name = 'Safari';
|
||
|
|
const match = userAgent.match(/Version\/(\d+)/);
|
||
|
|
version = match ? match[1] : 'Unknown';
|
||
|
|
}
|
||
|
|
|
||
|
|
return { name, version };
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if browser version meets minimum requirements
|
||
|
|
*/
|
||
|
|
export function checkMinimumVersion(): boolean {
|
||
|
|
const { name, version } = getBrowserInfo();
|
||
|
|
const versionNum = parseInt(version, 10);
|
||
|
|
|
||
|
|
const minimumVersions: Record<string, number> = {
|
||
|
|
Chrome: 90,
|
||
|
|
Edge: 90,
|
||
|
|
Firefox: 88,
|
||
|
|
Safari: 14,
|
||
|
|
};
|
||
|
|
|
||
|
|
const minVersion = minimumVersions[name];
|
||
|
|
if (!minVersion) {
|
||
|
|
// Unknown browser, assume it's ok
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return versionNum >= minVersion;
|
||
|
|
}
|