-
+
-
(e.target as HTMLInputElement).blur()}
- />
+
+
(e.target as HTMLInputElement).blur()}
+ disabled={isDisabled}
+ ref={inputRef}
+ />
+
+
+
+
+
);
diff --git a/frontend/src/components/dwe/cameras/device-list.tsx b/frontend/src/components/dwe/cameras/device-list.tsx
index b5c2c321..f18f0f72 100644
--- a/frontend/src/components/dwe/cameras/device-list.tsx
+++ b/frontend/src/components/dwe/cameras/device-list.tsx
@@ -17,9 +17,57 @@ import DevicesContext from "@/contexts/DevicesContext";
import { getDeviceByBusInfo } from "@/lib/utils";
import NotConnected from "../not-connected";
import { useToast } from "@/hooks/use-toast";
+import { useTour } from "@/components/tour/tour";
+import { TOUR_STEP_IDS } from "@/lib/tour-constants";
type DeviceModel = components["schemas"]["DeviceModel"];
+const DEMO_DEVICE: DeviceModel = {
+ bus_info: "demo-device",
+ device_type: 0,
+ nickname: "Demo Camera",
+ manufacturer: "DeepWater Exploration",
+ name: "exploreHD",
+
+ vid: 1234,
+ pid: 5678,
+
+ is_managed: false,
+ followers: [],
+ device_info: {
+ device_name: "exploreHD Demo",
+ bus_info: "demo-device",
+ device_paths: ["/dev/video99"],
+ vid: 1234,
+ pid: 5678,
+ },
+ controls: [],
+ stream: {
+ device_path: "/dev/video99",
+ encode_type: "H264",
+ stream_type: "UDP",
+ endpoints: [{ host: "192.168.1.100", port: 5600 }],
+ width: 1920,
+ height: 1080,
+ interval: { numerator: 1, denominator: 30 },
+ enabled: true,
+ },
+ cameras: [
+ {
+ path: "/dev/video99",
+ formats: {
+ H264: [
+ {
+ width: 1920,
+ height: 1080,
+ intervals: [{ numerator: 1, denominator: 30 }],
+ },
+ ],
+ },
+ },
+ ],
+};
+
const NoDevicesConnected = () => {
return (
@@ -55,6 +103,8 @@ const DeviceListLayout = () => {
const { toast } = useToast();
+ const { isActive } = useTour();
+
const [devices, setDevices] = useState([] as DeviceModel[]);
const [savedPreferences, setSavedPreferences] = useState({
@@ -62,6 +112,7 @@ const DeviceListLayout = () => {
} as components["schemas"]["SavedPreferencesModel"]);
const [nextPort, setNextPort] = useState(5600);
+ const [demoDeviceProxy] = useState(() => proxy(DEMO_DEVICE));
const getNextPort = (devs: DeviceModel[]) => {
const allPorts = devs.flatMap((device) =>
@@ -186,28 +237,40 @@ const DeviceListLayout = () => {
device.stream.enabled = true;
};
+ const displayDevices =
+ isActive && devices.length === 0 ? [demoDeviceProxy] : devices;
+
return (
-
-
d.device_type == 2),
- enableStream,
- }}
- >
- {devices.map((device, index) => (
-
-
-
-
-
- ))}
- {devices.length === 0 &&
- (connected ? : )}
-
+
+
+
d.device_type == 2),
+ enableStream,
+ }}
+ >
+ {displayDevices.map((device, index) => (
+
+
+
+
+
+ ))}
+ {displayDevices.length === 0 &&
+ (connected ? : )}
+
+
);
};
diff --git a/frontend/src/components/dwe/cameras/nickname.tsx b/frontend/src/components/dwe/cameras/nickname.tsx
index 371fc466..3f80700f 100644
--- a/frontend/src/components/dwe/cameras/nickname.tsx
+++ b/frontend/src/components/dwe/cameras/nickname.tsx
@@ -5,6 +5,7 @@ import { Check, Edit2, X } from "lucide-react";
import { useSnapshot } from "valtio";
import DeviceContext from "@/contexts/DeviceContext";
import { API_CLIENT } from "@/api";
+import { TOUR_STEP_IDS } from "@/lib/tour-constants";
export const CameraNickname = () => {
const device = useContext(DeviceContext)!;
@@ -54,7 +55,7 @@ export const CameraNickname = () => {
};
return (
-
+
-
+
@@ -223,6 +223,7 @@ const EndpointList = ({
{/* Add Button */}