返回 AiToEarn
device.ts
根目录 / project / aitoearn-web / src / store / user / utils / device.ts
1 export type ClientDeviceType = 'mobile' | 'desktop' | 'tablet' | 'unknown'
2
3 export interface ClientDeviceInfo {
4 deviceType: ClientDeviceType
5 os?: string
6 browser?: string
7 }
8
9 interface NavigatorUserAgentData {
10 mobile?: boolean
11 platform?: string
12 }
13
14 type NavigatorWithUserAgentData = Navigator & {
15 userAgentData?: NavigatorUserAgentData
16 }
17
18 function getRawBrowserUserAgent() {
19 if (typeof window === 'undefined')
20 return ''
21
22 return window.navigator.userAgent || ''
23 }
24
25 function getNavigatorWithUserAgentData(): NavigatorWithUserAgentData | undefined {
26 if (typeof window === 'undefined')
27 return undefined
28
29 return window.navigator as NavigatorWithUserAgentData
30 }
31
32 function isIpadOsDesktopMode(userAgent: string, platform: string, maxTouchPoints: number) {
33 return /macintosh|mac os x/i.test(userAgent) && /mac/i.test(platform) && maxTouchPoints > 1
34 }
35
36 function detectClientDeviceType(userAgent: string, navigatorInfo: NavigatorWithUserAgentData): ClientDeviceType {
37 const platform = navigatorInfo.userAgentData?.platform || navigatorInfo.platform || ''
38 const maxTouchPoints = navigatorInfo.maxTouchPoints || 0
39 const mobileFromUserAgentData = navigatorInfo.userAgentData?.mobile
40 const hasCoarsePointer = typeof window !== 'undefined' && typeof window.matchMedia === 'function'
41 ? window.matchMedia('(pointer: coarse)').matches
42 : false
43 const screenWidth = typeof window !== 'undefined' ? window.screen.width || window.innerWidth : 0
44 const screenHeight = typeof window !== 'undefined' ? window.screen.height || window.innerHeight : 0
45 const minScreenSize = Math.min(screenWidth, screenHeight)
46
47 if (isIpadOsDesktopMode(userAgent, platform, maxTouchPoints))
48 return 'tablet'
49
50 if (/ipad|tablet|kindle|silk|playbook|nexus 7|nexus 9|sm-t|tab/i.test(userAgent))
51 return 'tablet'
52
53 if (/android/i.test(userAgent) && !/mobile/i.test(userAgent))
54 return 'tablet'
55
56 if (mobileFromUserAgentData === true)
57 return 'mobile'
58
59 if (/mobi|iphone|ipod|blackberry|iemobile|opera mini|phone/i.test(userAgent))
60 return 'mobile'
61
62 if (mobileFromUserAgentData === false)
63 return 'desktop'
64
65 if (/windows nt|macintosh|x11|linux x86_64|cros/i.test(userAgent))
66 return 'desktop'
67
68 if (hasCoarsePointer && minScreenSize > 0 && minScreenSize < 768)
69 return 'mobile'
70
71 return 'unknown'
72 }
73
74 function detectClientOs(userAgent: string, navigatorInfo: NavigatorWithUserAgentData) {
75 const platform = navigatorInfo.userAgentData?.platform || navigatorInfo.platform || ''
76 const maxTouchPoints = navigatorInfo.maxTouchPoints || 0
77
78 if (isIpadOsDesktopMode(userAgent, platform, maxTouchPoints))
79 return 'iPadOS'
80
81 if (/iphone|ipad|ipod/i.test(userAgent))
82 return 'iOS'
83
84 if (/android/i.test(userAgent))
85 return 'Android'
86
87 if (/windows nt/i.test(userAgent))
88 return 'Windows'
89
90 if (/mac os x|macintosh/i.test(userAgent))
91 return 'macOS'
92
93 if (/cros/i.test(userAgent))
94 return 'Chrome OS'
95
96 if (/linux/i.test(userAgent))
97 return 'Linux'
98
99 return undefined
100 }
101
102 function detectClientBrowser(userAgent: string) {
103 if (/edgios|edga|edg\//i.test(userAgent))
104 return 'Edge'
105
106 if (/opr\//i.test(userAgent) || /opera/i.test(userAgent))
107 return 'Opera'
108
109 if (/crios/i.test(userAgent))
110 return 'Chrome'
111
112 if (/fxios/i.test(userAgent))
113 return 'Firefox'
114
115 if (/firefox\//i.test(userAgent))
116 return 'Firefox'
117
118 if (/samsungbrowser/i.test(userAgent))
119 return 'Samsung Browser'
120
121 if (/chrome\//i.test(userAgent) || /chromium/i.test(userAgent))
122 return 'Chrome'
123
124 if (/safari\//i.test(userAgent))
125 return 'Safari'
126
127 if (/msie|trident/i.test(userAgent))
128 return 'Internet Explorer'
129
130 return undefined
131 }
132
133 export function getClientDeviceInfo(): ClientDeviceInfo {
134 const navigatorInfo = getNavigatorWithUserAgentData()
135 if (!navigatorInfo) {
136 return { deviceType: 'unknown' }
137 }
138
139 const userAgent = getRawBrowserUserAgent()
140
141 return {
142 deviceType: detectClientDeviceType(userAgent, navigatorInfo),
143 os: detectClientOs(userAgent, navigatorInfo),
144 browser: detectClientBrowser(userAgent),
145 }
146 }
147
147 lines TYPESCRIPT