All files / app/utils clientPlatform.ts

85.71% Statements 18/21
83.33% Branches 15/18
100% Functions 3/3
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33234x             234x     5x 5x 5x 4x 3x         3x 3x 3x         5x 5x 5x 3x 3x    
import { theme } from "theme";
 
export type ClientPlatform = "web_desktop" | "web_mobile" | "app_ios" | "app_android";
 
// The native app's web views append this token to the browser user agent
// (app/mobile/utils/userAgent.ts); it's the only in-app signal every shipped app
// build already sends.
const NATIVE_USER_AGENT = /\bCouchersNative\/\S+\s+\((ios|android);/;
 
function getNativePlatform(): ClientPlatform | null {
  Iif (typeof navigator === "undefined") return null;
  const os = NATIVE_USER_AGENT.exec(navigator.userAgent)?.[1];
  if (os === "ios") return "app_ios";
  if (os === "android") return "app_android";
  return null;
}
 
// Matches the app's own "mobile" breakpoint (theme.breakpoints.down("md")).
function isMobileViewport(): boolean {
  Iif (typeof window === "undefined" || !window.matchMedia) return false;
  const query = theme.breakpoints.down("md").replace("@media ", "");
  return window.matchMedia(query).matches;
}
 
// The client platform a request is coming from, or null when it can't be
// determined (e.g. during server-side rendering).
export function getClientPlatform(): ClientPlatform | null {
  const nativePlatform = getNativePlatform();
  if (nativePlatform) return nativePlatform;
  Iif (typeof window === "undefined" || !window.matchMedia) return null;
  return isMobileViewport() ? "web_mobile" : "web_desktop";
}