Files
MultiRoombaRover/webui/src/ptz/usePtzSession.js
T

37 lines
1.5 KiB
JavaScript

import { useCallback, useEffect, useState } from 'react';
import { useSessionActions, useSessionSelector } from '../context/SessionContext.jsx';
export default function usePtzSession() {
const connected = useSessionSelector((state) => state.connected);
const socketId = useSessionSelector((state) => state.session?.socketId);
const canEnter = useSessionSelector((state) => Boolean(state.session?.ptzCamera?.permissions?.canEnter));
const { setOperatingMode, ptzRequestTurn } = useSessionActions();
const [entryError, setEntryError] = useState(null);
const enter = useCallback(async () => {
await setOperatingMode('ptz');
await ptzRequestTurn();
}, [setOperatingMode, ptzRequestTurn]);
useEffect(() => {
if (!connected || !socketId || !canEnter) return;
let active = true;
// Entry happens on route mount/reconnect, not on queue changes. Releasing a
// turn therefore leaves the page idle instead of silently requesting again.
// Both server actions are serialized and idempotent under Strict Mode.
(async () => {
await setOperatingMode('ptz');
if (active) await ptzRequestTurn();
})().then(() => {
if (active) setEntryError(null);
}).catch((err) => {
if (active) setEntryError(err.message);
});
return () => { active = false; };
}, [connected, socketId, canEnter, setOperatingMode, ptzRequestTurn]);
const retryEntry = useCallback(() => {
enter().then(() => setEntryError(null)).catch((err) => setEntryError(err.message));
}, [enter]);
return { entryError, retryEntry };
}