mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 09:31:20 -04:00
first lol
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useSocket } from './SocketContext.jsx';
|
||||
|
||||
const SessionContext = createContext({
|
||||
connected: false,
|
||||
session: null,
|
||||
logs: [],
|
||||
login: async () => {},
|
||||
setRole: async () => {},
|
||||
requestControl: async () => {},
|
||||
releaseControl: async () => {},
|
||||
subscribeAll: async () => {},
|
||||
});
|
||||
|
||||
function useAckEmitter(socket) {
|
||||
return useCallback(
|
||||
(event, payload = {}) =>
|
||||
new Promise((resolve, reject) => {
|
||||
socket.emit(event, payload, (resp = {}) => {
|
||||
if (resp.error) {
|
||||
reject(new Error(resp.error));
|
||||
} else {
|
||||
resolve(resp);
|
||||
}
|
||||
});
|
||||
}),
|
||||
[socket],
|
||||
);
|
||||
}
|
||||
|
||||
export function SessionProvider({ children }) {
|
||||
const socket = useSocket();
|
||||
const emitWithAck = useAckEmitter(socket);
|
||||
const [session, setSession] = useState(null);
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [connected, setConnected] = useState(socket.connected);
|
||||
|
||||
useEffect(() => {
|
||||
const onConnect = () => setConnected(true);
|
||||
const onDisconnect = () => setConnected(false);
|
||||
socket.on('connect', onConnect);
|
||||
socket.on('disconnect', onDisconnect);
|
||||
return () => {
|
||||
socket.off('connect', onConnect);
|
||||
socket.off('disconnect', onDisconnect);
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
useEffect(() => {
|
||||
function handleSession(payload) {
|
||||
setSession(payload);
|
||||
}
|
||||
function handleLogInit(entries = []) {
|
||||
setLogs(entries);
|
||||
}
|
||||
function handleLogEntry(entry) {
|
||||
setLogs((prev) => [...prev.slice(-199), entry]);
|
||||
}
|
||||
socket.on('session:sync', handleSession);
|
||||
socket.on('log:init', handleLogInit);
|
||||
socket.on('log:entry', handleLogEntry);
|
||||
return () => {
|
||||
socket.off('session:sync', handleSession);
|
||||
socket.off('log:init', handleLogInit);
|
||||
socket.off('log:entry', handleLogEntry);
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
const actions = useMemo(
|
||||
() => ({
|
||||
login: (username, password) => emitWithAck('auth:login', { username, password }),
|
||||
setRole: (role) => emitWithAck('session:setRole', { role }),
|
||||
requestControl: (roverId, options = {}) =>
|
||||
emitWithAck('session:requestControl', { roverId, ...options }),
|
||||
releaseControl: (roverId) => emitWithAck('session:releaseControl', { roverId }),
|
||||
subscribeAll: () => emitWithAck('session:subscribeAll'),
|
||||
}),
|
||||
[emitWithAck],
|
||||
);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
connected,
|
||||
session,
|
||||
logs,
|
||||
...actions,
|
||||
}),
|
||||
[actions, connected, logs, session],
|
||||
);
|
||||
|
||||
return <SessionContext.Provider value={value}>{children}</SessionContext.Provider>;
|
||||
}
|
||||
|
||||
export function useSession() {
|
||||
return useContext(SessionContext);
|
||||
}
|
||||
Reference in New Issue
Block a user