mirror of
https://github.com/imputnet/cobalt.git
synced 2025-12-13 14:12:55 +00:00
there's no navigator.maxTouchPoints in web worker context, so previously there was no way to detect whether safari is running on ipad or not
96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
import { browser } from "$app/environment";
|
|
|
|
const app = {
|
|
is: {
|
|
installed: false,
|
|
}
|
|
}
|
|
|
|
const device = {
|
|
is: {
|
|
iPhone: false,
|
|
iPad: false,
|
|
iOS: false,
|
|
android: false,
|
|
mobile: false,
|
|
},
|
|
browser: {
|
|
chrome: false,
|
|
webkit: false,
|
|
},
|
|
prefers: {
|
|
language: "en",
|
|
reducedMotion: false,
|
|
reducedTransparency: false,
|
|
},
|
|
supports: {
|
|
share: false,
|
|
directDownload: false,
|
|
haptics: false,
|
|
defaultLocalProcessing: false,
|
|
multithreading: false,
|
|
},
|
|
userAgent: "sveltekit server",
|
|
}
|
|
|
|
if (browser) {
|
|
const ua = navigator.userAgent.toLowerCase();
|
|
|
|
const iPhone = ua.includes("iphone os");
|
|
const iPad = !iPhone && ua.includes("mac os") && navigator.maxTouchPoints > 0;
|
|
|
|
const iosVersion = Number(ua.match(/version\/(\d+)/)?.[1]);
|
|
const modernIOS = iPhone && iosVersion >= 18;
|
|
|
|
const iOS = iPhone || iPad;
|
|
const android = ua.includes("android") || ua.includes("diordna");
|
|
|
|
const installed = window.matchMedia('(display-mode: standalone)').matches;
|
|
|
|
app.is = {
|
|
installed,
|
|
};
|
|
|
|
device.is = {
|
|
mobile: iOS || android,
|
|
android,
|
|
|
|
iPhone,
|
|
iPad,
|
|
iOS,
|
|
};
|
|
|
|
device.browser = {
|
|
chrome: ua.includes("chrome/"),
|
|
webkit: ua.includes("applewebkit/")
|
|
&& ua.includes("version/")
|
|
&& ua.includes("safari/")
|
|
// this is the version of webkit that's hardcoded into chrome
|
|
// and indicates that the browser is not actually webkit
|
|
&& !ua.includes("applewebkit/537.36")
|
|
};
|
|
|
|
device.prefers = {
|
|
language: navigator.language.toLowerCase().slice(0, 2) || "en",
|
|
reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
|
reducedTransparency: window.matchMedia('(prefers-reduced-transparency: reduce)').matches,
|
|
};
|
|
|
|
device.supports = {
|
|
share: navigator.share !== undefined,
|
|
directDownload: !(installed && iOS),
|
|
|
|
// not sure if vibrations feel the same on android,
|
|
// so they're enabled only on ios 18+ for now
|
|
haptics: modernIOS,
|
|
|
|
// enable local processing by default everywhere but android chrome
|
|
defaultLocalProcessing: !(device.is.android && device.browser.chrome),
|
|
multithreading: !iOS || iosVersion >= 18,
|
|
};
|
|
|
|
device.userAgent = navigator.userAgent;
|
|
}
|
|
|
|
export { device, app };
|