Files
Amanda Johnston c2e1ad385d chore(many): replace any types and add tech debt tickets (#26293)
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2023-01-06 09:34:55 -06:00

132 lines
3.7 KiB
TypeScript

import { config } from '../global/config';
export type Platforms = keyof typeof PLATFORMS_MAP;
// TODO(FW-2832): types
interface IsPlatformSignature {
(plt: Platforms): boolean;
(win: Window, plt: Platforms): boolean;
}
export const getPlatforms = (win?: any) => setupPlatforms(win);
export const isPlatform: IsPlatformSignature = (
winOrPlatform: Window | Platforms | undefined,
platform?: Platforms
) => {
if (typeof winOrPlatform === 'string') {
platform = winOrPlatform;
winOrPlatform = undefined;
}
return getPlatforms(winOrPlatform).includes(platform!);
};
export const setupPlatforms = (win: any = window) => {
if (typeof win === 'undefined') {
return [];
}
win.Ionic = win.Ionic || {};
let platforms: Platforms[] | undefined | null = win.Ionic.platforms;
if (platforms == null) {
platforms = win.Ionic.platforms = detectPlatforms(win);
platforms.forEach((p) => win.document.documentElement.classList.add(`plt-${p}`));
}
return platforms;
};
const detectPlatforms = (win: Window) => {
const customPlatformMethods = config.get('platform');
return (Object.keys(PLATFORMS_MAP) as Platforms[]).filter((p) => {
const customMethod = customPlatformMethods?.[p];
return typeof customMethod === 'function' ? customMethod(win) : PLATFORMS_MAP[p](win);
});
};
const isMobileWeb = (win: Window): boolean => isMobile(win) && !isHybrid(win);
const isIpad = (win: Window) => {
// iOS 12 and below
if (testUserAgent(win, /iPad/i)) {
return true;
}
// iOS 13+
if (testUserAgent(win, /Macintosh/i) && isMobile(win)) {
return true;
}
return false;
};
const isIphone = (win: Window) => testUserAgent(win, /iPhone/i);
const isIOS = (win: Window) => testUserAgent(win, /iPhone|iPod/i) || isIpad(win);
const isAndroid = (win: Window) => testUserAgent(win, /android|sink/i);
const isAndroidTablet = (win: Window) => {
return isAndroid(win) && !testUserAgent(win, /mobile/i);
};
const isPhablet = (win: Window) => {
const width = win.innerWidth;
const height = win.innerHeight;
const smallest = Math.min(width, height);
const largest = Math.max(width, height);
return smallest > 390 && smallest < 520 && largest > 620 && largest < 800;
};
const isTablet = (win: Window) => {
const width = win.innerWidth;
const height = win.innerHeight;
const smallest = Math.min(width, height);
const largest = Math.max(width, height);
return isIpad(win) || isAndroidTablet(win) || (smallest > 460 && smallest < 820 && largest > 780 && largest < 1400);
};
const isMobile = (win: Window) => matchMedia(win, '(any-pointer:coarse)');
const isDesktop = (win: Window) => !isMobile(win);
const isHybrid = (win: Window) => isCordova(win) || isCapacitorNative(win);
const isCordova = (win: any): boolean => !!(win['cordova'] || win['phonegap'] || win['PhoneGap']);
const isCapacitorNative = (win: any): boolean => {
const capacitor = win['Capacitor'];
return !!capacitor?.isNative;
};
const isElectron = (win: Window): boolean => testUserAgent(win, /electron/i);
const isPWA = (win: Window): boolean =>
!!(win.matchMedia?.('(display-mode: standalone)').matches || (win.navigator as any).standalone);
export const testUserAgent = (win: Window, expr: RegExp) => expr.test(win.navigator.userAgent);
const matchMedia = (win: Window, query: string): boolean => win.matchMedia?.(query).matches;
export type PlatformConfig = Partial<typeof PLATFORMS_MAP>;
const PLATFORMS_MAP = {
ipad: isIpad,
iphone: isIphone,
ios: isIOS,
android: isAndroid,
phablet: isPhablet,
tablet: isTablet,
cordova: isCordova,
capacitor: isCapacitorNative,
electron: isElectron,
pwa: isPWA,
mobile: isMobile,
mobileweb: isMobileWeb,
desktop: isDesktop,
hybrid: isHybrid,
};