From 451ea1a80b1999c12857cb5451cc01f6e0735819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=83=BC=E3=82=8B?= Date: Sun, 1 Nov 2026 13:47:54 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=BC=E3=83=96=E3=81=8C?= =?UTF-8?q?=E3=81=A4=E3=81=AA=E3=81=8C=E3=81=A3=E3=81=A6=E3=81=84=E3=82=8B?= =?UTF-8?q?=E9=96=93=E3=81=AF=E7=94=BB=E9=9D=A2=E3=81=8C=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E3=81=A7=E6=B6=88=E3=81=88=E3=81=AA=E3=81=84=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- web/src/components/ConnectionPanel.tsx | 3 +++ web/src/cube/wake-lock.ts | 30 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 web/src/cube/wake-lock.ts diff --git a/web/src/components/ConnectionPanel.tsx b/web/src/components/ConnectionPanel.tsx index 23dfe92..1d093d1 100644 --- a/web/src/components/ConnectionPanel.tsx +++ b/web/src/components/ConnectionPanel.tsx @@ -3,6 +3,7 @@ import { canWatchAdvertisements, connectBluetoothCube, isWebBluetoothAvailable, import { useCubeState, useCubeStore } from '../cube/hooks' import { MockConnection } from '../cube/mock' import type { GyroStatus } from '../cube/store' +import { useScreenWakeLock } from '../cube/wake-lock' import { useSettings } from '../settings/hooks' import { useDebug } from '../ui/prefs' import { Dialog } from '../ui/Dialog' @@ -136,6 +137,8 @@ function gyroNotice(useGyro: boolean, status: GyroStatus): { text: string; warn: export function CubeNotices() { const store = useCubeStore() const state = useCubeState() + // キューブを触っている間(つながっている間)は、画面が消えないようにする + useScreenWakeLock(state.status === 'connected') return ( <> {state.error && ( diff --git a/web/src/cube/wake-lock.ts b/web/src/cube/wake-lock.ts new file mode 100644 index 0000000..dd2d5f1 --- /dev/null +++ b/web/src/cube/wake-lock.ts @@ -0,0 +1,30 @@ +import { useEffect } from 'react' + +/** + * on の間、画面が自動で消えないようにする(Screen Wake Lock)。 + * タブを裏に回すとブラウザが解除するので、表に戻ったときに取り直す。対応していないブラウザでは何もしない。 + */ +export function useScreenWakeLock(on: boolean) { + useEffect(() => { + if (!on || !('wakeLock' in navigator)) return + let lock: WakeLockSentinel | null = null + let stopped = false + const acquire = async () => { + if (document.visibilityState !== 'visible' || (lock && !lock.released)) return + try { + const l = await navigator.wakeLock.request('screen') + if (stopped) void l.release() + else lock = l + } catch { + // 省電力モードなどで断られても、画面が消えるだけなので気にしない + } + } + void acquire() + document.addEventListener('visibilitychange', acquire) + return () => { + stopped = true + document.removeEventListener('visibilitychange', acquire) + void lock?.release() + } + }, [on]) +}