cobalt/web/src/lib/device.ts
wukko ea8560e8a9
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
Run tests / check lockfile correctness (push) Has been cancelled
Run tests / web sanity check (push) Has been cancelled
Run tests / api sanity check (push) Has been cancelled
web/settings/defaults: toggle localProcessing depending on device
webkit is really weird with wasm ram management, so we disable local processing by default there. the user can still enable it manually in settings, but then we're not at fault by allowing potentially broken behavior by default
2025-04-21 23:06:25 +06:00

93 lines
2.3 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,
},
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(/iphone os (\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,
defaultLocalProcessing: !iOS && !device.browser.webkit,
};
device.userAgent = navigator.userAgent;
}
export { device, app };