UNPKG

@shopware-ag/dive

Version:

Shopware Spatial Framework

155 lines (134 loc) 4.92 kB
export enum WebXRUnsupportedReason { 'UNKNWON_ERROR' = 0, 'NO_HTTPS' = 1, 'IMMERSIVE_AR_NOT_SUPPORTED_BY_DEVICE' = 2, 'AR_SESSION_NOT_ALLOWED' = 3, } export class DIVEInfo { private static _supportsWebXR: boolean | null = null; private static _webXRUnsupportedReason: WebXRUnsupportedReason | null = null; /** * * @returns The system the user is using. Possible values are "Android", "iOS", "Windows", "MacOS", "Linux" or "Unknown". */ public static GetSystem(): string { const platform = navigator.platform; if (/Android/.test(navigator.userAgent)) { return 'Android'; } else if (/iPhone|iPad|iPod/.test(navigator.userAgent)) { return 'iOS'; } else if (platform.startsWith('Win')) { return 'Windows'; } else if (platform.startsWith('Mac')) { return 'MacOS'; } else if (platform.startsWith('Linux')) { return 'Linux'; } else { return 'Unknown'; } } /** * @returns A promise that resolves to a boolean indicating whether the user's device supports WebXR. */ public static async GetSupportsWebXR(): Promise<boolean> { if (this._supportsWebXR !== null) { return this._supportsWebXR; } // check if XRSystem is available && if https enabled if (!navigator.xr) { this._supportsWebXR = false; if (window.isSecureContext === false) { this._webXRUnsupportedReason = WebXRUnsupportedReason.NO_HTTPS; } else { this._webXRUnsupportedReason = WebXRUnsupportedReason.UNKNWON_ERROR; } return this._supportsWebXR; } // Check if immersive-vr session mode is supported try { const supported = await navigator.xr!.isSessionSupported('immersive-ar'); if (!supported) { this._webXRUnsupportedReason = WebXRUnsupportedReason.IMMERSIVE_AR_NOT_SUPPORTED_BY_DEVICE; } this._supportsWebXR = supported; } catch (error) { this._supportsWebXR = false; this._webXRUnsupportedReason = WebXRUnsupportedReason.AR_SESSION_NOT_ALLOWED; } return this._supportsWebXR; } /** * @returns The reason why WebXR is not supported on the user's device. Returns null if WebXR is supported nor not has been checked yet. */ public static GetWebXRUnsupportedReason(): WebXRUnsupportedReason | null { if (this._supportsWebXR === null) { console.log('WebXR support has not been checked yet.'); return null; } return this._webXRUnsupportedReason; } /** * @returns A boolean indicating whether the user's device supports AR Quick Look. */ public static GetSupportsARQuickLook(): boolean { const a = document.createElement('a'); if (a.relList.supports('ar')) { return true; } // fallback check const userAgent = navigator.userAgent; // Check if the device is running iOS const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as unknown as Window & { MSStream?: string }).MSStream; if (!isIOS) { return false; } // Extract iOS version const match = userAgent.match(/OS (\d+)_/); if (!match || match.length < 2) { return false; } const iOSVersion = parseInt(match[1], 10); // Minimum iOS version for QuickLook support const minQuickLookVersion = 12; // Check if the iOS version is supported if (iOSVersion < minQuickLookVersion) { return false; } // Check for supported browser const isSupportedBrowser = /^((?!chrome|android).)*safari|CriOS|FxiOS/i.test(userAgent); if (isSupportedBrowser) { return true; } // Default to false if none of the conditions are met return false; } /** * @returns A boolean indicating whether the user's device is a mobile device. */ public static get isMobile(): boolean { return this.GetSystem() === 'Android' || this.GetSystem() === 'iOS'; } /** * @returns A boolean indicating whether the user's device is a desktop device. */ public static get isDesktop(): boolean { return !this.isMobile; } /** * @returns A promise that resolves to a boolean indicating whether the user's device is capable of AR. */ public static async GetIsARCapable(): Promise<boolean> { if (this.GetSupportsARQuickLook()) { return true; } return await this.GetSupportsWebXR(); } }