Duffer Derek

Current Path : /var/www/sitesecurity.bitkit.dk/httpdocs/src/lib/
Upload File :
Current File : /var/www/sitesecurity.bitkit.dk/httpdocs/src/lib/deviceDetection.ts

// Device detection utilities for PWA and notification features
import { isIOSDevice, isIOSPWA, safeLocalStorage } from "./iosPWAUtils";

export interface DeviceInfo {
  isMobile: boolean;
  isIOS: boolean;
  isAndroid: boolean;
  isDesktop: boolean;
  isPWA: boolean;
  isStandalone: boolean;
  iosVersion: number | null;
  browserName: string;
  platform: "Web" | "PWA";
  osName: string;
}

// Detect if device is mobile
export const isMobile = (): boolean => {
  if (typeof window === "undefined") return false;

  const userAgent = navigator.userAgent.toLowerCase();
  const mobileKeywords = [
    "mobile",
    "android",
    "iphone",
    "ipad",
    "ipod",
    "blackberry",
    "windows phone",
  ];

  return (
    mobileKeywords.some((keyword) => userAgent.includes(keyword)) ||
    /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)
  );
};

// Detect if device is iOS
export const isIOS = (): boolean => {
  return isIOSDevice();
};

// Detect if device is Android
export const isAndroid = (): boolean => {
  if (typeof window === "undefined") return false;

  const userAgent = navigator.userAgent.toLowerCase();
  return /android/.test(userAgent);
};

// Detect if device is desktop
export const isDesktop = (): boolean => {
  return !isMobile();
};

// Detect if app is running as PWA (standalone mode)
export const isPWA = (): boolean => {
  if (typeof window === "undefined") return false;

  // Use iOS-specific PWA detection if on iOS
  if (isIOSDevice()) {
    return isIOSPWA();
  }

  // Primary check: display mode
  const isStandaloneMode = window.matchMedia("(display-mode: standalone)").matches;

  // Secondary check: iOS Safari standalone
  const isIOSStandalone = (window.navigator as any).standalone === true;

  // Tertiary check: window dimensions (PWA has no browser chrome)
  const hasNoBrowserChrome = window.screen.height - window.innerHeight < 100;

  // Additional check: check if we're in a PWA context
  const isPWAContext =
    window.location.protocol === "https:" || window.location.hostname === "localhost";

  // Return true if any of the primary checks pass
  return isStandaloneMode || isIOSStandalone || (hasNoBrowserChrome && isPWAContext);
};

// Detect if app is in standalone mode (alternative check)
export const isStandalone = (): boolean => {
  if (typeof window === "undefined") return false;

  return (
    window.matchMedia("(display-mode: standalone)").matches ||
    (window.navigator as any).standalone === true
  );
};

// Get iOS version
export const getIOSVersion = (): number | null => {
  if (typeof window === "undefined" || !isIOS()) return null;

  const userAgent = navigator.userAgent;
  const match = userAgent.match(/OS (\d+)_(\d+)/);

  if (match) {
    const major = parseInt(match[1], 10);
    const minor = parseInt(match[2], 10);
    return major + minor / 10;
  }

  return null;
};

// Get OS name
export const getOSName = (): string => {
  if (typeof window === "undefined") return "Unknown";

  const userAgent = navigator.userAgent.toLowerCase();
  
  // Mobile OS detection
  if (/iphone|ipad|ipod/.test(userAgent)) {
    return "iOS";
  }
  if (/android/.test(userAgent)) {
    return "Android";
  }
  
  // Desktop OS detection
  if (/windows/.test(userAgent)) {
    return "Windows";
  }
  if (/macintosh|mac os x/.test(userAgent)) {
    return "macOS";
  }
  if (/linux/.test(userAgent)) {
    return "Linux";
  }
  if (/chrome os/.test(userAgent)) {
    return "Chrome OS";
  }
  
  return "Unknown";
};

// Get browser name
export const getBrowserName = (): string => {
  if (typeof window === "undefined") return "Unknown";

  const userAgent = navigator.userAgent;

  if (userAgent.includes("Chrome")) return "Chrome";
  if (userAgent.includes("Firefox")) return "Firefox";
  if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) return "Safari";
  if (userAgent.includes("Edge")) return "Edge";
  if (userAgent.includes("Opera")) return "Opera";
  if (userAgent.includes("Samsung")) return "Samsung Internet";

  return "Unknown";
};

// Get platform type
export const getPlatform = (): "Web" | "PWA" => {
  return isPWA() ? "PWA" : "Web";
};

// Check if iOS version supports notifications (>= 16.4)
export const isIOSNotificationSupported = (): boolean => {
  const iosVersion = getIOSVersion();
  return iosVersion !== null && iosVersion >= 16.4;
};

// Get comprehensive device information
export const getDeviceInfo = (): DeviceInfo => {
  return {
    isMobile: isMobile(),
    isIOS: isIOS(),
    isAndroid: isAndroid(),
    isDesktop: isDesktop(),
    isPWA: isPWA(),
    isStandalone: isStandalone(),
    iosVersion: getIOSVersion(),
    browserName: getBrowserName(),
    platform: getPlatform(),
    osName: getOSName(),
  };
};

// Check if notifications are supported on current device
export const isNotificationSupported = (): boolean => {
  if (typeof window === "undefined") return false;

  try {
    // Check if notifications are supported
    if (!("Notification" in window)) return false;

    // For iOS, check version requirement
    if (isIOS()) {
      return isIOSNotificationSupported();
    }

    return true;
  } catch (error) {
    console.warn("Error checking notification support:", error);
    return false;
  }
};

// Check if PWA installation is supported
export const isPWAInstallSupported = (): boolean => {
  if (typeof window === "undefined") return false;

  // Check if beforeinstallprompt event is supported
  const hasBeforeInstallPrompt = "onbeforeinstallprompt" in window;

  // Additional checks for PWA installation support
  const hasServiceWorker = "serviceWorker" in navigator;
  const isHTTPS = window.location.protocol === "https:" || window.location.hostname === "localhost";

  // console.log("PWA Install Support Check:", {
  //   hasBeforeInstallPrompt,
  //   hasServiceWorker,
  //   isHTTPS,
  //   userAgent: navigator.userAgent,
  // });

  return hasBeforeInstallPrompt && hasServiceWorker && isHTTPS;
};

// Check if PWA has been installed before (using multiple methods)
export const hasPWABeenInstalled = (): boolean => {
  if (typeof window === "undefined") return false;

  // Use safe localStorage for iOS
  const localStorageFlag = safeLocalStorage.getItem("pwa_installed") === "true";

  // Check if we're currently in PWA mode
  const currentlyInPWA = isPWA();

  // Check if the app was previously installed (by checking if we can detect PWA context)
  const hasPWAContext =
    window.matchMedia("(display-mode: standalone)").matches ||
    (window.navigator as any).standalone === true;

  // If we're currently in PWA mode, mark it as installed in localStorage
  if (currentlyInPWA && !localStorageFlag) {
    safeLocalStorage.setItem("pwa_installed", "true");
  }

  return localStorageFlag || currentlyInPWA || hasPWAContext;
};

// Check if service worker is supported
export const isServiceWorkerSupported = (): boolean => {
  if (typeof window === "undefined") return false;

  return "serviceWorker" in navigator;
};

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists