mirror of https://github.com/jetkvm/kvm.git
Compare commits
3 Commits
4da1bc3a42
...
e2e69e6975
Author | SHA1 | Date |
---|---|---|
|
e2e69e6975 | |
|
f8135263ed | |
|
d952480c2a |
|
@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||||
import { LuExternalLink } from "react-icons/lu";
|
import { LuExternalLink } from "react-icons/lu";
|
||||||
|
|
||||||
import { Button, LinkButton } from "@components/Button";
|
import { Button, LinkButton } from "@components/Button";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
|
|
||||||
import { InputFieldWithLabel } from "./InputField";
|
import { InputFieldWithLabel } from "./InputField";
|
||||||
import { SelectMenuBasic } from "./SelectMenuBasic";
|
import { SelectMenuBasic } from "./SelectMenuBasic";
|
||||||
|
@ -34,7 +34,7 @@ export function JigglerSetting({
|
||||||
const [timezones, setTimezones] = useState<string[]>([]);
|
const [timezones, setTimezones] = useState<string[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getTimezones", {}, resp => {
|
send("getTimezones", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setTimezones(resp.result as string[]);
|
setTimezones(resp.result as string[]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
export default function MacroBar() {
|
export default function MacroBar() {
|
||||||
const { macros, initialized, loadMacros, setSendFn } = useMacrosStore();
|
const { macros, initialized, loadMacros, setSendFn } = useMacrosStore();
|
||||||
const { executeMacro } = useKeyboard();
|
const { executeMacro } = useKeyboard();
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSendFn(send);
|
setSendFn(send);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useCallback , useEffect, useState } from "react";
|
import { useCallback , useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useJsonRpc } from "../hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "../hooks/useJsonRpc";
|
||||||
import notifications from "../notifications";
|
import notifications from "../notifications";
|
||||||
import { SettingsItem } from "../routes/devices.$id.settings";
|
import { SettingsItem } from "../routes/devices.$id.settings";
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ const usbPresets = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export function UsbDeviceSetting() {
|
export function UsbDeviceSetting() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [usbDeviceConfig, setUsbDeviceConfig] =
|
const [usbDeviceConfig, setUsbDeviceConfig] =
|
||||||
|
@ -67,7 +67,7 @@ export function UsbDeviceSetting() {
|
||||||
const [selectedPreset, setSelectedPreset] = useState<string>("default");
|
const [selectedPreset, setSelectedPreset] = useState<string>("default");
|
||||||
|
|
||||||
const syncUsbDeviceConfig = useCallback(() => {
|
const syncUsbDeviceConfig = useCallback(() => {
|
||||||
send("getUsbDevices", {}, resp => {
|
send("getUsbDevices", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Failed to load USB devices:", resp.error);
|
console.error("Failed to load USB devices:", resp.error);
|
||||||
notifications.error(
|
notifications.error(
|
||||||
|
@ -97,7 +97,7 @@ export function UsbDeviceSetting() {
|
||||||
const handleUsbConfigChange = useCallback(
|
const handleUsbConfigChange = useCallback(
|
||||||
(devices: UsbDeviceConfig) => {
|
(devices: UsbDeviceConfig) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
send("setUsbDevices", { devices }, async resp => {
|
send("setUsbDevices", { devices }, async (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set usb devices: ${resp.error.data || "Unknown error"}`,
|
`Failed to set usb devices: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -127,7 +127,7 @@ export function UsbDeviceSetting() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePresetChange = useCallback(
|
const handlePresetChange = useCallback(
|
||||||
async (e: React.ChangeEvent<HTMLSelectElement>) => {
|
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const newPreset = e.target.value;
|
const newPreset = e.target.value;
|
||||||
setSelectedPreset(newPreset);
|
setSelectedPreset(newPreset);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Button } from "@components/Button";
|
||||||
|
|
||||||
|
|
||||||
import { UsbConfigState } from "../hooks/stores";
|
import { UsbConfigState } from "../hooks/stores";
|
||||||
import { useJsonRpc } from "../hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "../hooks/useJsonRpc";
|
||||||
import notifications from "../notifications";
|
import notifications from "../notifications";
|
||||||
import { SettingsItem } from "../routes/devices.$id.settings";
|
import { SettingsItem } from "../routes/devices.$id.settings";
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ const usbConfigs = [
|
||||||
type UsbConfigMap = Record<string, USBConfig>;
|
type UsbConfigMap = Record<string, USBConfig>;
|
||||||
|
|
||||||
export function UsbInfoSetting() {
|
export function UsbInfoSetting() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [usbConfigProduct, setUsbConfigProduct] = useState("");
|
const [usbConfigProduct, setUsbConfigProduct] = useState("");
|
||||||
|
@ -94,7 +94,7 @@ export function UsbInfoSetting() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const syncUsbConfigProduct = useCallback(() => {
|
const syncUsbConfigProduct = useCallback(() => {
|
||||||
send("getUsbConfig", {}, resp => {
|
send("getUsbConfig", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Failed to load USB Config:", resp.error);
|
console.error("Failed to load USB Config:", resp.error);
|
||||||
notifications.error(
|
notifications.error(
|
||||||
|
@ -114,7 +114,7 @@ export function UsbInfoSetting() {
|
||||||
const handleUsbConfigChange = useCallback(
|
const handleUsbConfigChange = useCallback(
|
||||||
(usbConfig: USBConfig) => {
|
(usbConfig: USBConfig) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
send("setUsbConfig", { usbConfig }, async resp => {
|
send("setUsbConfig", { usbConfig }, async (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set usb config: ${resp.error.data || "Unknown error"}`,
|
`Failed to set usb config: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -137,7 +137,7 @@ export function UsbInfoSetting() {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getDeviceID", {}, async resp => {
|
send("getDeviceID", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
return notifications.error(
|
return notifications.error(
|
||||||
`Failed to get device ID: ${resp.error.data || "Unknown error"}`,
|
`Failed to get device ID: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -205,10 +205,10 @@ function USBConfigDialog({
|
||||||
product: "",
|
product: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const syncUsbConfig = useCallback(() => {
|
const syncUsbConfig = useCallback(() => {
|
||||||
send("getUsbConfig", {}, resp => {
|
send("getUsbConfig", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Failed to load USB Config:", resp.error);
|
console.error("Failed to load USB Config:", resp.error);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -74,7 +74,7 @@ export default function WebRTCVideo() {
|
||||||
const [blockWheelEvent, setBlockWheelEvent] = useState(false);
|
const [blockWheelEvent, setBlockWheelEvent] = useState(false);
|
||||||
|
|
||||||
// Misc states and hooks
|
// Misc states and hooks
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
// Video-related
|
// Video-related
|
||||||
useResizeObserver({
|
useResizeObserver({
|
||||||
|
@ -411,7 +411,7 @@ export default function WebRTCVideo() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const keyDownHandler = useCallback(
|
const keyDownHandler = useCallback(
|
||||||
async (e: KeyboardEvent) => {
|
(e: KeyboardEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const prev = useHidStore.getState();
|
const prev = useHidStore.getState();
|
||||||
let code = e.code;
|
let code = e.code;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||||
|
|
||||||
import { useJsonRpc } from "../../hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "../../hooks/useJsonRpc";
|
||||||
|
|
||||||
const LONG_PRESS_DURATION = 3000; // 3 seconds for long press
|
const LONG_PRESS_DURATION = 3000; // 3 seconds for long press
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export function ATXPowerControl() {
|
||||||
> | null>(null);
|
> | null>(null);
|
||||||
const [atxState, setAtxState] = useState<ATXState | null>(null);
|
const [atxState, setAtxState] = useState<ATXState | null>(null);
|
||||||
|
|
||||||
const [send] = useJsonRpc(function onRequest(resp) {
|
const { send } = useJsonRpc(function onRequest(resp) {
|
||||||
if (resp.method === "atxState") {
|
if (resp.method === "atxState") {
|
||||||
setAtxState(resp.params as ATXState);
|
setAtxState(resp.params as ATXState);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ export function ATXPowerControl() {
|
||||||
|
|
||||||
// Request initial state
|
// Request initial state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getATXState", {}, resp => {
|
send("getATXState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to get ATX state: ${resp.error.data || "Unknown error"}`,
|
`Failed to get ATX state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -54,7 +54,7 @@ export function ATXPowerControl() {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
// Send long press action
|
// Send long press action
|
||||||
console.log("Sending long press ATX power action");
|
console.log("Sending long press ATX power action");
|
||||||
send("setATXPowerAction", { action: "power-long" }, resp => {
|
send("setATXPowerAction", { action: "power-long" }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -75,7 +75,7 @@ export function ATXPowerControl() {
|
||||||
|
|
||||||
// Send short press action
|
// Send short press action
|
||||||
console.log("Sending short press ATX power action");
|
console.log("Sending short press ATX power action");
|
||||||
send("setATXPowerAction", { action: "power-short" }, resp => {
|
send("setATXPowerAction", { action: "power-short" }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -127,7 +127,7 @@ export function ATXPowerControl() {
|
||||||
LeadingIcon={LuRotateCcw}
|
LeadingIcon={LuRotateCcw}
|
||||||
text="Reset"
|
text="Reset"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
send("setATXPowerAction", { action: "reset" }, resp => {
|
send("setATXPowerAction", { action: "reset" }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
`Failed to send ATX power action: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useCallback, useEffect, useState } from "react";
|
||||||
import { Button } from "@components/Button";
|
import { Button } from "@components/Button";
|
||||||
import Card from "@components/Card";
|
import Card from "@components/Card";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import FieldLabel from "@components/FieldLabel";
|
import FieldLabel from "@components/FieldLabel";
|
||||||
import LoadingSpinner from "@components/LoadingSpinner";
|
import LoadingSpinner from "@components/LoadingSpinner";
|
||||||
|
@ -19,11 +19,11 @@ interface DCPowerState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DCPowerControl() {
|
export function DCPowerControl() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [powerState, setPowerState] = useState<DCPowerState | null>(null);
|
const [powerState, setPowerState] = useState<DCPowerState | null>(null);
|
||||||
|
|
||||||
const getDCPowerState = useCallback(() => {
|
const getDCPowerState = useCallback(() => {
|
||||||
send("getDCPowerState", {}, resp => {
|
send("getDCPowerState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to get DC power state: ${resp.error.data || "Unknown error"}`,
|
`Failed to get DC power state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -35,7 +35,7 @@ export function DCPowerControl() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const handlePowerToggle = (enabled: boolean) => {
|
const handlePowerToggle = (enabled: boolean) => {
|
||||||
send("setDCPowerState", { enabled }, resp => {
|
send("setDCPowerState", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set DC power state: ${resp.error.data || "Unknown error"}`,
|
`Failed to set DC power state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -47,7 +47,7 @@ export function DCPowerControl() {
|
||||||
};
|
};
|
||||||
const handleRestoreChange = (state: number) => {
|
const handleRestoreChange = (state: number) => {
|
||||||
// const state = powerState?.restoreState === 0 ? 1 : powerState?.restoreState === 1 ? 2 : 0;
|
// const state = powerState?.restoreState === 0 ? 1 : powerState?.restoreState === 1 ? 2 : 0;
|
||||||
send("setDCRestoreState", { state }, resp => {
|
send("setDCRestoreState", { state }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set DC power state: ${resp.error.data || "Unknown error"}`,
|
`Failed to set DC power state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
|
||||||
import { Button } from "@components/Button";
|
import { Button } from "@components/Button";
|
||||||
import Card from "@components/Card";
|
import Card from "@components/Card";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import { useUiStore } from "@/hooks/stores";
|
import { useUiStore } from "@/hooks/stores";
|
||||||
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
||||||
|
@ -17,7 +17,7 @@ interface SerialSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SerialConsole() {
|
export function SerialConsole() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [settings, setSettings] = useState<SerialSettings>({
|
const [settings, setSettings] = useState<SerialSettings>({
|
||||||
baudRate: "9600",
|
baudRate: "9600",
|
||||||
dataBits: "8",
|
dataBits: "8",
|
||||||
|
@ -26,7 +26,7 @@ export function SerialConsole() {
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getSerialSettings", {}, resp => {
|
send("getSerialSettings", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to get serial settings: ${resp.error.data || "Unknown error"}`,
|
`Failed to get serial settings: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -39,7 +39,7 @@ export function SerialConsole() {
|
||||||
|
|
||||||
const handleSettingChange = (setting: keyof SerialSettings, value: string) => {
|
const handleSettingChange = (setting: keyof SerialSettings, value: string) => {
|
||||||
const newSettings = { ...settings, [setting]: value };
|
const newSettings = { ...settings, [setting]: value };
|
||||||
send("setSerialSettings", { settings: newSettings }, resp => {
|
send("setSerialSettings", { settings: newSettings }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to update serial settings: ${resp.error.data || "Unknown error"}`,
|
`Failed to update serial settings: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
|
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
|
||||||
|
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import Card, { GridCard } from "@components/Card";
|
import Card, { GridCard } from "@components/Card";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { ATXPowerControl } from "@components/extensions/ATXPowerControl";
|
import { ATXPowerControl } from "@components/extensions/ATXPowerControl";
|
||||||
|
@ -39,12 +39,12 @@ const AVAILABLE_EXTENSIONS: Extension[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function ExtensionPopover() {
|
export default function ExtensionPopover() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [activeExtension, setActiveExtension] = useState<Extension | null>(null);
|
const [activeExtension, setActiveExtension] = useState<Extension | null>(null);
|
||||||
|
|
||||||
// Load active extension on component mount
|
// Load active extension on component mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getActiveExtension", {}, resp => {
|
send("getActiveExtension", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
const extensionId = resp.result as string;
|
const extensionId = resp.result as string;
|
||||||
if (extensionId) {
|
if (extensionId) {
|
||||||
|
@ -57,7 +57,7 @@ export default function ExtensionPopover() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const handleSetActiveExtension = (extension: Extension | null) => {
|
const handleSetActiveExtension = (extension: Extension | null) => {
|
||||||
send("setActiveExtension", { extensionId: extension?.id || "" }, resp => {
|
send("setActiveExtension", { extensionId: extension?.id || "" }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set active extension: ${resp.error.data || "Unknown error"}`,
|
`Failed to set active extension: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -16,13 +16,13 @@ import Card, { GridCard } from "@components/Card";
|
||||||
import { formatters } from "@/utils";
|
import { formatters } from "@/utils";
|
||||||
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
|
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
|
|
||||||
const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
|
const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
|
||||||
const diskDataChannelStats = useRTCStore(state => state.diskDataChannelStats);
|
const diskDataChannelStats = useRTCStore(state => state.diskDataChannelStats);
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const { remoteVirtualMediaState, setModalView, setRemoteVirtualMediaState } =
|
const { remoteVirtualMediaState, setModalView, setRemoteVirtualMediaState } =
|
||||||
useMountMediaStore();
|
useMountMediaStore();
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
|
||||||
}, [diskDataChannelStats]);
|
}, [diskDataChannelStats]);
|
||||||
|
|
||||||
const syncRemoteVirtualMediaState = useCallback(() => {
|
const syncRemoteVirtualMediaState = useCallback(() => {
|
||||||
send("getVirtualMediaState", {}, response => {
|
send("getVirtualMediaState", {}, (response: JsonRpcResponse) => {
|
||||||
if ("error" in response) {
|
if ("error" in response) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to get virtual media state: ${response.error.message}`,
|
`Failed to get virtual media state: ${response.error.message}`,
|
||||||
|
@ -59,7 +59,7 @@ const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
|
||||||
}, [send, setRemoteVirtualMediaState]);
|
}, [send, setRemoteVirtualMediaState]);
|
||||||
|
|
||||||
const handleUnmount = () => {
|
const handleUnmount = () => {
|
||||||
send("unmountImage", {}, response => {
|
send("unmountImage", {}, (response: JsonRpcResponse) => {
|
||||||
if ("error" in response) {
|
if ("error" in response) {
|
||||||
notifications.error(`Failed to unmount image: ${response.error.message}`);
|
notifications.error(`Failed to unmount image: ${response.error.message}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Button } from "@components/Button";
|
||||||
import { GridCard } from "@components/Card";
|
import { GridCard } from "@components/Card";
|
||||||
import { TextAreaWithLabel } from "@components/TextArea";
|
import { TextAreaWithLabel } from "@components/TextArea";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { useHidStore, useRTCStore, useUiStore, useSettingsStore } from "@/hooks/stores";
|
import { useHidStore, useRTCStore, useUiStore, useSettingsStore } from "@/hooks/stores";
|
||||||
import { keys, modifiers } from "@/keyboardMappings";
|
import { keys, modifiers } from "@/keyboardMappings";
|
||||||
import { KeyStroke, KeyboardLayout, selectedKeyboard } from "@/keyboardLayouts";
|
import { KeyStroke, KeyboardLayout, selectedKeyboard } from "@/keyboardLayouts";
|
||||||
|
@ -28,7 +28,7 @@ export default function PasteModal() {
|
||||||
const setPasteMode = useHidStore(state => state.setPasteModeEnabled);
|
const setPasteMode = useHidStore(state => state.setPasteModeEnabled);
|
||||||
const setDisableVideoFocusTrap = useUiStore(state => state.setDisableVideoFocusTrap);
|
const setDisableVideoFocusTrap = useUiStore(state => state.setDisableVideoFocusTrap);
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
||||||
|
|
||||||
const [invalidChars, setInvalidChars] = useState<string[]>([]);
|
const [invalidChars, setInvalidChars] = useState<string[]>([]);
|
||||||
|
@ -47,7 +47,7 @@ export default function PasteModal() {
|
||||||
}, [keyboardLayout]);
|
}, [keyboardLayout]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getKeyboardLayout", {}, resp => {
|
send("getKeyboardLayout", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setKeyboardLayout(resp.result as string);
|
setKeyboardLayout(resp.result as string);
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useClose } from "@headlessui/react";
|
||||||
|
|
||||||
import { GridCard } from "@components/Card";
|
import { GridCard } from "@components/Card";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { useRTCStore, useUiStore } from "@/hooks/stores";
|
import { useRTCStore, useUiStore } from "@/hooks/stores";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ export default function WakeOnLanModal() {
|
||||||
|
|
||||||
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const close = useClose();
|
const close = useClose();
|
||||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
const [addDeviceErrorMessage, setAddDeviceErrorMessage] = useState<string | null>(null);
|
const [addDeviceErrorMessage, setAddDeviceErrorMessage] = useState<string | null>(null);
|
||||||
|
@ -33,7 +33,7 @@ export default function WakeOnLanModal() {
|
||||||
setErrorMessage(null);
|
setErrorMessage(null);
|
||||||
if (rpcDataChannel?.readyState !== "open") return;
|
if (rpcDataChannel?.readyState !== "open") return;
|
||||||
|
|
||||||
send("sendWOLMagicPacket", { macAddress }, resp => {
|
send("sendWOLMagicPacket", { macAddress }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
const isInvalid = resp.error.data?.includes("invalid MAC address");
|
const isInvalid = resp.error.data?.includes("invalid MAC address");
|
||||||
if (isInvalid) {
|
if (isInvalid) {
|
||||||
|
@ -52,7 +52,7 @@ export default function WakeOnLanModal() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const syncStoredDevices = useCallback(() => {
|
const syncStoredDevices = useCallback(() => {
|
||||||
send("getWakeOnLanDevices", {}, resp => {
|
send("getWakeOnLanDevices", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("result" in resp) {
|
if ("result" in resp) {
|
||||||
setStoredDevices(resp.result as StoredDevice[]);
|
setStoredDevices(resp.result as StoredDevice[]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,7 +70,7 @@ export default function WakeOnLanModal() {
|
||||||
(index: number) => {
|
(index: number) => {
|
||||||
const updatedDevices = storedDevices.filter((_, i) => i !== index);
|
const updatedDevices = storedDevices.filter((_, i) => i !== index);
|
||||||
|
|
||||||
send("setWakeOnLanDevices", { params: { devices: updatedDevices } }, resp => {
|
send("setWakeOnLanDevices", { params: { devices: updatedDevices } }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Failed to update Wake-on-LAN devices:", resp.error);
|
console.error("Failed to update Wake-on-LAN devices:", resp.error);
|
||||||
} else {
|
} else {
|
||||||
|
@ -86,7 +86,7 @@ export default function WakeOnLanModal() {
|
||||||
if (!name || !macAddress) return;
|
if (!name || !macAddress) return;
|
||||||
const updatedDevices = [...storedDevices, { name, macAddress }];
|
const updatedDevices = [...storedDevices, { name, macAddress }];
|
||||||
console.log("updatedDevices", updatedDevices);
|
console.log("updatedDevices", updatedDevices);
|
||||||
send("setWakeOnLanDevices", { params: { devices: updatedDevices } }, resp => {
|
send("setWakeOnLanDevices", { params: { devices: updatedDevices } }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Failed to add Wake-on-LAN device:", resp.error);
|
console.error("Failed to add Wake-on-LAN device:", resp.error);
|
||||||
setAddDeviceErrorMessage("Failed to add device");
|
setAddDeviceErrorMessage("Failed to add device");
|
||||||
|
|
|
@ -833,7 +833,7 @@ export const useMacrosStore = create<MacrosState>((set, get) => ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
sendFn("getKeyboardMacros", {}, response => {
|
sendFn("getKeyboardMacros", {}, (response: JsonRpcResponse) => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.error("Error loading macros:", response.error);
|
console.error("Error loading macros:", response.error);
|
||||||
reject(new Error(response.error.message));
|
reject(new Error(response.error.message));
|
||||||
|
|
|
@ -78,5 +78,5 @@ export function useJsonRpc(onRequest?: (payload: JsonRpcRequest) => void) {
|
||||||
};
|
};
|
||||||
}, [rpcDataChannel, onRequest]);
|
}, [rpcDataChannel, onRequest]);
|
||||||
|
|
||||||
return [send];
|
return { send };
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { keys, modifiers } from "@/keyboardMappings";
|
import { keys, modifiers } from "@/keyboardMappings";
|
||||||
|
|
||||||
export default function useKeyboard() {
|
export default function useKeyboard() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
||||||
const updateActiveKeysAndModifiers = useHidStore(
|
const updateActiveKeysAndModifiers = useHidStore(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { lazy } from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import {
|
import {
|
||||||
|
@ -9,46 +10,45 @@ import {
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/16/solid";
|
import { ExclamationTriangleIcon } from "@heroicons/react/16/solid";
|
||||||
|
|
||||||
|
import { CLOUD_API, DEVICE_API } from "@/ui.config";
|
||||||
|
import api from "@/api";
|
||||||
|
import Root from "@/root";
|
||||||
|
import Card from "@components/Card";
|
||||||
import EmptyCard from "@components/EmptyCard";
|
import EmptyCard from "@components/EmptyCard";
|
||||||
import NotFoundPage from "@components/NotFoundPage";
|
import NotFoundPage from "@components/NotFoundPage";
|
||||||
|
import DeviceRoute, { LocalDevice } from "@routes/devices.$id";
|
||||||
|
import WelcomeRoute, { DeviceStatus } from "@routes/welcome-local";
|
||||||
|
import LoginLocalRoute from "@routes/login-local";
|
||||||
|
import WelcomeLocalModeRoute from "@routes/welcome-local.mode";
|
||||||
|
import WelcomeLocalPasswordRoute from "@routes/welcome-local.password";
|
||||||
|
import AdoptRoute from "@routes/adopt";
|
||||||
|
import SetupRoute from "@routes/devices.$id.setup";
|
||||||
import DevicesIdDeregister from "@routes/devices.$id.deregister";
|
import DevicesIdDeregister from "@routes/devices.$id.deregister";
|
||||||
import DeviceIdRename from "@routes/devices.$id.rename";
|
import DeviceIdRename from "@routes/devices.$id.rename";
|
||||||
import AdoptRoute from "@routes/adopt";
|
|
||||||
import SignupRoute from "@routes/signup";
|
|
||||||
import LoginRoute from "@routes/login";
|
|
||||||
import SetupRoute from "@routes/devices.$id.setup";
|
|
||||||
import DevicesRoute from "@routes/devices";
|
import DevicesRoute from "@routes/devices";
|
||||||
import DeviceRoute, { LocalDevice } from "@routes/devices.$id";
|
import SettingsIndexRoute from "@routes/devices.$id.settings._index";
|
||||||
import Card from "@components/Card";
|
import SettingsAccessIndexRoute from "@routes/devices.$id.settings.access._index";
|
||||||
import DevicesAlreadyAdopted from "@routes/devices.already-adopted";
|
const Notifications = lazy(() => import("@/notifications"));
|
||||||
|
const SignupRoute = lazy(() => import("@routes/signup"));
|
||||||
import Root from "./root";
|
const LoginRoute = lazy(() => import("@routes/login"));
|
||||||
import Notifications from "./notifications";
|
const DevicesAlreadyAdopted = lazy(() => import("@routes/devices.already-adopted"));
|
||||||
import LoginLocalRoute from "./routes/login-local";
|
const OtherSessionRoute = lazy(() => import("@routes/devices.$id.other-session"));
|
||||||
import WelcomeLocalModeRoute from "./routes/welcome-local.mode";
|
const MountRoute = lazy(() => import("./routes/devices.$id.mount"));
|
||||||
import WelcomeRoute, { DeviceStatus } from "./routes/welcome-local";
|
const SettingsRoute = lazy(() => import("@routes/devices.$id.settings"));
|
||||||
import WelcomeLocalPasswordRoute from "./routes/welcome-local.password";
|
const SettingsMouseRoute = lazy(() => import("@routes/devices.$id.settings.mouse"));
|
||||||
import { CLOUD_API, DEVICE_API } from "./ui.config";
|
const SettingsKeyboardRoute = lazy(() => import("@routes/devices.$id.settings.keyboard"));
|
||||||
import OtherSessionRoute from "./routes/devices.$id.other-session";
|
const SettingsAdvancedRoute = lazy(() => import("@routes/devices.$id.settings.advanced"));
|
||||||
import MountRoute from "./routes/devices.$id.mount";
|
const SettingsHardwareRoute = lazy(() => import("@routes/devices.$id.settings.hardware"));
|
||||||
import * as SettingsRoute from "./routes/devices.$id.settings";
|
const SettingsVideoRoute = lazy(() => import("@routes/devices.$id.settings.video"));
|
||||||
import SettingsMouseRoute from "./routes/devices.$id.settings.mouse";
|
const SettingsAppearanceRoute = lazy(() => import("@routes/devices.$id.settings.appearance"));
|
||||||
import SettingsKeyboardRoute from "./routes/devices.$id.settings.keyboard";
|
const SettingsGeneralIndexRoute = lazy(() => import("@routes/devices.$id.settings.general._index"));
|
||||||
import api from "./api";
|
const SettingsGeneralRebootRoute = lazy(() => import("@routes/devices.$id.settings.general.reboot"));
|
||||||
import * as SettingsIndexRoute from "./routes/devices.$id.settings._index";
|
const SettingsGeneralUpdateRoute = lazy(() => import("@routes/devices.$id.settings.general.update"));
|
||||||
import SettingsAdvancedRoute from "./routes/devices.$id.settings.advanced";
|
const SettingsNetworkRoute = lazy(() => import("@routes/devices.$id.settings.network"));
|
||||||
import SettingsAccessIndexRoute from "./routes/devices.$id.settings.access._index";
|
const SecurityAccessLocalAuthRoute = lazy(() => import("@routes/devices.$id.settings.access.local-auth"));
|
||||||
import SettingsHardwareRoute from "./routes/devices.$id.settings.hardware";
|
const SettingsMacrosRoute = lazy(() => import("@routes/devices.$id.settings.macros"));
|
||||||
import SettingsVideoRoute from "./routes/devices.$id.settings.video";
|
const SettingsMacrosAddRoute = lazy(() => import("@routes/devices.$id.settings.macros.add"));
|
||||||
import SettingsAppearanceRoute from "./routes/devices.$id.settings.appearance";
|
const SettingsMacrosEditRoute = lazy(() => import("@routes/devices.$id.settings.macros.edit"));
|
||||||
import * as SettingsGeneralIndexRoute from "./routes/devices.$id.settings.general._index";
|
|
||||||
import SettingsGeneralRebootRoute from "./routes/devices.$id.settings.general.reboot";
|
|
||||||
import SettingsGeneralUpdateRoute from "./routes/devices.$id.settings.general.update";
|
|
||||||
import SettingsNetworkRoute from "./routes/devices.$id.settings.network";
|
|
||||||
import SecurityAccessLocalAuthRoute from "./routes/devices.$id.settings.access.local-auth";
|
|
||||||
import SettingsMacrosRoute from "./routes/devices.$id.settings.macros";
|
|
||||||
import SettingsMacrosAddRoute from "./routes/devices.$id.settings.macros.add";
|
|
||||||
import SettingsMacrosEditRoute from "./routes/devices.$id.settings.macros.edit";
|
|
||||||
|
|
||||||
export const isOnDevice = import.meta.env.MODE === "device";
|
export const isOnDevice = import.meta.env.MODE === "device";
|
||||||
export const isInCloud = !isOnDevice;
|
export const isInCloud = !isOnDevice;
|
||||||
|
@ -128,7 +128,7 @@ if (isOnDevice) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: "settings",
|
||||||
element: <SettingsRoute.default />,
|
element: <SettingsRoute />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
|
@ -139,7 +139,7 @@ if (isOnDevice) {
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
element: <SettingsGeneralIndexRoute.default />,
|
element: <SettingsGeneralIndexRoute />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "reboot",
|
path: "reboot",
|
||||||
|
@ -265,7 +265,7 @@ if (isOnDevice) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: "settings",
|
||||||
element: <SettingsRoute.default />,
|
element: <SettingsRoute />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
|
@ -276,7 +276,7 @@ if (isOnDevice) {
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
element: <SettingsGeneralIndexRoute.default />,
|
element: <SettingsGeneralIndexRoute />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "update",
|
path: "update",
|
||||||
|
|
|
@ -27,7 +27,7 @@ import NetBootIcon from "@/assets/netboot-icon.svg";
|
||||||
import Fieldset from "@/components/Fieldset";
|
import Fieldset from "@/components/Fieldset";
|
||||||
import { DEVICE_API } from "@/ui.config";
|
import { DEVICE_API } from "@/ui.config";
|
||||||
|
|
||||||
import { useJsonRpc } from "../hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "../hooks/useJsonRpc";
|
||||||
import notifications from "../notifications";
|
import notifications from "../notifications";
|
||||||
import { isOnDevice } from "../main";
|
import { isOnDevice } from "../main";
|
||||||
import { cx } from "../cva.config";
|
import { cx } from "../cva.config";
|
||||||
|
@ -64,10 +64,10 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
||||||
setRemoteVirtualMediaState(null);
|
setRemoteVirtualMediaState(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
async function syncRemoteVirtualMediaState() {
|
async function syncRemoteVirtualMediaState() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
send("getVirtualMediaState", {}, resp => {
|
send("getVirtualMediaState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
reject(new Error(resp.error.message));
|
reject(new Error(resp.error.message));
|
||||||
} else {
|
} else {
|
||||||
|
@ -89,7 +89,7 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
||||||
console.log(`Mounting ${url} as ${mode}`);
|
console.log(`Mounting ${url} as ${mode}`);
|
||||||
|
|
||||||
setMountInProgress(true);
|
setMountInProgress(true);
|
||||||
send("mountWithHTTP", { url, mode }, async resp => {
|
send("mountWithHTTP", { url, mode }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) triggerError(resp.error.message);
|
if ("error" in resp) triggerError(resp.error.message);
|
||||||
|
|
||||||
clearMountMediaState();
|
clearMountMediaState();
|
||||||
|
@ -108,7 +108,7 @@ export function Dialog({ onClose }: { onClose: () => void }) {
|
||||||
console.log(`Mounting ${fileName} as ${mode}`);
|
console.log(`Mounting ${fileName} as ${mode}`);
|
||||||
|
|
||||||
setMountInProgress(true);
|
setMountInProgress(true);
|
||||||
send("mountWithStorage", { filename: fileName, mode }, async resp => {
|
send("mountWithStorage", { filename: fileName, mode }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) triggerError(resp.error.message);
|
if ("error" in resp) triggerError(resp.error.message);
|
||||||
|
|
||||||
clearMountMediaState();
|
clearMountMediaState();
|
||||||
|
@ -689,7 +689,7 @@ function DeviceFileView({
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const filesPerPage = 5;
|
const filesPerPage = 5;
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
interface StorageSpace {
|
interface StorageSpace {
|
||||||
bytesUsed: number;
|
bytesUsed: number;
|
||||||
|
@ -718,12 +718,12 @@ function DeviceFileView({
|
||||||
}, [storageSpace]);
|
}, [storageSpace]);
|
||||||
|
|
||||||
const syncStorage = useCallback(() => {
|
const syncStorage = useCallback(() => {
|
||||||
send("listStorageFiles", {}, res => {
|
send("listStorageFiles", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in res) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Error listing storage files: ${res.error}`);
|
notifications.error(`Error listing storage files: ${resp.error}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { files } = res.result as StorageFiles;
|
const { files } = resp.result as StorageFiles;
|
||||||
const formattedFiles = files.map(file => ({
|
const formattedFiles = files.map(file => ({
|
||||||
name: file.filename,
|
name: file.filename,
|
||||||
size: formatters.bytes(file.size),
|
size: formatters.bytes(file.size),
|
||||||
|
@ -733,13 +733,13 @@ function DeviceFileView({
|
||||||
setOnStorageFiles(formattedFiles);
|
setOnStorageFiles(formattedFiles);
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getStorageSpace", {}, res => {
|
send("getStorageSpace", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in res) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Error getting storage space: ${res.error}`);
|
notifications.error(`Error getting storage space: ${resp.error}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const space = res.result as StorageSpace;
|
const space = resp.result as StorageSpace;
|
||||||
setStorageSpace(space);
|
setStorageSpace(space);
|
||||||
});
|
});
|
||||||
}, [send, setOnStorageFiles, setStorageSpace]);
|
}, [send, setOnStorageFiles, setStorageSpace]);
|
||||||
|
@ -762,9 +762,9 @@ function DeviceFileView({
|
||||||
|
|
||||||
function handleDeleteFile(file: { name: string; size: string; createdAt: string }) {
|
function handleDeleteFile(file: { name: string; size: string; createdAt: string }) {
|
||||||
console.log("Deleting file:", file);
|
console.log("Deleting file:", file);
|
||||||
send("deleteStorageFile", { filename: file.name }, res => {
|
send("deleteStorageFile", { filename: file.name }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in res) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Error deleting file: ${res.error}`);
|
notifications.error(`Error deleting file: ${resp.error}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1001,7 @@ function UploadFileView({
|
||||||
const [fileError, setFileError] = useState<string | null>(null);
|
const [fileError, setFileError] = useState<string | null>(null);
|
||||||
const [uploadError, setUploadError] = useState<string | null>(null);
|
const [uploadError, setUploadError] = useState<string | null>(null);
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const rtcDataChannelRef = useRef<RTCDataChannel | null>(null);
|
const rtcDataChannelRef = useRef<RTCDataChannel | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1216,7 +1216,7 @@ function UploadFileView({
|
||||||
setUploadState("uploading");
|
setUploadState("uploading");
|
||||||
console.log("Upload state set to 'uploading'");
|
console.log("Upload state set to 'uploading'");
|
||||||
|
|
||||||
send("startStorageFileUpload", { filename: file.name, size: file.size }, resp => {
|
send("startStorageFileUpload", { filename: file.name, size: file.size }, (resp: JsonRpcResponse) => {
|
||||||
console.log("startStorageFileUpload response:", resp);
|
console.log("startStorageFileUpload response:", resp);
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
console.error("Upload error:", resp.error.message);
|
console.error("Upload error:", resp.error.message);
|
||||||
|
|
|
@ -2,6 +2,12 @@ import { LoaderFunctionArgs, redirect } from "react-router-dom";
|
||||||
|
|
||||||
import { getDeviceUiPath } from "../hooks/useAppNavigation";
|
import { getDeviceUiPath } from "../hooks/useAppNavigation";
|
||||||
|
|
||||||
export function loader({ params }: LoaderFunctionArgs) {
|
const loader = ({ params }: LoaderFunctionArgs) => {
|
||||||
return redirect(getDeviceUiPath("/settings/general", params.id));
|
return redirect(getDeviceUiPath("/settings/general", params.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function SettingIndexRoute() {
|
||||||
|
return (<></>);
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingIndexRoute.loader = loader;
|
|
@ -12,7 +12,7 @@ import { SettingsSectionHeader } from "@/components/SettingsSectionHeader";
|
||||||
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import { DEVICE_API } from "@/ui.config";
|
import { DEVICE_API } from "@/ui.config";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { isOnDevice } from "@/main";
|
import { isOnDevice } from "@/main";
|
||||||
import { TextAreaWithLabel } from "@components/TextArea";
|
import { TextAreaWithLabel } from "@components/TextArea";
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
const { navigateTo } = useDeviceUiNavigation();
|
const { navigateTo } = useDeviceUiNavigation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const [isAdopted, setAdopted] = useState(false);
|
const [isAdopted, setAdopted] = useState(false);
|
||||||
const [deviceId, setDeviceId] = useState<string | null>(null);
|
const [deviceId, setDeviceId] = useState<string | null>(null);
|
||||||
|
@ -56,7 +56,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
const [tlsKey, setTlsKey] = useState<string>("");
|
const [tlsKey, setTlsKey] = useState<string>("");
|
||||||
|
|
||||||
const getCloudState = useCallback(() => {
|
const getCloudState = useCallback(() => {
|
||||||
send("getCloudState", {}, resp => {
|
send("getCloudState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return console.error(resp.error);
|
if ("error" in resp) return console.error(resp.error);
|
||||||
const cloudState = resp.result as CloudState;
|
const cloudState = resp.result as CloudState;
|
||||||
setAdopted(cloudState.connected);
|
setAdopted(cloudState.connected);
|
||||||
|
@ -77,7 +77,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const getTLSState = useCallback(() => {
|
const getTLSState = useCallback(() => {
|
||||||
send("getTLSState", {}, resp => {
|
send("getTLSState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return console.error(resp.error);
|
if ("error" in resp) return console.error(resp.error);
|
||||||
const tlsState = resp.result as TLSState;
|
const tlsState = resp.result as TLSState;
|
||||||
|
|
||||||
|
@ -87,8 +87,8 @@ export default function SettingsAccessIndexRoute() {
|
||||||
});
|
});
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const deregisterDevice = async () => {
|
const deregisterDevice = () => {
|
||||||
send("deregisterDevice", {}, resp => {
|
send("deregisterDevice", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to de-register device: ${resp.error.data || "Unknown error"}`,
|
`Failed to de-register device: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -110,7 +110,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
send("setCloudUrl", { apiUrl: cloudApiUrl, appUrl: cloudAppUrl }, resp => {
|
send("setCloudUrl", { apiUrl: cloudApiUrl, appUrl: cloudAppUrl }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to update cloud URL: ${resp.error.data || "Unknown error"}`,
|
`Failed to update cloud URL: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -156,7 +156,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
state.privateKey = key;
|
state.privateKey = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
send("setTLSState", { state }, resp => {
|
send("setTLSState", { state }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to update TLS settings: ${resp.error.data || "Unknown error"}`,
|
`Failed to update TLS settings: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -198,7 +198,7 @@ export default function SettingsAccessIndexRoute() {
|
||||||
getCloudState();
|
getCloudState();
|
||||||
getTLSState();
|
getTLSState();
|
||||||
|
|
||||||
send("getDeviceID", {}, async resp => {
|
send("getDeviceID", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return console.error(resp.error);
|
if ("error" in resp) return console.error(resp.error);
|
||||||
setDeviceId(resp.result as string);
|
setDeviceId(resp.result as string);
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,14 +8,14 @@ import { ConfirmDialog } from "../components/ConfirmDialog";
|
||||||
import { SettingsPageHeader } from "../components/SettingsPageheader";
|
import { SettingsPageHeader } from "../components/SettingsPageheader";
|
||||||
import { TextAreaWithLabel } from "../components/TextArea";
|
import { TextAreaWithLabel } from "../components/TextArea";
|
||||||
import { useSettingsStore } from "../hooks/stores";
|
import { useSettingsStore } from "../hooks/stores";
|
||||||
import { useJsonRpc } from "../hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "../hooks/useJsonRpc";
|
||||||
import { isOnDevice } from "../main";
|
import { isOnDevice } from "../main";
|
||||||
import notifications from "../notifications";
|
import notifications from "../notifications";
|
||||||
|
|
||||||
import { SettingsItem } from "./devices.$id.settings";
|
import { SettingsItem } from "./devices.$id.settings";
|
||||||
|
|
||||||
export default function SettingsAdvancedRoute() {
|
export default function SettingsAdvancedRoute() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const [sshKey, setSSHKey] = useState<string>("");
|
const [sshKey, setSSHKey] = useState<string>("");
|
||||||
const setDeveloperMode = useSettingsStore(state => state.setDeveloperMode);
|
const setDeveloperMode = useSettingsStore(state => state.setDeveloperMode);
|
||||||
|
@ -27,35 +27,35 @@ export default function SettingsAdvancedRoute() {
|
||||||
const settings = useSettingsStore();
|
const settings = useSettingsStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getDevModeState", {}, resp => {
|
send("getDevModeState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
const result = resp.result as { enabled: boolean };
|
const result = resp.result as { enabled: boolean };
|
||||||
setDeveloperMode(result.enabled);
|
setDeveloperMode(result.enabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getSSHKeyState", {}, resp => {
|
send("getSSHKeyState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setSSHKey(resp.result as string);
|
setSSHKey(resp.result as string);
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getUsbEmulationState", {}, resp => {
|
send("getUsbEmulationState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setUsbEmulationEnabled(resp.result as boolean);
|
setUsbEmulationEnabled(resp.result as boolean);
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getDevChannelState", {}, resp => {
|
send("getDevChannelState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setDevChannel(resp.result as boolean);
|
setDevChannel(resp.result as boolean);
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getLocalLoopbackOnly", {}, resp => {
|
send("getLocalLoopbackOnly", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setLocalLoopbackOnly(resp.result as boolean);
|
setLocalLoopbackOnly(resp.result as boolean);
|
||||||
});
|
});
|
||||||
}, [send, setDeveloperMode]);
|
}, [send, setDeveloperMode]);
|
||||||
|
|
||||||
const getUsbEmulationState = useCallback(() => {
|
const getUsbEmulationState = useCallback(() => {
|
||||||
send("getUsbEmulationState", {}, resp => {
|
send("getUsbEmulationState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setUsbEmulationEnabled(resp.result as boolean);
|
setUsbEmulationEnabled(resp.result as boolean);
|
||||||
});
|
});
|
||||||
|
@ -63,7 +63,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
|
|
||||||
const handleUsbEmulationToggle = useCallback(
|
const handleUsbEmulationToggle = useCallback(
|
||||||
(enabled: boolean) => {
|
(enabled: boolean) => {
|
||||||
send("setUsbEmulationState", { enabled: enabled }, resp => {
|
send("setUsbEmulationState", { enabled: enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to ${enabled ? "enable" : "disable"} USB emulation: ${resp.error.data || "Unknown error"}`,
|
`Failed to ${enabled ? "enable" : "disable"} USB emulation: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -78,7 +78,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleResetConfig = useCallback(() => {
|
const handleResetConfig = useCallback(() => {
|
||||||
send("resetConfig", {}, resp => {
|
send("resetConfig", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to reset configuration: ${resp.error.data || "Unknown error"}`,
|
`Failed to reset configuration: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -90,7 +90,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const handleUpdateSSHKey = useCallback(() => {
|
const handleUpdateSSHKey = useCallback(() => {
|
||||||
send("setSSHKeyState", { sshKey }, resp => {
|
send("setSSHKeyState", { sshKey }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to update SSH key: ${resp.error.data || "Unknown error"}`,
|
`Failed to update SSH key: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -103,7 +103,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
|
|
||||||
const handleDevModeChange = useCallback(
|
const handleDevModeChange = useCallback(
|
||||||
(developerMode: boolean) => {
|
(developerMode: boolean) => {
|
||||||
send("setDevModeState", { enabled: developerMode }, resp => {
|
send("setDevModeState", { enabled: developerMode }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set dev mode: ${resp.error.data || "Unknown error"}`,
|
`Failed to set dev mode: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -118,7 +118,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
|
|
||||||
const handleDevChannelChange = useCallback(
|
const handleDevChannelChange = useCallback(
|
||||||
(enabled: boolean) => {
|
(enabled: boolean) => {
|
||||||
send("setDevChannelState", { enabled }, resp => {
|
send("setDevChannelState", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set dev channel state: ${resp.error.data || "Unknown error"}`,
|
`Failed to set dev channel state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -133,7 +133,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
|
|
||||||
const applyLoopbackOnlyMode = useCallback(
|
const applyLoopbackOnlyMode = useCallback(
|
||||||
(enabled: boolean) => {
|
(enabled: boolean) => {
|
||||||
send("setLocalLoopbackOnly", { enabled }, resp => {
|
send("setLocalLoopbackOnly", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to ${enabled ? "enable" : "disable"} loopback-only mode: ${resp.error.data || "Unknown error"}`,
|
`Failed to ${enabled ? "enable" : "disable"} loopback-only mode: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import { useState , useEffect } from "react";
|
import { useState , useEffect } from "react";
|
||||||
|
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
|
|
||||||
import { SettingsPageHeader } from "../components/SettingsPageheader";
|
import { SettingsPageHeader } from "../components/SettingsPageheader";
|
||||||
import { Button } from "../components/Button";
|
import { Button } from "../components/Button";
|
||||||
|
@ -13,7 +13,7 @@ import { useDeviceStore } from "../hooks/stores";
|
||||||
import { SettingsItem } from "./devices.$id.settings";
|
import { SettingsItem } from "./devices.$id.settings";
|
||||||
|
|
||||||
export default function SettingsGeneralRoute() {
|
export default function SettingsGeneralRoute() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const { navigateTo } = useDeviceUiNavigation();
|
const { navigateTo } = useDeviceUiNavigation();
|
||||||
const [autoUpdate, setAutoUpdate] = useState(true);
|
const [autoUpdate, setAutoUpdate] = useState(true);
|
||||||
|
|
||||||
|
@ -24,14 +24,14 @@ export default function SettingsGeneralRoute() {
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getAutoUpdateState", {}, resp => {
|
send("getAutoUpdateState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setAutoUpdate(resp.result as boolean);
|
setAutoUpdate(resp.result as boolean);
|
||||||
});
|
});
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const handleAutoUpdateChange = (enabled: boolean) => {
|
const handleAutoUpdateChange = (enabled: boolean) => {
|
||||||
send("setAutoUpdateState", { enabled }, resp => {
|
send("setAutoUpdateState", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set auto-update: ${resp.error.data || "Unknown error"}`,
|
`Failed to set auto-update: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Button } from "@components/Button";
|
||||||
|
|
||||||
export default function SettingsGeneralRebootRoute() {
|
export default function SettingsGeneralRebootRoute() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const onConfirmUpdate = useCallback(() => {
|
const onConfirmUpdate = useCallback(() => {
|
||||||
// This is where we send the RPC to the golang binary
|
// This is where we send the RPC to the golang binary
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { CheckCircleIcon } from "@heroicons/react/20/solid";
|
import { CheckCircleIcon } from "@heroicons/react/20/solid";
|
||||||
|
|
||||||
import Card from "@/components/Card";
|
import Card from "@/components/Card";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { Button } from "@components/Button";
|
import { Button } from "@components/Button";
|
||||||
import { UpdateState, useDeviceStore, useUpdateStore } from "@/hooks/stores";
|
import { UpdateState, useDeviceStore, useUpdateStore } from "@/hooks/stores";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
|
@ -16,7 +16,7 @@ export default function SettingsGeneralUpdateRoute() {
|
||||||
const { updateSuccess } = location.state || {};
|
const { updateSuccess } = location.state || {};
|
||||||
|
|
||||||
const { setModalView, otaState } = useUpdateStore();
|
const { setModalView, otaState } = useUpdateStore();
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const onConfirmUpdate = useCallback(() => {
|
const onConfirmUpdate = useCallback(() => {
|
||||||
send("tryUpdate", {});
|
send("tryUpdate", {});
|
||||||
|
@ -62,7 +62,7 @@ export function Dialog({
|
||||||
const { modalView, setModalView, otaState } = useUpdateStore();
|
const { modalView, setModalView, otaState } = useUpdateStore();
|
||||||
|
|
||||||
const onFinishedLoading = useCallback(
|
const onFinishedLoading = useCallback(
|
||||||
async (versionInfo: SystemVersionInfo) => {
|
(versionInfo: SystemVersionInfo) => {
|
||||||
const hasUpdate =
|
const hasUpdate =
|
||||||
versionInfo?.systemUpdateAvailable || versionInfo?.appUpdateAvailable;
|
versionInfo?.systemUpdateAvailable || versionInfo?.appUpdateAvailable;
|
||||||
|
|
||||||
|
@ -134,14 +134,14 @@ function LoadingState({
|
||||||
}) {
|
}) {
|
||||||
const [progressWidth, setProgressWidth] = useState("0%");
|
const [progressWidth, setProgressWidth] = useState("0%");
|
||||||
const abortControllerRef = useRef<AbortController | null>(null);
|
const abortControllerRef = useRef<AbortController | null>(null);
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const setAppVersion = useDeviceStore(state => state.setAppVersion);
|
const setAppVersion = useDeviceStore(state => state.setAppVersion);
|
||||||
const setSystemVersion = useDeviceStore(state => state.setSystemVersion);
|
const setSystemVersion = useDeviceStore(state => state.setSystemVersion);
|
||||||
|
|
||||||
const getVersionInfo = useCallback(() => {
|
const getVersionInfo = useCallback(() => {
|
||||||
return new Promise<SystemVersionInfo>((resolve, reject) => {
|
return new Promise<SystemVersionInfo>((resolve, reject) => {
|
||||||
send("getUpdateStatus", {}, async resp => {
|
send("getUpdateStatus", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Failed to check for updates: ${resp.error}`);
|
notifications.error(`Failed to check for updates: ${resp.error}`);
|
||||||
reject(new Error("Failed to check for updates"));
|
reject(new Error("Failed to check for updates"));
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useEffect } from "react";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { SettingsItem } from "@routes/devices.$id.settings";
|
import { SettingsItem } from "@routes/devices.$id.settings";
|
||||||
import { BacklightSettings, useSettingsStore } from "@/hooks/stores";
|
import { BacklightSettings, useSettingsStore } from "@/hooks/stores";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
||||||
import { UsbDeviceSetting } from "@components/UsbDeviceSetting";
|
import { UsbDeviceSetting } from "@components/UsbDeviceSetting";
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import { UsbInfoSetting } from "../components/UsbInfoSetting";
|
||||||
import { FeatureFlag } from "../components/FeatureFlag";
|
import { FeatureFlag } from "../components/FeatureFlag";
|
||||||
|
|
||||||
export default function SettingsHardwareRoute() {
|
export default function SettingsHardwareRoute() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const settings = useSettingsStore();
|
const settings = useSettingsStore();
|
||||||
|
|
||||||
const setDisplayRotation = useSettingsStore(state => state.setDisplayRotation);
|
const setDisplayRotation = useSettingsStore(state => state.setDisplayRotation);
|
||||||
|
@ -23,7 +23,7 @@ export default function SettingsHardwareRoute() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDisplayRotationSave = () => {
|
const handleDisplayRotationSave = () => {
|
||||||
send("setDisplayRotation", { params: { rotation: settings.displayRotation } }, resp => {
|
send("setDisplayRotation", { params: { rotation: settings.displayRotation } }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set display orientation: ${resp.error.data || "Unknown error"}`,
|
`Failed to set display orientation: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -48,7 +48,7 @@ export default function SettingsHardwareRoute() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBacklightSettingsSave = () => {
|
const handleBacklightSettingsSave = () => {
|
||||||
send("setBacklightSettings", { params: settings.backlightSettings }, resp => {
|
send("setBacklightSettings", { params: settings.backlightSettings }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set backlight settings: ${resp.error.data || "Unknown error"}`,
|
`Failed to set backlight settings: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -60,7 +60,7 @@ export default function SettingsHardwareRoute() {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getBacklightSettings", {}, resp => {
|
send("getBacklightSettings", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
return notifications.error(
|
return notifications.error(
|
||||||
`Failed to get backlight settings: ${resp.error.data || "Unknown error"}`,
|
`Failed to get backlight settings: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useCallback, useEffect, useMemo } from "react";
|
import { useCallback, useEffect, useMemo } from "react";
|
||||||
|
|
||||||
import { KeyboardLedSync, useSettingsStore } from "@/hooks/stores";
|
import { KeyboardLedSync, useSettingsStore } from "@/hooks/stores";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { keyboardOptions } from "@/keyboardLayouts";
|
import { keyboardOptions } from "@/keyboardLayouts";
|
||||||
|
@ -39,10 +39,10 @@ export default function SettingsKeyboardRoute() {
|
||||||
{ value: "host", label: "Host Only" },
|
{ value: "host", label: "Host Only" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getKeyboardLayout", {}, resp => {
|
send("getKeyboardLayout", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setKeyboardLayout(resp.result as string);
|
setKeyboardLayout(resp.result as string);
|
||||||
});
|
});
|
||||||
|
@ -51,7 +51,7 @@ export default function SettingsKeyboardRoute() {
|
||||||
const onKeyboardLayoutChange = useCallback(
|
const onKeyboardLayoutChange = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const layout = e.target.value;
|
const layout = e.target.value;
|
||||||
send("setKeyboardLayout", { layout }, resp => {
|
send("setKeyboardLayout", { layout }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set keyboard layout: ${resp.error.data || "Unknown error"}`,
|
`Failed to set keyboard layout: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import PointingFinger from "@/assets/pointing-finger.svg";
|
||||||
import { GridCard } from "@/components/Card";
|
import { GridCard } from "@/components/Card";
|
||||||
import { Checkbox } from "@/components/Checkbox";
|
import { Checkbox } from "@/components/Checkbox";
|
||||||
import { useSettingsStore } from "@/hooks/stores";
|
import { useSettingsStore } from "@/hooks/stores";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
||||||
import { JigglerSetting } from "@components/JigglerSetting";
|
import { JigglerSetting } from "@components/JigglerSetting";
|
||||||
|
@ -87,17 +87,17 @@ export default function SettingsMouseRoute() {
|
||||||
{ value: "100", label: "Very High" },
|
{ value: "100", label: "Very High" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
const syncJigglerSettings = useCallback(() => {
|
const syncJigglerSettings = useCallback(() => {
|
||||||
send("getJigglerState", {}, resp => {
|
send("getJigglerState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
const isEnabled = resp.result as boolean;
|
const isEnabled = resp.result as boolean;
|
||||||
|
|
||||||
// If the jiggler is disabled, set the selected option to "disabled" and nothing else
|
// If the jiggler is disabled, set the selected option to "disabled" and nothing else
|
||||||
if (!isEnabled) return setSelectedJigglerOption("disabled");
|
if (!isEnabled) return setSelectedJigglerOption("disabled");
|
||||||
|
|
||||||
send("getJigglerConfig", {}, resp => {
|
send("getJigglerConfig", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
const result = resp.result as JigglerConfig;
|
const result = resp.result as JigglerConfig;
|
||||||
setCurrentJigglerConfig(result);
|
setCurrentJigglerConfig(result);
|
||||||
|
@ -121,7 +121,7 @@ export default function SettingsMouseRoute() {
|
||||||
const saveJigglerConfig = useCallback(
|
const saveJigglerConfig = useCallback(
|
||||||
(jigglerConfig: JigglerConfig) => {
|
(jigglerConfig: JigglerConfig) => {
|
||||||
// We assume the jiggler should be set to enabled if the config is being updated
|
// We assume the jiggler should be set to enabled if the config is being updated
|
||||||
send("setJigglerState", { enabled: true }, async resp => {
|
send("setJigglerState", { enabled: true }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
return notifications.error(
|
return notifications.error(
|
||||||
`Failed to set jiggler state: ${resp.error.data || "Unknown error"}`,
|
`Failed to set jiggler state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -129,7 +129,7 @@ export default function SettingsMouseRoute() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
send("setJigglerConfig", { jigglerConfig }, async resp => {
|
send("setJigglerConfig", { jigglerConfig }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
const errorMsg = resp.error.data || "Unknown error";
|
const errorMsg = resp.error.data || "Unknown error";
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ export default function SettingsMouseRoute() {
|
||||||
|
|
||||||
// We don't need to update the device jiggler state when the option is "disabled"
|
// We don't need to update the device jiggler state when the option is "disabled"
|
||||||
if (option === "disabled") {
|
if (option === "disabled") {
|
||||||
send("setJigglerState", { enabled: false }, async resp => {
|
send("setJigglerState", { enabled: false }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
return notifications.error(
|
return notifications.error(
|
||||||
`Failed to set jiggler state: ${resp.error.data || "Unknown error"}`,
|
`Failed to set jiggler state: ${resp.error.data || "Unknown error"}`,
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
TimeSyncMode,
|
TimeSyncMode,
|
||||||
useNetworkStateStore,
|
useNetworkStateStore,
|
||||||
} from "@/hooks/stores";
|
} from "@/hooks/stores";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { Button } from "@components/Button";
|
import { Button } from "@components/Button";
|
||||||
import { GridCard } from "@components/Card";
|
import { GridCard } from "@components/Card";
|
||||||
import InputField, { InputFieldWithLabel } from "@components/InputField";
|
import InputField, { InputFieldWithLabel } from "@components/InputField";
|
||||||
|
@ -72,7 +72,7 @@ export function LifeTimeLabel({ lifetime }: { lifetime: string }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SettingsNetworkRoute() {
|
export default function SettingsNetworkRoute() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [networkState, setNetworkState] = useNetworkStateStore(state => [
|
const [networkState, setNetworkState] = useNetworkStateStore(state => [
|
||||||
state,
|
state,
|
||||||
state.setNetworkState,
|
state.setNetworkState,
|
||||||
|
@ -104,7 +104,7 @@ export default function SettingsNetworkRoute() {
|
||||||
|
|
||||||
const getNetworkSettings = useCallback(() => {
|
const getNetworkSettings = useCallback(() => {
|
||||||
setNetworkSettingsLoaded(false);
|
setNetworkSettingsLoaded(false);
|
||||||
send("getNetworkSettings", {}, resp => {
|
send("getNetworkSettings", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
console.log(resp.result);
|
console.log(resp.result);
|
||||||
setNetworkSettings(resp.result as NetworkSettings);
|
setNetworkSettings(resp.result as NetworkSettings);
|
||||||
|
@ -117,7 +117,7 @@ export default function SettingsNetworkRoute() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const getNetworkState = useCallback(() => {
|
const getNetworkState = useCallback(() => {
|
||||||
send("getNetworkState", {}, resp => {
|
send("getNetworkState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
console.log(resp.result);
|
console.log(resp.result);
|
||||||
setNetworkState(resp.result as NetworkState);
|
setNetworkState(resp.result as NetworkState);
|
||||||
|
@ -127,7 +127,7 @@ export default function SettingsNetworkRoute() {
|
||||||
const setNetworkSettingsRemote = useCallback(
|
const setNetworkSettingsRemote = useCallback(
|
||||||
(settings: NetworkSettings) => {
|
(settings: NetworkSettings) => {
|
||||||
setNetworkSettingsLoaded(false);
|
setNetworkSettingsLoaded(false);
|
||||||
send("setNetworkSettings", { settings }, resp => {
|
send("setNetworkSettings", { settings }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
"Failed to save network settings: " +
|
"Failed to save network settings: " +
|
||||||
|
@ -148,7 +148,7 @@ export default function SettingsNetworkRoute() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleRenewLease = useCallback(() => {
|
const handleRenewLease = useCallback(() => {
|
||||||
send("renewDHCPLease", {}, resp => {
|
send("renewDHCPLease", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error("Failed to renew lease: " + resp.error.message);
|
notifications.error("Failed to renew lease: " + resp.error.message);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
||||||
|
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { TextAreaWithLabel } from "@/components/TextArea";
|
import { TextAreaWithLabel } from "@/components/TextArea";
|
||||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { useSettingsStore } from "@/hooks/stores";
|
import { useSettingsStore } from "@/hooks/stores";
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ const streamQualityOptions = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SettingsVideoRoute() {
|
export default function SettingsVideoRoute() {
|
||||||
const [send] = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
const [streamQuality, setStreamQuality] = useState("1");
|
const [streamQuality, setStreamQuality] = useState("1");
|
||||||
const [customEdidValue, setCustomEdidValue] = useState<string | null>(null);
|
const [customEdidValue, setCustomEdidValue] = useState<string | null>(null);
|
||||||
const [edid, setEdid] = useState<string | null>(null);
|
const [edid, setEdid] = useState<string | null>(null);
|
||||||
|
@ -55,12 +55,12 @@ export default function SettingsVideoRoute() {
|
||||||
const setVideoContrast = useSettingsStore(state => state.setVideoContrast);
|
const setVideoContrast = useSettingsStore(state => state.setVideoContrast);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
send("getStreamQualityFactor", {}, resp => {
|
send("getStreamQualityFactor", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setStreamQuality(String(resp.result));
|
setStreamQuality(String(resp.result));
|
||||||
});
|
});
|
||||||
|
|
||||||
send("getEDID", {}, resp => {
|
send("getEDID", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Failed to get EDID: ${resp.error.data || "Unknown error"}`);
|
notifications.error(`Failed to get EDID: ${resp.error.data || "Unknown error"}`);
|
||||||
return;
|
return;
|
||||||
|
@ -85,7 +85,7 @@ export default function SettingsVideoRoute() {
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
const handleStreamQualityChange = (factor: string) => {
|
const handleStreamQualityChange = (factor: string) => {
|
||||||
send("setStreamQualityFactor", { factor: Number(factor) }, resp => {
|
send("setStreamQualityFactor", { factor: Number(factor) }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set stream quality: ${resp.error.data || "Unknown error"}`,
|
`Failed to set stream quality: ${resp.error.data || "Unknown error"}`,
|
||||||
|
@ -99,7 +99,7 @@ export default function SettingsVideoRoute() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEDIDChange = (newEdid: string) => {
|
const handleEDIDChange = (newEdid: string) => {
|
||||||
send("setEDID", { edid: newEdid }, resp => {
|
send("setEDID", { edid: newEdid }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Failed to set EDID: ${resp.error.data || "Unknown error"}`);
|
notifications.error(`Failed to set EDID: ${resp.error.data || "Unknown error"}`);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { lazy, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
LoaderFunctionArgs,
|
LoaderFunctionArgs,
|
||||||
Outlet,
|
Outlet,
|
||||||
|
@ -16,7 +16,11 @@ import { FocusTrap } from "focus-trap-react";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import useWebSocket from "react-use-websocket";
|
import useWebSocket from "react-use-websocket";
|
||||||
|
|
||||||
|
import { CLOUD_API, DEVICE_API } from "@/ui.config";
|
||||||
|
import api from "@/api";
|
||||||
|
import { checkAuth, isInCloud, isOnDevice } from "@/main";
|
||||||
import { cx } from "@/cva.config";
|
import { cx } from "@/cva.config";
|
||||||
|
import notifications from "@/notifications";
|
||||||
import {
|
import {
|
||||||
HidState,
|
HidState,
|
||||||
KeyboardLedState,
|
KeyboardLedState,
|
||||||
|
@ -34,27 +38,21 @@ import {
|
||||||
VideoState,
|
VideoState,
|
||||||
} from "@/hooks/stores";
|
} from "@/hooks/stores";
|
||||||
import WebRTCVideo from "@components/WebRTCVideo";
|
import WebRTCVideo from "@components/WebRTCVideo";
|
||||||
import { checkAuth, isInCloud, isOnDevice } from "@/main";
|
|
||||||
import DashboardNavbar from "@components/Header";
|
import DashboardNavbar from "@components/Header";
|
||||||
import ConnectionStatsSidebar from "@/components/sidebar/connectionStats";
|
const ConnectionStatsSidebar = lazy(() => import('@/components/sidebar/connectionStats'));
|
||||||
import { JsonRpcRequest, useJsonRpc } from "@/hooks/useJsonRpc";
|
const Terminal = lazy(() => import('@components/Terminal'));
|
||||||
import Terminal from "@components/Terminal";
|
const UpdateInProgressStatusCard = lazy(() => import("@/components/UpdateInProgressStatusCard"));
|
||||||
import { CLOUD_API, DEVICE_API } from "@/ui.config";
|
import Modal from "@/components/Modal";
|
||||||
|
import { JsonRpcRequest, JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
|
||||||
import UpdateInProgressStatusCard from "../components/UpdateInProgressStatusCard";
|
|
||||||
import api from "../api";
|
|
||||||
import Modal from "../components/Modal";
|
|
||||||
import { useDeviceUiNavigation } from "../hooks/useAppNavigation";
|
|
||||||
import {
|
import {
|
||||||
ConnectionFailedOverlay,
|
ConnectionFailedOverlay,
|
||||||
LoadingConnectionOverlay,
|
LoadingConnectionOverlay,
|
||||||
PeerConnectionDisconnectedOverlay,
|
PeerConnectionDisconnectedOverlay,
|
||||||
} from "../components/VideoOverlay";
|
} from "@/components/VideoOverlay";
|
||||||
import { FeatureFlagProvider } from "../providers/FeatureFlagProvider";
|
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||||
import notifications from "../notifications";
|
import { FeatureFlagProvider } from "@/providers/FeatureFlagProvider";
|
||||||
|
import { DeviceStatus } from "@routes/welcome-local";
|
||||||
import { DeviceStatus } from "./welcome-local";
|
import { SystemVersionInfo } from "@routes/devices.$id.settings.general.update";
|
||||||
import { SystemVersionInfo } from "./devices.$id.settings.general.update";
|
|
||||||
|
|
||||||
interface LocalLoaderResp {
|
interface LocalLoaderResp {
|
||||||
authMode: "password" | "noPassword" | null;
|
authMode: "password" | "noPassword" | null;
|
||||||
|
@ -114,7 +112,7 @@ const cloudLoader = async (params: Params<string>): Promise<CloudLoaderResp> =>
|
||||||
return { user, iceConfig, deviceName: device.name || device.id };
|
return { user, iceConfig, deviceName: device.name || device.id };
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader = async ({ params }: LoaderFunctionArgs) => {
|
const loader = ({ params }: LoaderFunctionArgs) => {
|
||||||
return import.meta.env.MODE === "device" ? deviceLoader() : cloudLoader(params);
|
return import.meta.env.MODE === "device" ? deviceLoader() : cloudLoader(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -452,7 +450,7 @@ export default function KvmIdRoute() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pc.onicecandidate = async ({ candidate }) => {
|
pc.onicecandidate = ({ candidate }) => {
|
||||||
if (!candidate) return;
|
if (!candidate) return;
|
||||||
if (candidate.candidate === "") return;
|
if (candidate.candidate === "") return;
|
||||||
sendWebRTCSignal("new-ice-candidate", candidate);
|
sendWebRTCSignal("new-ice-candidate", candidate);
|
||||||
|
@ -646,11 +644,11 @@ export default function KvmIdRoute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
const rpcDataChannel = useRTCStore(state => state.rpcDataChannel);
|
||||||
const [send] = useJsonRpc(onJsonRpcRequest);
|
const { send } = useJsonRpc(onJsonRpcRequest);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rpcDataChannel?.readyState !== "open") return;
|
if (rpcDataChannel?.readyState !== "open") return;
|
||||||
send("getVideoState", {}, resp => {
|
send("getVideoState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) return;
|
if ("error" in resp) return;
|
||||||
setHdmiState(resp.result as Parameters<VideoState["setHdmiState"]>[0]);
|
setHdmiState(resp.result as Parameters<VideoState["setHdmiState"]>[0]);
|
||||||
});
|
});
|
||||||
|
@ -662,7 +660,7 @@ export default function KvmIdRoute() {
|
||||||
if (keyboardLedState !== undefined) return;
|
if (keyboardLedState !== undefined) return;
|
||||||
console.log("Requesting keyboard led state");
|
console.log("Requesting keyboard led state");
|
||||||
|
|
||||||
send("getKeyboardLedState", {}, resp => {
|
send("getKeyboardLedState", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
// -32601 means the method is not supported
|
// -32601 means the method is not supported
|
||||||
if (resp.error.code === -32601) {
|
if (resp.error.code === -32601) {
|
||||||
|
@ -735,7 +733,7 @@ export default function KvmIdRoute() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (appVersion) return;
|
if (appVersion) return;
|
||||||
|
|
||||||
send("getUpdateStatus", {}, async resp => {
|
send("getUpdateStatus", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(`Failed to get device version: ${resp.error}`);
|
notifications.error(`Failed to get device version: ${resp.error}`);
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue