[email protected] 1 месяц назад
Родитель
Сommit
2e0ede2a4d
1 измененных файлов: 35 добавлений и 12 удалений
  1. +35
    -12
      src/lib/devicePresence.ts

+ 35
- 12
src/lib/devicePresence.ts Просмотреть файл

@@ -61,19 +61,36 @@ export function formatClientIpDisplay(ip?: string | null): string {
return ip.trim();
}

/** CSS px; tablets in portrait are often 600–800; phones are usually smaller. */
const TABLET_MIN_SHORT_SIDE_PX = 480;

function hasTouchCapability(): boolean {
if (typeof navigator === "undefined") return false;
const touchPoints = navigator.maxTouchPoints ?? 0;
return touchPoints > 0 || "ontouchstart" in window;
}

export function detectClientTypeFromUa(): string {
if (typeof navigator === "undefined") return "unknown";

const ua = navigator.userAgent.toLowerCase();
const touchPoints = navigator.maxTouchPoints ?? 0;
const hasTouch = hasTouchCapability();
const shortSide = screenShortSidePx();

// iPadOS 13+ "desktop" Safari: MacIntel + multi-touch, no "iPad" in UA string
const isIpad =
ua.includes("ipad") ||
(navigator.platform === "MacIntel" && touchPoints > 1);
if (ua.includes("iphone") || ua.includes("ipod")) {
return "mobile";
}

if (ua.includes("ipad") || ua.includes("tablet")) {
return "tablet";
}

if (isIpad || ua.includes("tablet")) {
// iPadOS 13+ "desktop" Safari: MacIntel + multi-touch, no "iPad" in UA string
if (
(navigator.platform === "MacIntel" || ua.includes("macintosh")) &&
touchPoints > 1
) {
return "tablet";
}

@@ -83,24 +100,30 @@ export function detectClientTypeFromUa(): string {
const platform = uad.platform?.toLowerCase() ?? "";
if (platform.includes("android")) {
if (!uad.mobile) return "tablet";
if (touchPoints > 0 && shortSide >= 600) return "tablet";
if (hasTouch && shortSide >= TABLET_MIN_SHORT_SIDE_PX) return "tablet";
return "mobile";
}
if (platform === "ios" && hasTouch) {
return "tablet";
}
}

if (ua.includes("android")) {
// Many Android tablets still include "Mobile" in the UA string
// Warehouse slates almost always include "Mobile" in UA even when not phones
if (!ua.includes("mobile")) return "tablet";
if (touchPoints > 0 && shortSide >= 600) return "tablet";
return "mobile";
if (hasTouch && shortSide >= TABLET_MIN_SHORT_SIDE_PX) return "tablet";
// Small Android phone
if (shortSide > 0 && shortSide < 400) return "mobile";
return "tablet";
}

if (ua.includes("iphone") || ua.includes("ipod")) {
if (ua.includes("mobile")) {
return "mobile";
}

if (ua.includes("mobile")) {
return "mobile";
// Touch slate / Surface / kiosk with desktop-like UA
if (hasTouch && shortSide >= 400) {
return "tablet";
}

return "desktop";


Загрузка…
Отмена
Сохранить