Skip to content

Commit 83caa8f

Browse files
authored
feat: get local version only (#813)
1 parent 27750b9 commit 83caa8f

File tree

5 files changed

+104
-54
lines changed

5 files changed

+104
-54
lines changed

jsonrpc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ func rpcGetUpdateStatus() (*UpdateStatus, error) {
282282
return updateStatus, nil
283283
}
284284

285+
func rpcGetLocalVersion() (*LocalMetadata, error) {
286+
systemVersion, appVersion, err := GetLocalVersion()
287+
if err != nil {
288+
return nil, fmt.Errorf("error getting local version: %w", err)
289+
}
290+
return &LocalMetadata{
291+
AppVersion: appVersion.String(),
292+
SystemVersion: systemVersion.String(),
293+
}, nil
294+
}
295+
285296
func rpcTryUpdate() error {
286297
includePreRelease := config.IncludePreRelease
287298
go func() {
@@ -1191,6 +1202,7 @@ var rpcHandlers = map[string]RPCHandler{
11911202
"setEDID": {Func: rpcSetEDID, Params: []string{"edid"}},
11921203
"getDevChannelState": {Func: rpcGetDevChannelState},
11931204
"setDevChannelState": {Func: rpcSetDevChannelState, Params: []string{"enabled"}},
1205+
"getLocalVersion": {Func: rpcGetLocalVersion},
11941206
"getUpdateStatus": {Func: rpcGetUpdateStatus},
11951207
"tryUpdate": {Func: rpcTryUpdate},
11961208
"getDevModeState": {Func: rpcGetDevModeState},

ui/src/hooks/useJsonRpc.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface JsonRpcErrorResponse {
2929

3030
export type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse;
3131

32+
export const RpcMethodNotFound = -32601;
33+
3234
const callbackStore = new Map<number | string, (resp: JsonRpcResponse) => void>();
3335
let requestCounter = 0;
3436

ui/src/hooks/useVersion.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { useCallback } from "react";
2+
3+
import { useDeviceStore } from "@/hooks/stores";
4+
import { type JsonRpcResponse, RpcMethodNotFound, useJsonRpc } from "@/hooks/useJsonRpc";
5+
import notifications from "@/notifications";
6+
7+
export interface VersionInfo {
8+
appVersion: string;
9+
systemVersion: string;
10+
}
11+
12+
export interface SystemVersionInfo {
13+
local: VersionInfo;
14+
remote?: VersionInfo;
15+
systemUpdateAvailable: boolean;
16+
appUpdateAvailable: boolean;
17+
error?: string;
18+
}
19+
20+
export function useVersion() {
21+
const {
22+
appVersion,
23+
systemVersion,
24+
setAppVersion,
25+
setSystemVersion,
26+
} = useDeviceStore();
27+
const { send } = useJsonRpc();
28+
const getVersionInfo = useCallback(() => {
29+
return new Promise<SystemVersionInfo>((resolve, reject) => {
30+
send("getUpdateStatus", {}, (resp: JsonRpcResponse) => {
31+
if ("error" in resp) {
32+
notifications.error(`Failed to check for updates: ${resp.error}`);
33+
reject(new Error("Failed to check for updates"));
34+
} else {
35+
const result = resp.result as SystemVersionInfo;
36+
setAppVersion(result.local.appVersion);
37+
setSystemVersion(result.local.systemVersion);
38+
39+
if (result.error) {
40+
notifications.error(`Failed to check for updates: ${result.error}`);
41+
reject(new Error("Failed to check for updates"));
42+
} else {
43+
resolve(result);
44+
}
45+
}
46+
});
47+
});
48+
}, [send, setAppVersion, setSystemVersion]);
49+
50+
const getLocalVersion = useCallback(() => {
51+
return new Promise<VersionInfo>((resolve, reject) => {
52+
send("getLocalVersion", {}, (resp: JsonRpcResponse) => {
53+
if ("error" in resp) {
54+
console.log(resp.error)
55+
if (resp.error.code === RpcMethodNotFound) {
56+
console.warn("Failed to get device version, using legacy version");
57+
return getVersionInfo().then(result => resolve(result.local)).catch(reject);
58+
}
59+
console.error("Failed to get device version N", resp.error);
60+
notifications.error(`Failed to get device version: ${resp.error}`);
61+
reject(new Error("Failed to get device version"));
62+
} else {
63+
const result = resp.result as VersionInfo;
64+
65+
setAppVersion(result.appVersion);
66+
setSystemVersion(result.systemVersion);
67+
resolve(result);
68+
}
69+
});
70+
});
71+
}, [send, setAppVersion, setSystemVersion, getVersionInfo]);
72+
73+
return {
74+
getVersionInfo,
75+
getLocalVersion,
76+
appVersion,
77+
systemVersion,
78+
};
79+
}

ui/src/routes/devices.$id.settings.general.update.tsx

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { useCallback, useEffect, useRef, useState } from "react";
33
import { CheckCircleIcon } from "@heroicons/react/20/solid";
44

55
import Card from "@/components/Card";
6-
import { JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
6+
import { useJsonRpc } from "@/hooks/useJsonRpc";
77
import { Button } from "@components/Button";
8-
import { UpdateState, useDeviceStore, useUpdateStore } from "@/hooks/stores";
9-
import notifications from "@/notifications";
8+
import { UpdateState, useUpdateStore } from "@/hooks/stores";
109
import LoadingSpinner from "@/components/LoadingSpinner";
1110
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
11+
import { SystemVersionInfo, useVersion } from "@/hooks/useVersion";
1212

1313
export default function SettingsGeneralUpdateRoute() {
1414
const navigate = useNavigate();
@@ -41,13 +41,7 @@ export default function SettingsGeneralUpdateRoute() {
4141
return <Dialog onClose={() => navigate("..")} onConfirmUpdate={onConfirmUpdate} />;
4242
}
4343

44-
export interface SystemVersionInfo {
45-
local: { appVersion: string; systemVersion: string };
46-
remote?: { appVersion: string; systemVersion: string };
47-
systemUpdateAvailable: boolean;
48-
appUpdateAvailable: boolean;
49-
error?: string;
50-
}
44+
5145

5246
export function Dialog({
5347
onClose,
@@ -134,30 +128,8 @@ function LoadingState({
134128
}) {
135129
const [progressWidth, setProgressWidth] = useState("0%");
136130
const abortControllerRef = useRef<AbortController | null>(null);
137-
const { setAppVersion, setSystemVersion } = useDeviceStore();
138-
const { send } = useJsonRpc();
139131

140-
const getVersionInfo = useCallback(() => {
141-
return new Promise<SystemVersionInfo>((resolve, reject) => {
142-
send("getUpdateStatus", {}, (resp: JsonRpcResponse) => {
143-
if ("error" in resp) {
144-
notifications.error(`Failed to check for updates: ${resp.error}`);
145-
reject(new Error("Failed to check for updates"));
146-
} else {
147-
const result = resp.result as SystemVersionInfo;
148-
setAppVersion(result.local.appVersion);
149-
setSystemVersion(result.local.systemVersion);
150-
151-
if (result.error) {
152-
notifications.error(`Failed to check for updates: ${result.error}`);
153-
reject(new Error("Failed to check for updates"));
154-
} else {
155-
resolve(result);
156-
}
157-
}
158-
});
159-
});
160-
}, [send, setAppVersion, setSystemVersion]);
132+
const { getVersionInfo } = useVersion();
161133

162134
const progressBarRef = useRef<HTMLDivElement>(null);
163135
useEffect(() => {

ui/src/routes/devices.$id.tsx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@ import { CLOUD_API, DEVICE_API } from "@/ui.config";
1919
import api from "@/api";
2020
import { checkAuth, isInCloud, isOnDevice } from "@/main";
2121
import { cx } from "@/cva.config";
22-
import notifications from "@/notifications";
2322
import {
2423
KeyboardLedState,
2524
KeysDownState,
2625
NetworkState,
2726
OtaState,
2827
USBStates,
29-
useDeviceStore,
3028
useHidStore,
3129
useNetworkStateStore,
3230
User,
@@ -42,7 +40,7 @@ const ConnectionStatsSidebar = lazy(() => import('@/components/sidebar/connectio
4240
const Terminal = lazy(() => import('@components/Terminal'));
4341
const UpdateInProgressStatusCard = lazy(() => import("@/components/UpdateInProgressStatusCard"));
4442
import Modal from "@/components/Modal";
45-
import { JsonRpcRequest, JsonRpcResponse, useJsonRpc } from "@/hooks/useJsonRpc";
43+
import { JsonRpcRequest, JsonRpcResponse, RpcMethodNotFound, useJsonRpc } from "@/hooks/useJsonRpc";
4644
import {
4745
ConnectionFailedOverlay,
4846
LoadingConnectionOverlay,
@@ -51,7 +49,7 @@ import {
5149
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
5250
import { FeatureFlagProvider } from "@/providers/FeatureFlagProvider";
5351
import { DeviceStatus } from "@routes/welcome-local";
54-
import { SystemVersionInfo } from "@routes/devices.$id.settings.general.update";
52+
import { useVersion } from "@/hooks/useVersion";
5553

5654
interface LocalLoaderResp {
5755
authMode: "password" | "noPassword" | null;
@@ -715,7 +713,7 @@ export default function KvmIdRoute() {
715713
send("getKeyDownState", {}, (resp: JsonRpcResponse) => {
716714
if ("error" in resp) {
717715
// -32601 means the method is not supported
718-
if (resp.error.code === -32601) {
716+
if (resp.error.code === RpcMethodNotFound) {
719717
// if we don't support key down state, we know key press is also not available
720718
console.warn("Failed to get key down state, switching to old-school", resp.error);
721719
setHidRpcDisabled(true);
@@ -758,26 +756,13 @@ export default function KvmIdRoute() {
758756
if (location.pathname !== "/other-session") navigateTo("/");
759757
}, [navigateTo, location.pathname]);
760758

761-
const { appVersion, setAppVersion, setSystemVersion} = useDeviceStore();
759+
const { appVersion, getLocalVersion} = useVersion();
762760

763761
useEffect(() => {
764762
if (appVersion) return;
765763

766-
send("getUpdateStatus", {}, (resp: JsonRpcResponse) => {
767-
if ("error" in resp) {
768-
notifications.error(`Failed to get device version: ${resp.error}`);
769-
return
770-
}
771-
772-
const result = resp.result as SystemVersionInfo;
773-
if (result.error) {
774-
notifications.error(`Failed to get device version: ${result.error}`);
775-
}
776-
777-
setAppVersion(result.local.appVersion);
778-
setSystemVersion(result.local.systemVersion);
779-
});
780-
}, [appVersion, send, setAppVersion, setSystemVersion]);
764+
getLocalVersion();
765+
}, [appVersion, getLocalVersion]);
781766

782767
const ConnectionStatusElement = useMemo(() => {
783768
const hasConnectionFailed =

0 commit comments

Comments
 (0)