mirror of https://github.com/jetkvm/kvm.git
refactor: simplify version check and downgrade
This commit is contained in:
parent
329ad025bf
commit
1bca0c5e26
|
|
@ -239,10 +239,29 @@ func (s *State) getUpdateStatus(
|
|||
systemUpdate = ¤tSystemUpdate
|
||||
}
|
||||
|
||||
err = s.doGetUpdateStatus(ctx, params, appUpdate, systemUpdate)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
s.componentUpdateStatuses["app"] = *appUpdate
|
||||
s.componentUpdateStatuses["system"] = *systemUpdate
|
||||
|
||||
return appUpdate, systemUpdate, nil
|
||||
}
|
||||
|
||||
// doGetUpdateStatus is the internal function that gets the update status
|
||||
// it WON'T change the state of the OTA state
|
||||
func (s *State) doGetUpdateStatus(
|
||||
ctx context.Context,
|
||||
params UpdateParams,
|
||||
appUpdate *componentUpdateStatus,
|
||||
systemUpdate *componentUpdateStatus,
|
||||
) error {
|
||||
// Get local versions
|
||||
systemVersionLocal, appVersionLocal, err := s.getLocalVersion()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error getting local version: %w", err)
|
||||
return fmt.Errorf("error getting local version: %w", err)
|
||||
}
|
||||
appUpdate.localVersion = appVersionLocal.String()
|
||||
systemUpdate.localVersion = systemVersionLocal.String()
|
||||
|
|
@ -255,7 +274,7 @@ func (s *State) getUpdateStatus(
|
|||
} else {
|
||||
err = fmt.Errorf("error checking for updates: %w", err)
|
||||
}
|
||||
return
|
||||
return err
|
||||
}
|
||||
appUpdate.url = remoteMetadata.AppURL
|
||||
appUpdate.hash = remoteMetadata.AppHash
|
||||
|
|
@ -269,7 +288,7 @@ func (s *State) getUpdateStatus(
|
|||
systemVersionRemote, err := semver.NewVersion(remoteMetadata.SystemVersion)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing remote system version: %w", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
systemUpdate.available = systemVersionRemote.GreaterThan(systemVersionLocal)
|
||||
systemUpdate.downgradeAvailable = systemVersionRemote.LessThan(systemVersionLocal)
|
||||
|
|
@ -277,7 +296,7 @@ func (s *State) getUpdateStatus(
|
|||
appVersionRemote, err := semver.NewVersion(remoteMetadata.AppVersion)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing remote app version: %w, %s", err, remoteMetadata.AppVersion)
|
||||
return
|
||||
return err
|
||||
}
|
||||
appUpdate.available = appVersionRemote.GreaterThan(appVersionLocal)
|
||||
appUpdate.downgradeAvailable = appVersionRemote.LessThan(appVersionLocal)
|
||||
|
|
@ -293,18 +312,17 @@ func (s *State) getUpdateStatus(
|
|||
appUpdate.available = false
|
||||
}
|
||||
|
||||
s.componentUpdateStatuses["app"] = *appUpdate
|
||||
s.componentUpdateStatuses["system"] = *systemUpdate
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUpdateStatus returns the current update status (for backwards compatibility)
|
||||
func (s *State) GetUpdateStatus(ctx context.Context, params UpdateParams) (*UpdateStatus, error) {
|
||||
_, _, err := s.getUpdateStatus(ctx, params)
|
||||
appUpdate := &componentUpdateStatus{}
|
||||
systemUpdate := &componentUpdateStatus{}
|
||||
err := s.doGetUpdateStatus(ctx, params, appUpdate, systemUpdate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting update status: %w", err)
|
||||
}
|
||||
|
||||
return s.ToUpdateStatus(), nil
|
||||
return toUpdateStatus(appUpdate, systemUpdate, ""), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,18 +156,7 @@ func (s *State) GetTargetVersion(component string) string {
|
|||
return componentUpdate.targetVersion
|
||||
}
|
||||
|
||||
// ToUpdateStatus converts the State to the UpdateStatus
|
||||
func (s *State) ToUpdateStatus() *UpdateStatus {
|
||||
appUpdate, ok := s.componentUpdateStatuses["app"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
systemUpdate, ok := s.componentUpdateStatuses["system"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
func toUpdateStatus(appUpdate *componentUpdateStatus, systemUpdate *componentUpdateStatus, error string) *UpdateStatus {
|
||||
return &UpdateStatus{
|
||||
Local: &LocalMetadata{
|
||||
AppVersion: appUpdate.localVersion,
|
||||
|
|
@ -185,10 +174,25 @@ func (s *State) ToUpdateStatus() *UpdateStatus {
|
|||
SystemDowngradeAvailable: systemUpdate.downgradeAvailable,
|
||||
AppUpdateAvailable: appUpdate.available,
|
||||
AppDowngradeAvailable: appUpdate.downgradeAvailable,
|
||||
Error: s.error,
|
||||
Error: error,
|
||||
}
|
||||
}
|
||||
|
||||
// ToUpdateStatus converts the State to the UpdateStatus
|
||||
func (s *State) ToUpdateStatus() *UpdateStatus {
|
||||
appUpdate, ok := s.componentUpdateStatuses["app"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
systemUpdate, ok := s.componentUpdateStatuses["system"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return toUpdateStatus(&appUpdate, &systemUpdate, s.error)
|
||||
}
|
||||
|
||||
// IsUpdatePending returns true if an update is pending
|
||||
func (s *State) IsUpdatePending() bool {
|
||||
return s.updating
|
||||
|
|
|
|||
|
|
@ -1151,9 +1151,10 @@ var rpcHandlers = map[string]RPCHandler{
|
|||
"setDevChannelState": {Func: rpcSetDevChannelState, Params: []string{"enabled"}},
|
||||
"getLocalVersion": {Func: rpcGetLocalVersion},
|
||||
"getUpdateStatus": {Func: rpcGetUpdateStatus},
|
||||
"checkUpdateComponents": {Func: rpcCheckUpdateComponents, Params: []string{"params", "includePreRelease"}},
|
||||
"getUpdateStatusChannel": {Func: rpcGetUpdateStatusChannel},
|
||||
"tryUpdate": {Func: rpcTryUpdate},
|
||||
"tryUpdateComponents": {Func: rpcTryUpdateComponents, Params: []string{"components", "includePreRelease", "checkOnly", "resetConfig"}},
|
||||
"tryUpdateComponents": {Func: rpcTryUpdateComponents, Params: []string{"params", "includePreRelease", "resetConfig"}},
|
||||
"cancelDowngrade": {Func: rpcCancelDowngrade},
|
||||
"getDevModeState": {Func: rpcGetDevModeState},
|
||||
"setDevModeState": {Func: rpcSetDevModeState, Params: []string{"enabled"}},
|
||||
|
|
|
|||
73
ota.go
73
ota.go
|
|
@ -6,7 +6,6 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/jetkvm/kvm/internal/ota"
|
||||
|
|
@ -135,72 +134,56 @@ func rpcGetLocalVersion() (*ota.LocalMetadata, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ComponentName represents the name of a component
|
||||
type tryUpdateComponents struct {
|
||||
type updateParams struct {
|
||||
AppTargetVersion string `json:"app"`
|
||||
SystemTargetVersion string `json:"system"`
|
||||
Components string `json:"components,omitempty"` // components is a comma-separated list of components to update
|
||||
}
|
||||
|
||||
func rpcTryUpdate() error {
|
||||
return rpcTryUpdateComponents(tryUpdateComponents{
|
||||
return rpcTryUpdateComponents(updateParams{
|
||||
AppTargetVersion: "",
|
||||
SystemTargetVersion: "",
|
||||
}, config.IncludePreRelease, false, false)
|
||||
}, config.IncludePreRelease, false)
|
||||
}
|
||||
|
||||
func rpcTryUpdateComponents(components tryUpdateComponents, includePreRelease bool, checkOnly bool, resetConfig bool) error {
|
||||
// rpcCheckUpdateComponents checks the update status for the given components
|
||||
func rpcCheckUpdateComponents(params updateParams, includePreRelease bool) (*ota.UpdateStatus, error) {
|
||||
updateParams := ota.UpdateParams{
|
||||
DeviceID: GetDeviceID(),
|
||||
IncludePreRelease: includePreRelease,
|
||||
AppTargetVersion: params.AppTargetVersion,
|
||||
SystemTargetVersion: params.SystemTargetVersion,
|
||||
}
|
||||
if params.Components != "" {
|
||||
updateParams.Components = strings.Split(params.Components, ",")
|
||||
}
|
||||
info, err := otaState.GetUpdateStatus(context.Background(), updateParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check update: %w", err)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func rpcTryUpdateComponents(params updateParams, includePreRelease bool, resetConfig bool) error {
|
||||
updateParams := ota.UpdateParams{
|
||||
DeviceID: GetDeviceID(),
|
||||
IncludePreRelease: includePreRelease,
|
||||
CheckOnly: checkOnly,
|
||||
ResetConfig: resetConfig,
|
||||
}
|
||||
|
||||
logger.Info().Interface("components", components).Msg("components")
|
||||
|
||||
currentAppTargetVersion := otaState.GetTargetVersion("app")
|
||||
appTargetVersionChanged := currentAppTargetVersion != components.AppTargetVersion
|
||||
updateParams.AppTargetVersion = components.AppTargetVersion
|
||||
if err := otaState.SetTargetVersion("app", components.AppTargetVersion); err != nil {
|
||||
updateParams.AppTargetVersion = params.AppTargetVersion
|
||||
if err := otaState.SetTargetVersion("app", params.AppTargetVersion); err != nil {
|
||||
return fmt.Errorf("failed to set app target version: %w", err)
|
||||
}
|
||||
|
||||
currentSystemTargetVersion := otaState.GetTargetVersion("system")
|
||||
systemTargetVersionChanged := currentSystemTargetVersion != components.SystemTargetVersion
|
||||
updateParams.SystemTargetVersion = components.SystemTargetVersion
|
||||
if err := otaState.SetTargetVersion("system", components.SystemTargetVersion); err != nil {
|
||||
updateParams.SystemTargetVersion = params.SystemTargetVersion
|
||||
if err := otaState.SetTargetVersion("system", params.SystemTargetVersion); err != nil {
|
||||
return fmt.Errorf("failed to set system target version: %w", err)
|
||||
}
|
||||
|
||||
if components.Components != "" {
|
||||
updateParams.Components = strings.Split(components.Components, ",")
|
||||
}
|
||||
|
||||
// if it's a check only update, we don't need to try to update, we just need to check if the version is available
|
||||
// and return the error immediately then revert the previous target versions
|
||||
if checkOnly {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, err := otaState.GetUpdateStatus(ctx, updateParams)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// revert the previous target versions
|
||||
if appTargetVersionChanged {
|
||||
if err := otaState.SetTargetVersion("app", currentAppTargetVersion); err != nil {
|
||||
return fmt.Errorf("failed to revert app target version: %w", err)
|
||||
}
|
||||
}
|
||||
if systemTargetVersionChanged {
|
||||
if err := otaState.SetTargetVersion("system", currentSystemTargetVersion); err != nil {
|
||||
return fmt.Errorf("failed to revert system target version: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
if params.Components != "" {
|
||||
updateParams.Components = strings.Split(params.Components, ",")
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { useSettingsStore } from "@hooks/stores";
|
||||
import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
|
||||
import { JsonRpcError, JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
|
||||
import { useDeviceUiNavigation } from "@hooks/useAppNavigation";
|
||||
import { Button } from "@components/Button";
|
||||
import Checkbox, { CheckboxWithLabel } from "@components/Checkbox";
|
||||
|
|
@ -17,6 +17,8 @@ import { isOnDevice } from "@/main";
|
|||
import notifications from "@/notifications";
|
||||
import { m } from "@localizations/messages.js";
|
||||
import { sleep } from "@/utils";
|
||||
import { checkUpdateComponents } from "@/utils/jsonrpc";
|
||||
import { SystemVersionInfo } from "@hooks/useVersion";
|
||||
|
||||
export default function SettingsAdvancedRoute() {
|
||||
const { send } = useJsonRpc();
|
||||
|
|
@ -33,7 +35,7 @@ export default function SettingsAdvancedRoute() {
|
|||
const [systemVersion, setSystemVersion] = useState<string>("");
|
||||
const [resetConfig, setResetConfig] = useState(false);
|
||||
const [versionChangeAcknowledged, setVersionChangeAcknowledged] = useState(false);
|
||||
|
||||
const [versionUpdateLoading, setVersionUpdateLoading] = useState(false);
|
||||
const settings = useSettingsStore();
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -183,34 +185,57 @@ export default function SettingsAdvancedRoute() {
|
|||
setShowLoopbackWarning(false);
|
||||
}, [applyLoopbackOnlyMode, setShowLoopbackWarning]);
|
||||
|
||||
const handleVersionUpdate = useCallback(() => {
|
||||
const params = {
|
||||
components: {
|
||||
const handleVersionUpdateError = useCallback((error?: JsonRpcError) => {
|
||||
notifications.error(
|
||||
m.advanced_error_version_update({
|
||||
error: error?.data ?? error?.message ?? m.unknown_error()
|
||||
}),
|
||||
{ duration: 1000 * 15 } // 15 seconds
|
||||
);
|
||||
setVersionUpdateLoading(false);
|
||||
}, []);
|
||||
|
||||
const handleVersionUpdate = useCallback(async () => {
|
||||
const components = updateTarget === "both" ? ["app", "system"] : [updateTarget];
|
||||
let versionInfo: SystemVersionInfo | undefined;
|
||||
try {
|
||||
// we do not need to set it to false if check succeeds,
|
||||
// because it will be redirected to the update page later
|
||||
setVersionUpdateLoading(true);
|
||||
versionInfo = await checkUpdateComponents({
|
||||
components: components.join(","),
|
||||
app: appVersion,
|
||||
system: systemVersion,
|
||||
},
|
||||
includePreRelease: devChannel,
|
||||
checkOnly: true,
|
||||
// no need to reset config for a check only update
|
||||
resetConfig: false,
|
||||
};
|
||||
}, devChannel);
|
||||
console.log("versionInfo", versionInfo);
|
||||
} catch (error: unknown) {
|
||||
const jsonRpcError = error as JsonRpcError;
|
||||
handleVersionUpdateError(jsonRpcError);
|
||||
return ;
|
||||
}
|
||||
|
||||
send("tryUpdateComponents", params, (resp: JsonRpcResponse) => {
|
||||
if ("error" in resp) {
|
||||
notifications.error(
|
||||
m.advanced_error_version_update({ error: resp.error.data || m.unknown_error() })
|
||||
);
|
||||
return;
|
||||
}
|
||||
const pageParams = new URLSearchParams();
|
||||
pageParams.set("downgrade", "true");
|
||||
pageParams.set("resetConfig", resetConfig.toString());
|
||||
pageParams.set("components", updateTarget === "both" ? "app,system" : updateTarget);
|
||||
if (!versionInfo) {
|
||||
handleVersionUpdateError();
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigate to update page
|
||||
navigateTo(`/settings/general/update?${pageParams.toString()}`);
|
||||
});
|
||||
}, [updateTarget, appVersion, systemVersion, devChannel, send, navigateTo, resetConfig]);
|
||||
const pageParams = new URLSearchParams();
|
||||
pageParams.set("downgrade", "true");
|
||||
if (components.includes("app") && versionInfo.remote?.appVersion && versionInfo.appDowngradeAvailable) {
|
||||
pageParams.set("app", versionInfo.remote?.appVersion);
|
||||
}
|
||||
if (components.includes("system") && versionInfo.remote?.systemVersion && versionInfo.systemDowngradeAvailable) {
|
||||
pageParams.set("system", versionInfo.remote?.systemVersion);
|
||||
}
|
||||
pageParams.set("resetConfig", resetConfig.toString());
|
||||
|
||||
// Navigate to update page
|
||||
navigateTo(`/settings/general/update?${pageParams.toString()}`);
|
||||
}, [
|
||||
updateTarget, appVersion, systemVersion, devChannel,
|
||||
navigateTo, resetConfig, handleVersionUpdateError,
|
||||
setVersionUpdateLoading
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
|
|
@ -374,8 +399,10 @@ export default function SettingsAdvancedRoute() {
|
|||
(updateTarget === "app" && !appVersion) ||
|
||||
(updateTarget === "system" && !systemVersion) ||
|
||||
(updateTarget === "both" && (!appVersion || !systemVersion)) ||
|
||||
!versionChangeAcknowledged
|
||||
!versionChangeAcknowledged ||
|
||||
versionUpdateLoading
|
||||
}
|
||||
loading={versionUpdateLoading}
|
||||
onClick={handleVersionUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ export default function SettingsGeneralUpdateRoute() {
|
|||
const { send } = useJsonRpc();
|
||||
|
||||
const downgrade = useMemo(() => searchParams.get("downgrade") === "true", [searchParams]);
|
||||
const updateComponents = useMemo(() => searchParams.get("components") || "", [searchParams]);
|
||||
const customAppVersion = useMemo(() => searchParams.get("app") || "", [searchParams]);
|
||||
const customSystemVersion = useMemo(() => searchParams.get("system") || "", [searchParams]);
|
||||
const resetConfig = useMemo(() => searchParams.get("resetConfig") === "true", [searchParams]);
|
||||
|
||||
const onClose = useCallback(async () => {
|
||||
|
|
@ -38,18 +39,28 @@ export default function SettingsGeneralUpdateRoute() {
|
|||
setModalView("updating");
|
||||
}, [send, setModalView]);
|
||||
|
||||
const onConfirmDowngrade = useCallback((system?: string, app?: string) => {
|
||||
const onConfirmDowngrade = useCallback(() => {
|
||||
const components = [];
|
||||
if (customSystemVersion) {
|
||||
components.push("system");
|
||||
}
|
||||
if (customAppVersion) {
|
||||
components.push("app");
|
||||
}
|
||||
|
||||
send("tryUpdateComponents", {
|
||||
components: {
|
||||
system, app,
|
||||
components: updateComponents
|
||||
params: {
|
||||
components: components.join(","),
|
||||
app: customAppVersion,
|
||||
system: customSystemVersion,
|
||||
},
|
||||
includePreRelease: true,
|
||||
checkOnly: false,
|
||||
resetConfig: resetConfig,
|
||||
includePreRelease: false,
|
||||
resetConfig,
|
||||
}, (resp) => {
|
||||
if ("error" in resp) return;
|
||||
setModalView("updating");
|
||||
});
|
||||
setModalView("updating");
|
||||
}, [send, setModalView, updateComponents, resetConfig]);
|
||||
}, [send, setModalView, customAppVersion, customSystemVersion, resetConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (otaState.updating) {
|
||||
|
|
@ -64,10 +75,12 @@ export default function SettingsGeneralUpdateRoute() {
|
|||
}, [otaState.error, otaState.updating, setModalView, updateSuccess]);
|
||||
|
||||
return <Dialog
|
||||
onClose={onClose}
|
||||
onConfirmUpdate={onConfirmUpdate}
|
||||
onConfirmDowngrade={onConfirmDowngrade}
|
||||
downgrade={downgrade}
|
||||
onClose={onClose}
|
||||
onConfirmUpdate={onConfirmUpdate}
|
||||
onConfirmDowngrade={onConfirmDowngrade}
|
||||
downgrade={downgrade}
|
||||
customAppVersion={customAppVersion}
|
||||
customSystemVersion={customSystemVersion}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
|
@ -76,11 +89,15 @@ export function Dialog({
|
|||
onConfirmUpdate,
|
||||
onConfirmDowngrade,
|
||||
downgrade,
|
||||
customAppVersion,
|
||||
customSystemVersion,
|
||||
}: Readonly<{
|
||||
downgrade: boolean;
|
||||
onClose: () => void;
|
||||
onConfirmUpdate: () => void;
|
||||
onConfirmDowngrade: () => void;
|
||||
customAppVersion?: string;
|
||||
customSystemVersion?: string;
|
||||
}>) {
|
||||
const { navigateTo } = useDeviceUiNavigation();
|
||||
|
||||
|
|
@ -92,8 +109,7 @@ export function Dialog({
|
|||
(versionInfo: SystemVersionInfo) => {
|
||||
const hasUpdate =
|
||||
versionInfo?.systemUpdateAvailable || versionInfo?.appUpdateAvailable;
|
||||
const hasDowngrade =
|
||||
versionInfo?.systemDowngradeAvailable || versionInfo?.appDowngradeAvailable;
|
||||
const hasDowngrade = customSystemVersion !== undefined || customAppVersion !== undefined;
|
||||
|
||||
setVersionInfo(versionInfo);
|
||||
|
||||
|
|
@ -105,7 +121,7 @@ export function Dialog({
|
|||
setModalView("upToDate");
|
||||
}
|
||||
},
|
||||
[setModalView, downgrade],
|
||||
[setModalView, downgrade, customAppVersion, customSystemVersion],
|
||||
);
|
||||
|
||||
const onCancelDowngrade = useCallback(() => {
|
||||
|
|
@ -137,9 +153,10 @@ export function Dialog({
|
|||
)}
|
||||
{modalView === "updateDowngradeAvailable" && (
|
||||
<UpdateDowngradeAvailableState
|
||||
appVersion={customAppVersion}
|
||||
systemVersion={customSystemVersion}
|
||||
onConfirmDowngrade={onConfirmDowngrade}
|
||||
onCancelDowngrade={onCancelDowngrade}
|
||||
versionInfo={versionInfo!}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
@ -455,20 +472,19 @@ function UpdateAvailableState({
|
|||
}
|
||||
|
||||
function UpdateDowngradeAvailableState({
|
||||
versionInfo,
|
||||
appVersion,
|
||||
systemVersion,
|
||||
onConfirmDowngrade,
|
||||
onCancelDowngrade,
|
||||
}: {
|
||||
versionInfo: SystemVersionInfo;
|
||||
onConfirmDowngrade: (system?: string, app?: string) => void;
|
||||
appVersion?: string;
|
||||
systemVersion?: string;
|
||||
onConfirmDowngrade: () => void;
|
||||
onCancelDowngrade: () => void;
|
||||
}) {
|
||||
const confirmDowngrade = useCallback(() => {
|
||||
onConfirmDowngrade(
|
||||
versionInfo?.remote?.systemVersion || undefined,
|
||||
versionInfo?.remote?.appVersion || undefined,
|
||||
);
|
||||
}, [versionInfo, onConfirmDowngrade]);
|
||||
onConfirmDowngrade();
|
||||
}, [onConfirmDowngrade]);
|
||||
return (
|
||||
<div className="flex flex-col items-start justify-start space-y-4 text-left">
|
||||
<div className="text-left">
|
||||
|
|
@ -479,15 +495,15 @@ function UpdateDowngradeAvailableState({
|
|||
{m.general_update_downgrade_available_description()}
|
||||
</p>
|
||||
<p className="mb-4 text-sm text-slate-600 dark:text-slate-300">
|
||||
{versionInfo?.systemDowngradeAvailable ? (
|
||||
{systemVersion ? (
|
||||
<>
|
||||
<span className="font-semibold">{m.general_update_system_type()}</span>: {versionInfo?.remote?.systemVersion}
|
||||
<span className="font-semibold">{m.general_update_system_type()}</span>: {systemVersion}
|
||||
<br />
|
||||
</>
|
||||
) : null}
|
||||
{versionInfo?.appDowngradeAvailable ? (
|
||||
{appVersion ? (
|
||||
<>
|
||||
<span className="font-semibold">{m.general_update_application_type()}</span>: {versionInfo?.remote?.appVersion}
|
||||
<span className="font-semibold">{m.general_update_application_type()}</span>: {appVersion}
|
||||
</>
|
||||
) : null}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -244,3 +244,21 @@ export async function getLocalVersion() {
|
|||
if (response.error) throw response.error;
|
||||
return response.result;
|
||||
}
|
||||
|
||||
export interface updateParams {
|
||||
app?: string;
|
||||
system?: string;
|
||||
components?: string;
|
||||
}
|
||||
|
||||
export async function checkUpdateComponents(params: updateParams, includePreRelease: boolean) {
|
||||
const response = await callJsonRpc<SystemVersionInfo>({
|
||||
method: "checkUpdateComponents",
|
||||
params: {
|
||||
params,
|
||||
includePreRelease,
|
||||
},
|
||||
});
|
||||
if (response.error) throw response.error;
|
||||
return response.result;
|
||||
}
|
||||
Loading…
Reference in New Issue