Skip to content

Commit

Permalink
Merge pull request #106 from DDD-Community/feat/#58
Browse files Browse the repository at this point in the history
[feat/#58] Safari 에서 카메라 및 알람에 접근 가능하도록 수정, 모바일 환경에서 접근할 경우 모니터링 안되게 수정
  • Loading branch information
G-hoon authored Sep 27, 2024
2 parents 9979100 + 9439f82 commit 1cf0d33
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 32 deletions.
46 changes: 29 additions & 17 deletions src/hooks/useCameraPermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
41 changes: 27 additions & 14 deletions src/hooks/usePushNotification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}
}, [])

Expand Down
19 changes: 18 additions & 1 deletion src/pages/MonitoringPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const MonitoringPage: React.FC = () => {
useEffect(() => {
const init = async (): Promise<void> => {
// 최근 스냅샷을 가져오기
if (!snapshot) {
if (!snapshot || snapshot.length === 0) {
const userSnap = await getRecentSnapshot()

// 스냅샷이 있으면 store에 저장
Expand All @@ -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 <div className="text-2xl font-bold text-white">모바일 디바이스는 현재 사용이 불가능 합니다</div>
}

return (
<div className="relative flex h-full w-full overflow-hidden">
{/* Main content area */}
Expand Down

0 comments on commit 1cf0d33

Please sign in to comment.