mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-11 09:09:34 +00:00
refactor(wakelock): simplify logic into hook
This commit is contained in:
committed by
Carlos Valente
parent
f128f7acd2
commit
1189a94bff
@@ -1,84 +1,10 @@
|
|||||||
import { use, useCallback, useEffect, useMemo, useState } from 'react';
|
import { useWakelock } from './useWakeLock';
|
||||||
import { useSearchParams } from 'react-router';
|
|
||||||
|
|
||||||
import { PresetContext } from '../../common/context/PresetContext';
|
|
||||||
|
|
||||||
/** @url https://developer.mozilla.org/en-US/docs/Web/API/WakeLock */
|
|
||||||
export default function KeepAwake() {
|
|
||||||
const { keepAwake } = useKeepAwakeOptions();
|
|
||||||
const [wakeLockSentinel, setWakeLockSentinel] = useState<WakeLockSentinel | null>(null);
|
|
||||||
|
|
||||||
const removeLock = () => {
|
|
||||||
if (wakeLockSentinel) wakeLockSentinel.release().finally(() => setWakeLockSentinel(null));
|
|
||||||
};
|
|
||||||
|
|
||||||
const acquireLock = () => {
|
|
||||||
if (!wakeLockSentinel || wakeLockSentinel.released) {
|
|
||||||
setWakeLockSentinel(null);
|
|
||||||
navigator.wakeLock
|
|
||||||
.request('screen')
|
|
||||||
.then((sentinel) => {
|
|
||||||
setWakeLockSentinel(sentinel);
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const controller = new AbortController();
|
|
||||||
if (keepAwake) {
|
|
||||||
acquireLock();
|
|
||||||
document.addEventListener(
|
|
||||||
'visibilitychange',
|
|
||||||
() => {
|
|
||||||
if (wakeLockSentinel !== null && document.visibilityState === 'visible') {
|
|
||||||
acquireLock();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ signal: controller.signal },
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
removeLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
controller.abort();
|
|
||||||
removeLock();
|
|
||||||
};
|
|
||||||
}, [keepAwake]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keepAwakeKey = 'keep-awake';
|
|
||||||
|
|
||||||
function getOptionsFromParams(searchParams: URLSearchParams, defaultValues?: URLSearchParams) {
|
|
||||||
// Helper to get value from either source, prioritizing defaultValues
|
|
||||||
return defaultValues?.has(keepAwakeKey) || searchParams.has(keepAwakeKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook exposes the keep awake options
|
* Composes the wakelock hook to contain re-renders
|
||||||
*/
|
*/
|
||||||
export function useKeepAwakeOptions() {
|
export default function KeepAwake() {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
useWakelock();
|
||||||
const maybePreset = use(PresetContext);
|
|
||||||
|
|
||||||
const keepAwake = useMemo(() => {
|
return null;
|
||||||
const defaultValues = maybePreset ? new URLSearchParams(maybePreset.search) : undefined;
|
|
||||||
return getOptionsFromParams(searchParams, defaultValues);
|
|
||||||
}, [maybePreset, searchParams]);
|
|
||||||
|
|
||||||
const toggleKeepAwake = useCallback(() => {
|
|
||||||
setSearchParams((searchParams) => {
|
|
||||||
if (keepAwake) {
|
|
||||||
searchParams.delete(keepAwakeKey);
|
|
||||||
} else {
|
|
||||||
searchParams.set(keepAwakeKey, '1');
|
|
||||||
}
|
|
||||||
return searchParams;
|
|
||||||
});
|
|
||||||
}, [keepAwake]);
|
|
||||||
|
|
||||||
return { keepAwake, toggleKeepAwake };
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import { use, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
|
import { useSearchParams } from 'react-router';
|
||||||
|
|
||||||
|
import { PresetContext } from '../../common/context/PresetContext';
|
||||||
|
|
||||||
|
// wakelock is only available in secure contexts
|
||||||
|
// however, that is covered by the navigator check
|
||||||
|
export const canUseWakeLock = typeof window !== 'undefined' && 'wakeLock' in navigator;
|
||||||
|
|
||||||
|
/** @url https://developer.mozilla.org/en-US/docs/Web/API/WakeLock */
|
||||||
|
export function useWakelock() {
|
||||||
|
const { keepAwake } = useKeepAwakeOptions();
|
||||||
|
const wakeLockSentinelRef = useRef<WakeLockSentinel | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const removeLock = () => {
|
||||||
|
if (wakeLockSentinelRef.current) {
|
||||||
|
wakeLockSentinelRef.current.release().finally(() => {
|
||||||
|
wakeLockSentinelRef.current = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const acquireLock = () => {
|
||||||
|
const sentinel = wakeLockSentinelRef.current;
|
||||||
|
if (!sentinel || sentinel.released) {
|
||||||
|
wakeLockSentinelRef.current = null;
|
||||||
|
navigator.wakeLock
|
||||||
|
.request('screen')
|
||||||
|
.then((sentinel) => {
|
||||||
|
wakeLockSentinelRef.current = sentinel;
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const controller = new AbortController();
|
||||||
|
if (keepAwake) {
|
||||||
|
acquireLock();
|
||||||
|
document.addEventListener(
|
||||||
|
'visibilitychange',
|
||||||
|
() => {
|
||||||
|
if (wakeLockSentinelRef.current !== null && document.visibilityState === 'visible') {
|
||||||
|
acquireLock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ signal: controller.signal },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
removeLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
controller.abort();
|
||||||
|
removeLock();
|
||||||
|
};
|
||||||
|
}, [keepAwake]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keepAwakeKey = 'keep-awake';
|
||||||
|
|
||||||
|
function getOptionsFromParams(searchParams: URLSearchParams, defaultValues?: URLSearchParams) {
|
||||||
|
// Helper to get value from either source, prioritizing defaultValues
|
||||||
|
return defaultValues?.has(keepAwakeKey) || searchParams.has(keepAwakeKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook exposes the keep awake options
|
||||||
|
*/
|
||||||
|
export function useKeepAwakeOptions() {
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const maybePreset = use(PresetContext);
|
||||||
|
|
||||||
|
const keepAwake = useMemo(() => {
|
||||||
|
const defaultValues = maybePreset ? new URLSearchParams(maybePreset.search) : undefined;
|
||||||
|
return getOptionsFromParams(searchParams, defaultValues);
|
||||||
|
}, [maybePreset, searchParams]);
|
||||||
|
|
||||||
|
const toggleKeepAwake = useCallback(() => {
|
||||||
|
setSearchParams((searchParams) => {
|
||||||
|
if (keepAwake) {
|
||||||
|
searchParams.delete(keepAwakeKey);
|
||||||
|
} else {
|
||||||
|
searchParams.set(keepAwakeKey, '1');
|
||||||
|
}
|
||||||
|
return searchParams;
|
||||||
|
});
|
||||||
|
}, [keepAwake, setSearchParams]);
|
||||||
|
|
||||||
|
return { keepAwake, toggleKeepAwake };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user