1import { Platform } from 'expo-modules-core';
2import UAParser from 'ua-parser-js';
3
4import { DeviceType } from './Device.types';
5
6type NavigatorWithDeviceMemory = Navigator & { deviceMemory: number };
7
8let result: any = null;
9if (Platform.isDOMAvailable) {
10  const parser = new UAParser(window.navigator.userAgent);
11  result = parser.getResult();
12}
13
14function convertGiBtoBytes(gib: number): number {
15  return Math.round(gib * 1024 ** 3);
16}
17
18function getDeviceType(): DeviceType {
19  switch (result?.device?.type) {
20    case 'mobile':
21      return DeviceType.PHONE;
22    case 'tablet':
23      return DeviceType.TABLET;
24    case 'smarttv':
25      return DeviceType.TV;
26    case 'console':
27    case 'embedded':
28    case 'wearable':
29      return DeviceType.UNKNOWN;
30    default:
31      return DeviceType.DESKTOP;
32  }
33}
34
35export default {
36  get isDevice(): boolean {
37    return true;
38  },
39  get brand(): null {
40    return null;
41  },
42  get manufacturer(): null {
43    return (result && result.device.vendor) || null;
44  },
45  get modelName(): string | null {
46    return (result && result.device.model) || null;
47  },
48  get deviceYearClass(): null {
49    return null;
50  },
51  get deviceType(): DeviceType {
52    return getDeviceType();
53  },
54  get totalMemory(): number | null {
55    if (Platform.isDOMAvailable && 'deviceMemory' in navigator) {
56      const { deviceMemory } = navigator as NavigatorWithDeviceMemory;
57      return convertGiBtoBytes(deviceMemory);
58    }
59    return null;
60  },
61  get supportedCpuArchitectures(): string[] | null {
62    return result && result.cpu.architecture ? [result.cpu.architecture] : null;
63  },
64  get osName(): string {
65    return (result && result.os.name) || '';
66  },
67  get osVersion(): string {
68    return (result && result.os.version) || '';
69  },
70  get osBuildId(): null {
71    return null;
72  },
73  get osInternalBuildId(): null {
74    return null;
75  },
76  get deviceName(): null {
77    return null;
78  },
79  async getDeviceTypeAsync(): Promise<DeviceType> {
80    return getDeviceType();
81  },
82  async isRootedExperimentalAsync(): Promise<boolean> {
83    return false;
84  },
85};
86