diff --git a/src/hooks/useCameraPermission.ts b/src/hooks/useCameraPermission.ts index 77f1249..a8ec991 100644 --- a/src/hooks/useCameraPermission.ts +++ b/src/hooks/useCameraPermission.ts @@ -8,39 +8,51 @@ export const useCameraPermission = () => { // 카메라 권한 확인 함수 const checkCameraPermission = async () => { try { - const permissionStatus = await navigator.permissions.query({ - name: "camera" as PermissionName, - }) + // 먼저 navigator.permissions.query()를 시도합니다. + if ("permissions" in navigator && "query" in navigator.permissions) { + const permissionStatus = await navigator.permissions.query({ + name: "camera" as PermissionName, + }) - // 권한 상태 설정 - if (permissionStatus.state === "granted") { - setHasPermission(true) - setIsPermissionDenied(false) - } else if (permissionStatus.state === "denied") { - setHasPermission(false) - setIsPermissionDenied(true) - } - - // 권한 변경 감지 - permissionStatus.onchange = () => { + // 권한 상태 설정 if (permissionStatus.state === "granted") { setHasPermission(true) setIsPermissionDenied(false) + return } else if (permissionStatus.state === "denied") { setHasPermission(false) setIsPermissionDenied(true) + return + } + + // 권한 변경 감지 (크롬에서 작동) + permissionStatus.onchange = () => { + if (permissionStatus.state === "granted") { + setHasPermission(true) + setIsPermissionDenied(false) + } else if (permissionStatus.state === "denied") { + setHasPermission(false) + setIsPermissionDenied(true) + } } } + + // navigator.permissions.query()가 지원되지 않거나 "prompt" 상태인 경우 + // 실제 카메라 접근을 시도합니다. + const stream = await navigator.mediaDevices.getUserMedia({ video: true }) + stream.getTracks().forEach((track) => track.stop()) // 스트림 정리 + setHasPermission(true) + setIsPermissionDenied(false) } catch (error) { - console.error("Permission API error:", error) + console.error("Camera access error:", error) setHasPermission(false) setIsPermissionDenied(true) } } useEffect(() => { - checkCameraPermission() // 컴포넌트 마운트 시 권한 확인 + checkCameraPermission() }, []) - return { hasPermission, isPermissionDenied } + return { hasPermission, isPermissionDenied, checkCameraPermission } } diff --git a/src/hooks/usePushNotification.ts b/src/hooks/usePushNotification.ts index 6114d41..b0d8e29 100644 --- a/src/hooks/usePushNotification.ts +++ b/src/hooks/usePushNotification.ts @@ -10,8 +10,8 @@ interface UsePushNotificationResult { // 커스텀 훅: 알림 권한을 확인하고 권한 변경을 감지 const usePushNotification = (): UsePushNotificationResult => { - const [hasPermission, setHasPermission] = useState(false) // 권한이 허용되었는지 여부 - const [isPermissionDenied, setIsPermissionDenied] = useState(false) // 권한이 거부되었는지 여부 + const [hasPermission, setHasPermission] = useState(false) + const [isPermissionDenied, setIsPermissionDenied] = useState(false) // 최신 상태 추적용 useRef const hasPermissionRef = useRef(hasPermission) @@ -62,18 +62,31 @@ const usePushNotification = (): UsePushNotificationResult => { useEffect(() => { // 컴포넌트가 마운트될 때 권한 상태 확인 if ("Notification" in window) { - requestNotificationPermission() - // 권한 변경 감지 - navigator.permissions - .query({ name: "notifications" as PermissionName }) - .then((permissionStatus) => { - permissionStatus.onchange = () => { - handlePermissionChange(Notification.permission) - } - }) - .catch((error) => { - console.error("Permission API error:", error) - }) + handlePermissionChange(Notification.permission) + + const checkPermission = () => { + handlePermissionChange(Notification.permission) + } + + if ("permissions" in navigator && "query" in navigator.permissions) { + // Chrome and other browsers that support Permissions API + navigator.permissions + .query({ name: "notifications" as PermissionName }) + .then((permissionStatus) => { + checkPermission() + permissionStatus.onchange = checkPermission + }) + .catch((error) => { + console.error("Permission API error:", error) + // Fallback to interval checking for Safari + const checkPermissionInterval = setInterval(checkPermission, 1000) + return () => clearInterval(checkPermissionInterval) + }) + } else { + // Safari and other browsers that don't support Permissions API + const checkPermissionInterval = setInterval(checkPermission, 1000) + return () => clearInterval(checkPermissionInterval) + } } }, []) diff --git a/src/pages/MonitoringPage.tsx b/src/pages/MonitoringPage.tsx index 885cdbb..567d625 100644 --- a/src/pages/MonitoringPage.tsx +++ b/src/pages/MonitoringPage.tsx @@ -18,7 +18,7 @@ const MonitoringPage: React.FC = () => { useEffect(() => { const init = async (): Promise => { // 최근 스냅샷을 가져오기 - if (!snapshot) { + if (!snapshot || snapshot.length === 0) { const userSnap = await getRecentSnapshot() // 스냅샷이 있으면 store에 저장 @@ -32,6 +32,23 @@ const MonitoringPage: React.FC = () => { init() }, []) + const checkMobile = () => { + const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera + + // Regular expressions to check for mobile and tablet devices + const mobileRegex = + /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i + const tabletRegex = /android|ipad|playbook|silk/i + + const isMobileDevice = mobileRegex.test(userAgent) || tabletRegex.test(userAgent) + + return isMobileDevice + } + + if (checkMobile()) { + return
모바일 디바이스는 현재 사용이 불가능 합니다
+ } + return (
{/* Main content area */}