feat: 初始化财务管理应用前端项目,包含账户、预算、交易、报表、设置等核心功能模块。
This commit is contained in:
180
copy/src/hooks/useDevice.ts
Normal file
180
copy/src/hooks/useDevice.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Device type enum
|
||||
*/
|
||||
export type DeviceType = 'mobile' | 'tablet' | 'desktop';
|
||||
|
||||
/**
|
||||
* Device detection result
|
||||
*/
|
||||
export interface DeviceInfo {
|
||||
isMobile: boolean;
|
||||
isTablet: boolean;
|
||||
isDesktop: boolean;
|
||||
deviceType: DeviceType;
|
||||
isTouchDevice: boolean;
|
||||
screenWidth: number;
|
||||
screenHeight: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Breakpoints for device detection
|
||||
*/
|
||||
const BREAKPOINTS = {
|
||||
mobile: 768, // < 768px
|
||||
tablet: 1024, // 768px - 1024px
|
||||
desktop: 1024, // >= 1024px
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect device type based on User Agent
|
||||
*/
|
||||
const detectDeviceFromUserAgent = (): DeviceType => {
|
||||
const ua = navigator.userAgent.toLowerCase();
|
||||
|
||||
// Mobile devices
|
||||
if (/(android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini)/i.test(ua)) {
|
||||
// Distinguish between tablet and mobile
|
||||
if (/(ipad|tablet|playbook|silk)|(android(?!.*mobile))/i.test(ua)) {
|
||||
return 'tablet';
|
||||
}
|
||||
return 'mobile';
|
||||
}
|
||||
|
||||
return 'desktop';
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect device type based on screen width
|
||||
*/
|
||||
const detectDeviceFromScreenWidth = (width: number): DeviceType => {
|
||||
if (width < BREAKPOINTS.mobile) {
|
||||
return 'mobile';
|
||||
} else if (width < BREAKPOINTS.desktop) {
|
||||
return 'tablet';
|
||||
}
|
||||
return 'desktop';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if device supports touch
|
||||
*/
|
||||
const isTouchDevice = (): boolean => {
|
||||
return (
|
||||
'ontouchstart' in window ||
|
||||
navigator.maxTouchPoints > 0 ||
|
||||
// @ts-ignore - for older browsers
|
||||
navigator.msMaxTouchPoints > 0
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get current device information
|
||||
*/
|
||||
const getDeviceInfo = (): DeviceInfo => {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
// Combine User Agent and screen width detection
|
||||
const uaDevice = detectDeviceFromUserAgent();
|
||||
const screenDevice = detectDeviceFromScreenWidth(width);
|
||||
|
||||
// Prefer User Agent detection, but fall back to screen width
|
||||
const deviceType = uaDevice !== 'desktop' ? uaDevice : screenDevice;
|
||||
|
||||
return {
|
||||
isMobile: deviceType === 'mobile',
|
||||
isTablet: deviceType === 'tablet',
|
||||
isDesktop: deviceType === 'desktop',
|
||||
deviceType,
|
||||
isTouchDevice: isTouchDevice(),
|
||||
screenWidth: width,
|
||||
screenHeight: height,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom hook to detect device type and screen size
|
||||
*
|
||||
* @returns DeviceInfo object with device detection results
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { isMobile, isDesktop, deviceType } = useDevice();
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* {isMobile && <MobileView />}
|
||||
* {isDesktop && <DesktopView />}
|
||||
* </div>
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export const useDevice = (): DeviceInfo => {
|
||||
const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(getDeviceInfo);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setDeviceInfo(getDeviceInfo());
|
||||
};
|
||||
|
||||
// Listen for window resize
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
// Listen for orientation change (mobile devices)
|
||||
window.addEventListener('orientationchange', handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
window.removeEventListener('orientationchange', handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return deviceInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to check if current device is mobile
|
||||
*
|
||||
* @returns boolean indicating if device is mobile
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const isMobile = useIsMobile();
|
||||
* ```
|
||||
*/
|
||||
export const useIsMobile = (): boolean => {
|
||||
const { isMobile } = useDevice();
|
||||
return isMobile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to check if current device is desktop
|
||||
*
|
||||
* @returns boolean indicating if device is desktop
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const isDesktop = useIsDesktop();
|
||||
* ```
|
||||
*/
|
||||
export const useIsDesktop = (): boolean => {
|
||||
const { isDesktop } = useDevice();
|
||||
return isDesktop;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to check if current device is tablet
|
||||
*
|
||||
* @returns boolean indicating if device is tablet
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const isTablet = useIsTablet();
|
||||
* ```
|
||||
*/
|
||||
export const useIsTablet = (): boolean => {
|
||||
const { isTablet } = useDevice();
|
||||
return isTablet;
|
||||
};
|
||||
Reference in New Issue
Block a user