Spaces:
Configuration error
Configuration error
| export class DeviceDetect { | |
| static inIframe(): boolean { | |
| try { | |
| return window.self !== window.top; | |
| } catch { | |
| return true; | |
| } | |
| } | |
| static hasTouch(): boolean { | |
| return window.matchMedia("(pointer: coarse)").matches; | |
| } | |
| static canHover(): boolean { | |
| return !window.matchMedia("(hover: none)").matches; | |
| } | |
| /** | |
| * Whether the visitor has asked for less motion. Guarded, unlike its neighbours, | |
| * because a caller runs under jsdom where `matchMedia` is undefined until a test | |
| * stubs it. | |
| */ | |
| static prefersReducedMotion(): boolean { | |
| return globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false; | |
| } | |
| /** | |
| * Whether to build the app with the reduced chrome. One definition, because | |
| * two consumers act on it — createViewer decides which widgets exist, and | |
| * CesiumController decides what the UI toggle is allowed to hide. | |
| */ | |
| static minimalUI(): boolean { | |
| return this.inIframe() || this.isIos(); | |
| } | |
| static isIos(): boolean { | |
| const userAgent = window.navigator.userAgent.toLowerCase(); | |
| return /iphone|ipad|ipod/.test(userAgent); | |
| } | |
| static isSafari(): boolean { | |
| const userAgent = window.navigator.userAgent.toLowerCase(); | |
| return /safari/.test(userAgent); | |
| } | |
| static isInStandaloneMode(): boolean { | |
| // Non-standard Safari property | |
| return "standalone" in window.navigator && Boolean((window.navigator as Navigator & { standalone?: boolean }).standalone); | |
| } | |
| static isiPhoneWithNotch(): boolean { | |
| return this.isIos() && /iPhone X/.test(this.getiPhoneModel()); | |
| } | |
| static isiPhoneWithNotchVisible(): boolean { | |
| return this.isiPhoneWithNotch() && (this.isInStandaloneMode() || !this.isSafari()); | |
| } | |
| static getiPhoneModel(): string { | |
| // Screen geometry and pixel ratio per model, from | |
| // https://51degrees.com/blog/website-optimisation-for-apple-devices-ipad-and-iphone | |
| const ratio = window.devicePixelRatio; | |
| if (window.screen.height / window.screen.width === 896 / 414) { | |
| switch (ratio) { | |
| case 2: | |
| return "iPhone XR"; | |
| case 3: | |
| return "iPhone XS Max"; | |
| default: | |
| return "iPhone XR, iPhone XS Max"; | |
| } | |
| } else if (window.screen.height / window.screen.width === 812 / 375) { | |
| return "iPhone X, iPhone XS"; | |
| } else if (window.screen.height / window.screen.width === 736 / 414) { | |
| return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus"; | |
| } else if (window.screen.height / window.screen.width === 667 / 375) { | |
| if (ratio === 2) { | |
| return "iPhone 6, 6s, 7 or 8"; | |
| } | |
| return "iPhone 6 Plus, 6s Plus , 7 Plus or 8 Plus (display zoom)"; | |
| } else if (window.screen.height / window.screen.width === 1.775) { | |
| return "iPhone 5, 5C, 5S, SE or 6, 6s, 7 and 8 (display zoom)"; | |
| } else if (window.screen.height / window.screen.width === 1.5 && ratio === 2) { | |
| return "iPhone 4 or 4s"; | |
| } else if (window.screen.height / window.screen.width === 1.5 && ratio === 1) { | |
| return "iPhone 1, 3G or 3GS"; | |
| } else { | |
| return "Not an iPhone"; | |
| } | |
| } | |
| } | |