Moved web socket updates to context and fixed panel update bug.

This commit is contained in:
Tom Butcher 2026-02-15 02:56:16 +00:00
parent 72005ea946
commit 1fd8961979
2 changed files with 75 additions and 55 deletions

View File

@ -1,5 +1,4 @@
import React, { useMemo, useState, useEffect, useCallback } from "react";
import { useParams } from "react-router-dom";
import React, { useMemo, useState, useCallback } from "react";
import { useWebSocket } from "@contexts/WebSocketContext";
import { DeviceProvider, useDevice } from "@contexts/DeviceContext";
import { HPAppProvider } from "@contexts/HPAppContext";
@ -12,15 +11,8 @@ import DashboardCarousel from "./dashboard/DashboardCarousel";
import "./Device.css";
function DeviceContent() {
const { id } = useParams();
const {
isConnected,
subscribeToOwnDeviceUpdate,
setDeviceId,
setDeviceOnline,
} = useWebSocket();
const { panels, handlePanelChange, deviceName, setDeviceName } = useDevice();
const [device, setDevice] = useState(null);
const { isConnected } = useWebSocket();
const { panels, handlePanelChange, device, deviceName } = useDevice();
const [isCarouselVisible, setIsCarouselVisible] = useState(false);
@ -29,19 +21,6 @@ function DeviceContent() {
setIsCarouselVisible(true);
}, 1);
}, []);
// Subscribe to own device updates - returns initial device data
// The server uses the authenticated deviceId from the client
useEffect(() => {
setDeviceId(id);
if (!isConnected || !id) return;
const unsubscribe = subscribeToOwnDeviceUpdate((updatedDevice) => {
setDevice(updatedDevice);
setDeviceName(updatedDevice?.name || null);
});
return () => unsubscribe();
}, [isConnected, id, subscribeToOwnDeviceUpdate, setDeviceId, setDeviceName]);
const devicePanels = useMemo(() => {
const devicePanels = device?.panels || [];
@ -57,17 +36,6 @@ function DeviceContent() {
return newPanels;
}, [device?.panels, panels]);
useEffect(() => {
if (isConnected == true && device?.id) {
setDeviceOnline(true);
return () => {
setDeviceOnline(false).catch(() => {
// Silently handle errors in cleanup (e.g., socket not connected)
});
};
}
}, [isConnected, setDeviceOnline, device?.id]);
let status = null;
if (!device) {

View File

@ -1,4 +1,12 @@
import React, { createContext, useContext, useState, useCallback } from "react";
import React, {
createContext,
useContext,
useState,
useCallback,
useEffect,
} from "react";
import { useParams } from "react-router-dom";
import { useWebSocket } from "@contexts/WebSocketContext";
const DeviceContext = createContext(null);
@ -16,37 +24,81 @@ export const useDeviceSafe = () => {
};
export const DeviceProvider = ({ children }) => {
const { id } = useParams();
const {
isConnected,
subscribeToOwnDeviceUpdate,
setDeviceId,
setDeviceOnline,
} = useWebSocket();
const [panels, setPanels] = useState([]);
const [device, setDevice] = useState(null);
const [deviceName, setDeviceName] = useState(null);
const [currentPanelIndex, setCurrentPanelIndex] = useState(0);
const [panelSelectorVisible, setPanelSelectorVisible] = useState(false);
// Subscribe to own device updates - returns initial device data
// The server uses the authenticated deviceId from the client
useEffect(() => {
setDeviceId(id);
if (!isConnected || !id) return;
const unsubscribe = subscribeToOwnDeviceUpdate((updatedDevice) => {
setDevice(updatedDevice);
setPanels(updatedDevice?.panels || []);
setDeviceName(updatedDevice?.name || null);
});
return () => unsubscribe();
}, [
isConnected,
id,
subscribeToOwnDeviceUpdate,
setDeviceId,
setDeviceName,
setPanels,
]);
useEffect(() => {
if (isConnected === true && device?.id) {
setDeviceOnline(true);
return () => {
setDeviceOnline(false).catch(() => {
// Silently handle errors in cleanup (e.g., socket not connected)
});
};
}
}, [isConnected, setDeviceOnline, device?.id]);
const handlePanelChange = useCallback((updatedPanels) => {
if (!updatedPanels || !Array.isArray(updatedPanels)) return;
// Update local panels state with the new panels array
setPanels(updatedPanels);
}, []);
const setCurrentPanel = useCallback((panelOrIndex, delay = 0) => {
const changePanel = () => {
if (typeof panelOrIndex === "number") {
// If it's a number, treat it as an index
setCurrentPanelIndex(panelOrIndex);
} else if (panelOrIndex && typeof panelOrIndex === "object") {
// If it's an object, find the index by panel id
const index = panels.findIndex((p) => p?.id === panelOrIndex?.id);
if (index !== -1) {
setCurrentPanelIndex(index);
const setCurrentPanel = useCallback(
(panelOrIndex, delay = 0) => {
const changePanel = () => {
if (typeof panelOrIndex === "number") {
// If it's a number, treat it as an index
setCurrentPanelIndex(panelOrIndex);
} else if (panelOrIndex && typeof panelOrIndex === "object") {
// If it's an object, find the index by panel id
const index = panels.findIndex((p) => p?.id === panelOrIndex?.id);
if (index !== -1) {
setCurrentPanelIndex(index);
}
}
}
};
};
if (delay > 0) {
setTimeout(changePanel, delay);
} else {
changePanel();
}
}, [panels]);
if (delay > 0) {
setTimeout(changePanel, delay);
} else {
changePanel();
}
},
[panels],
);
return (
<DeviceContext.Provider
@ -54,6 +106,7 @@ export const DeviceProvider = ({ children }) => {
panels,
setPanels,
handlePanelChange,
device,
deviceName,
setDeviceName,
currentPanelIndex,
@ -68,4 +121,3 @@ export const DeviceProvider = ({ children }) => {
};
export default DeviceContext;