Skip to content

Commit c9b7586

Browse files
committed
Update browser tools
1 parent 23fec8c commit c9b7586

File tree

2 files changed

+185
-45
lines changed

2 files changed

+185
-45
lines changed

src/utils/hooks/useIsMobile.js

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,103 @@ const App = () => {
2424
import { useEffect, useState } from 'react';
2525

2626

27-
const useIsMobile = (breakpoint = 768) => {
27+
const useIsMobile = (breakpoint = 600) => {
2828
const [isMobile, setIsMobile] = useState(false);
2929
const [isMounted, setIsMounted] = useState(false);
30-
31-
const checkUserAgent = () => {
32-
if (!window) return false;
33-
34-
const userAgent = window.navigator.userAgent.toLowerCase();
35-
const mobileKeywords = [
36-
'android',
37-
'iphone',
38-
'ipad',
39-
'ipod',
40-
'webos',
41-
'blackberry',
42-
'windows phone',
43-
'opera mini',
44-
'mobile',
45-
'tablet'
46-
];
47-
48-
return mobileKeywords.some(keyword => userAgent.includes(keyword));
49-
};
30+
5031

5132
useEffect(() => {
5233
// Set the mounted state to true after the component has mounted
5334
setIsMounted(true);
5435

5536
const handleResize = () => {
5637
if (window) {
57-
const isMobileSize = window.innerWidth <= breakpoint;
58-
const isMobileDevice = checkUserAgent();
59-
setIsMobile(isMobileSize || isMobileDevice);
38+
39+
40+
const detectDeviceType = () => {
41+
// 1. First check if window and navigator are available (SSR compatibility)
42+
if (typeof window === 'undefined' || !navigator) {
43+
return 'desktop'; // Default to desktop
44+
}
45+
46+
// 2. Get user agent string
47+
const ua = navigator.userAgent.toLowerCase();
48+
49+
// 3. Get platform info
50+
const platform = navigator.platform.toLowerCase();
51+
52+
// 4. Check screen characteristics using window.matchMedia
53+
const isTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;
54+
55+
const isPortrait = window.matchMedia('(orientation: portrait)').matches;
56+
const isLandscape = window.matchMedia('(orientation: landscape)').matches;
57+
58+
// 5. Get screen dimensions
59+
const screenWidth = window.screen.width;
60+
const screenHeight = window.screen.height;
61+
const minScreenSize = Math.min(screenWidth, screenHeight);
62+
const maxScreenSize = Math.max(screenWidth, screenHeight);
63+
64+
// Define device characteristics
65+
const isTablet = (
66+
// Traditional UA detection
67+
/ipad/.test(ua) ||
68+
(/android/.test(ua) && !/mobile/.test(ua)) ||
69+
/tablet/.test(ua) ||
70+
/playbook/.test(ua) ||
71+
/nexus (7|9|10)/.test(ua) ||
72+
/sm-t/.test(ua) ||
73+
/huawei(.*)mediapad/.test(ua) ||
74+
75+
// Special detection for iPad Pro and newer iPads
76+
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) ||
77+
78+
// Screen size characteristics (tablets typically fall within this range)
79+
(minScreenSize >= breakpoint && maxScreenSize <= 1366 && isTouch) ||
80+
81+
// Specific device detection
82+
/kindle|silk|kftt|kfot|kfjwa|kfjwi|kfsowi|kfthwa|kfthwi|kfapwa|kfapwi/i.test(ua)
83+
);
84+
85+
const isMobile = (
86+
!isTablet && ( // Prevent tablets from being detected as phones
87+
// Traditional mobile device detection
88+
/iphone|ipod|android.*mobile|windows phone|mobi/.test(ua) ||
89+
90+
// Screen size characteristics (phones typically smaller than 600px)
91+
(minScreenSize < breakpoint && isTouch) ||
92+
93+
// Additional mobile device detection
94+
/blackberry|\bbb\d+|meego|webos|palm|phone|pocket|mobile|mini|iemobile/i.test(ua)
95+
)
96+
);
97+
98+
// 6. Comprehensive decision logic
99+
if (isMobile) {
100+
// Additional check for small tablets
101+
if (maxScreenSize >= 1024 && isTouch) {
102+
return 'tablet';
103+
}
104+
return 'mobile';
105+
}
106+
107+
if (isTablet) {
108+
// Additional check for touch-enabled laptops
109+
if (maxScreenSize > 1366 && /windows/.test(ua)) {
110+
return 'desktop';
111+
}
112+
return 'tablet';
113+
}
114+
115+
// 7. Check for touch-enabled laptops
116+
if (isTouch && /windows/.test(ua) && maxScreenSize > 1366) {
117+
return 'desktop';
118+
}
119+
120+
return 'desktop';
121+
};
122+
123+
setIsMobile(detectDeviceType() === 'mobile');
60124
}
61125
};
62126

src/utils/libs/browser.js

Lines changed: 97 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,107 @@ if ( typeof window !== "undefined" ) {
1616
document.addEventListener("test", null, { get passive() { supportsPassive = true }});
1717
} catch(e) {}
1818

19-
const userAgent = window.navigator.userAgent.toLowerCase();
20-
const mobileKeywords = [
21-
'android',
22-
'iphone',
23-
'ipad',
24-
'ipod',
25-
'webos',
26-
'blackberry',
27-
'windows phone',
28-
'opera mini',
29-
'mobile',
30-
'tablet'
31-
];
32-
33-
const _isTablet = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(userAgent);
34-
const _isMobile = mobileKeywords.some(keyword => userAgent.includes(keyword));
35-
const _isAndroid = ['android'].some(keyword => userAgent.includes(keyword));
19+
const detectDeviceType = () => {
20+
// 1. First check if window and navigator are available (SSR compatibility)
21+
if (typeof window === 'undefined' || !navigator) {
22+
return 'desktop'; // Default to desktop
23+
}
3624

25+
// 2. Get user agent string
26+
const ua = navigator.userAgent.toLowerCase();
27+
28+
// 3. Get platform info
29+
const platform = navigator.platform.toLowerCase();
30+
31+
// 4. Check screen characteristics using window.matchMedia
32+
const isTouch = ('ontouchstart' in window) || navigator.maxTouchPoints > 0;
33+
34+
const isPortrait = window.matchMedia('(orientation: portrait)').matches;
35+
const isLandscape = window.matchMedia('(orientation: landscape)').matches;
36+
37+
// 5. Get screen dimensions
38+
const screenWidth = window.screen.width;
39+
const screenHeight = window.screen.height;
40+
const minScreenSize = Math.min(screenWidth, screenHeight);
41+
const maxScreenSize = Math.max(screenWidth, screenHeight);
42+
43+
// Define device characteristics
44+
const isTablet = (
45+
// Traditional UA detection
46+
/ipad/.test(ua) ||
47+
(/android/.test(ua) && !/mobile/.test(ua)) ||
48+
/tablet/.test(ua) ||
49+
/playbook/.test(ua) ||
50+
/nexus (7|9|10)/.test(ua) ||
51+
/sm-t/.test(ua) ||
52+
/huawei(.*)mediapad/.test(ua) ||
53+
54+
// Special detection for iPad Pro and newer iPads
55+
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) ||
56+
57+
// Screen size characteristics (tablets typically fall within this range)
58+
(minScreenSize >= 600 && maxScreenSize <= 1366 && isTouch) ||
59+
60+
// Specific device detection
61+
/kindle|silk|kftt|kfot|kfjwa|kfjwi|kfsowi|kfthwa|kfthwi|kfapwa|kfapwi/i.test(ua)
62+
);
63+
64+
const isMobile = (
65+
!isTablet && ( // Prevent tablets from being detected as phones
66+
// Traditional mobile device detection
67+
/iphone|ipod|android.*mobile|windows phone|mobi/.test(ua) ||
68+
69+
// Screen size characteristics (phones typically smaller than 600px)
70+
(minScreenSize < 600 && isTouch) ||
71+
72+
// Additional mobile device detection
73+
/blackberry|\bbb\d+|meego|webos|palm|phone|pocket|mobile|mini|iemobile/i.test(ua)
74+
)
75+
);
76+
77+
// 6. Comprehensive decision logic
78+
if (isMobile) {
79+
// Additional check for small tablets
80+
if (maxScreenSize >= 1024 && isTouch) {
81+
return 'tablet';
82+
}
83+
return 'mobile';
84+
}
85+
86+
if (isTablet) {
87+
// Additional check for touch-enabled laptops
88+
if (maxScreenSize > 1366 && /windows/.test(ua)) {
89+
return 'desktop';
90+
}
91+
return 'tablet';
92+
}
93+
94+
// 7. Check for touch-enabled laptops
95+
if (isTouch && /windows/.test(ua) && maxScreenSize > 1366) {
96+
return 'desktop';
97+
}
98+
99+
return 'desktop';
100+
};
101+
102+
const _ua = navigator.userAgent.toLowerCase();
103+
const _vendor = navigator.vendor.toLowerCase();
104+
const _isSafari = (
105+
/safari/.test(_ua) &&
106+
/apple computer/.test(_vendor) &&
107+
!/chrome/.test(_ua) &&
108+
!/chromium/.test(_ua) &&
109+
!/android/.test(_ua)
110+
);
111+
112+
const _isAndroid = /android/.test(_ua);
37113

38114
browser = {
39-
isTablet : _isTablet,
40-
isMobile : _isMobile,
115+
isTablet : detectDeviceType() === 'tablet',
116+
isMobile : detectDeviceType() === 'mobile',
41117
isAndroid : _isAndroid,
42-
isPC : !_isTablet && !_isMobile,
43-
isSafari : !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/), /*Test to 9, 10. */
118+
isPC : detectDeviceType() === 'desktop',
119+
isSafari : _isSafari,
44120
isIE : !!window.ActiveXObject || "ActiveXObject" in window, /*Test to 6 ~ 11 (not edge) */
45121
supportsPassive : supportsPassive
46122
};

0 commit comments

Comments
 (0)