diff --git a/internal/ota/ota.go b/internal/ota/ota.go index e23010f5..272a5414 100644 --- a/internal/ota/ota.go +++ b/internal/ota/ota.go @@ -152,12 +152,12 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error { return nil } - if shouldUpdateApp && (appUpdate.available || appUpdate.downgradeAvailable) { + if shouldUpdateApp && appUpdate.available { appUpdate.pending = true s.triggerComponentUpdateState("app", appUpdate) } - if shouldUpdateSystem && (systemUpdate.available || systemUpdate.downgradeAvailable) { + if shouldUpdateSystem && systemUpdate.available { systemUpdate.pending = true s.triggerComponentUpdateState("system", systemUpdate) } @@ -292,7 +292,6 @@ func (s *State) checkUpdateStatus( return err } systemUpdateStatus.available = systemVersionRemote.GreaterThan(systemVersionLocal) - systemUpdateStatus.downgradeAvailable = systemVersionRemote.LessThan(systemVersionLocal) appVersionRemote, err := semver.NewVersion(remoteMetadata.AppVersion) if err != nil { @@ -300,7 +299,6 @@ func (s *State) checkUpdateStatus( return err } appUpdateStatus.available = appVersionRemote.GreaterThan(appVersionLocal) - appUpdateStatus.downgradeAvailable = appVersionRemote.LessThan(appVersionLocal) // Handle pre-release updates isRemoteSystemPreRelease := systemVersionRemote.Prerelease() != "" @@ -313,6 +311,15 @@ func (s *State) checkUpdateStatus( appUpdateStatus.available = false } + // Handle custom target versions + if slices.Contains(params.Components, "app") && params.AppTargetVersion != "" { + appUpdateStatus.available = appVersionRemote.String() != appUpdateStatus.localVersion + } + + if slices.Contains(params.Components, "system") && params.SystemTargetVersion != "" { + systemUpdateStatus.available = systemVersionRemote.String() != systemUpdateStatus.localVersion + } + return nil } diff --git a/internal/ota/state.go b/internal/ota/state.go index f6a35e40..d8aa4399 100644 --- a/internal/ota/state.go +++ b/internal/ota/state.go @@ -28,12 +28,10 @@ type LocalMetadata struct { // UpdateStatus represents the current update status type UpdateStatus struct { - Local *LocalMetadata `json:"local"` - Remote *UpdateMetadata `json:"remote"` - SystemUpdateAvailable bool `json:"systemUpdateAvailable"` - SystemDowngradeAvailable bool `json:"systemDowngradeAvailable"` - AppUpdateAvailable bool `json:"appUpdateAvailable"` - AppDowngradeAvailable bool `json:"appDowngradeAvailable"` + Local *LocalMetadata `json:"local"` + Remote *UpdateMetadata `json:"remote"` + SystemUpdateAvailable bool `json:"systemUpdateAvailable"` + AppUpdateAvailable bool `json:"appUpdateAvailable"` // for backwards compatibility Error string `json:"error,omitempty"` @@ -50,7 +48,6 @@ type PostRebootAction struct { type componentUpdateStatus struct { pending bool available bool - downgradeAvailable bool version string localVersion string targetVersion string @@ -170,11 +167,9 @@ func toUpdateStatus(appUpdate *componentUpdateStatus, systemUpdate *componentUpd SystemURL: systemUpdate.url, SystemHash: systemUpdate.hash, }, - SystemUpdateAvailable: systemUpdate.available, - SystemDowngradeAvailable: systemUpdate.downgradeAvailable, - AppUpdateAvailable: appUpdate.available, - AppDowngradeAvailable: appUpdate.downgradeAvailable, - Error: error, + SystemUpdateAvailable: systemUpdate.available, + AppUpdateAvailable: appUpdate.available, + Error: error, } } diff --git a/jsonrpc.go b/jsonrpc.go index 2810e4f9..5b6d0457 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -1155,7 +1155,6 @@ var rpcHandlers = map[string]RPCHandler{ "getUpdateStatusChannel": {Func: rpcGetUpdateStatusChannel}, "tryUpdate": {Func: rpcTryUpdate}, "tryUpdateComponents": {Func: rpcTryUpdateComponents, Params: []string{"params", "includePreRelease", "resetConfig"}}, - "cancelDowngrade": {Func: rpcCancelDowngrade}, "getDevModeState": {Func: rpcGetDevModeState}, "setDevModeState": {Func: rpcSetDevModeState, Params: []string{"enabled"}}, "getSSHKeyState": {Func: rpcGetSSHKeyState}, diff --git a/ota.go b/ota.go index 1ebd54e3..44fe0cd3 100644 --- a/ota.go +++ b/ota.go @@ -194,13 +194,3 @@ func rpcTryUpdateComponents(params updateParams, includePreRelease bool, resetCo }() return nil } - -func rpcCancelDowngrade() error { - if err := otaState.SetTargetVersion("app", ""); err != nil { - return fmt.Errorf("failed to set app target version: %w", err) - } - if err := otaState.SetTargetVersion("system", ""); err != nil { - return fmt.Errorf("failed to set system target version: %w", err) - } - return nil -} diff --git a/ui/src/hooks/stores.ts b/ui/src/hooks/stores.ts index 9f7fd226..c56cb5f8 100644 --- a/ui/src/hooks/stores.ts +++ b/ui/src/hooks/stores.ts @@ -554,7 +554,6 @@ export type UpdateModalViews = | "updating" | "upToDate" | "updateAvailable" - | "updateDowngradeAvailable" | "updateCompleted" | "error"; diff --git a/ui/src/hooks/useVersion.tsx b/ui/src/hooks/useVersion.tsx index 48af1f46..feb99617 100644 --- a/ui/src/hooks/useVersion.tsx +++ b/ui/src/hooks/useVersion.tsx @@ -15,9 +15,7 @@ export interface SystemVersionInfo { local: VersionInfo; remote?: VersionInfo; systemUpdateAvailable: boolean; - systemDowngradeAvailable: boolean; appUpdateAvailable: boolean; - appDowngradeAvailable: boolean; error?: string; } diff --git a/ui/src/routes/devices.$id.settings.advanced.tsx b/ui/src/routes/devices.$id.settings.advanced.tsx index 2d251598..260db3ca 100644 --- a/ui/src/routes/devices.$id.settings.advanced.tsx +++ b/ui/src/routes/devices.$id.settings.advanced.tsx @@ -185,10 +185,10 @@ export default function SettingsAdvancedRoute() { setShowLoopbackWarning(false); }, [applyLoopbackOnlyMode, setShowLoopbackWarning]); - const handleVersionUpdateError = useCallback((error?: JsonRpcError) => { + const handleVersionUpdateError = useCallback((error?: JsonRpcError | string) => { notifications.error( m.advanced_error_version_update({ - error: error?.data ?? error?.message ?? m.unknown_error() + error: typeof error === "string" ? error : (error?.data ?? error?.message ?? m.unknown_error()) }), { duration: 1000 * 15 } // 15 seconds ); @@ -214,15 +214,31 @@ export default function SettingsAdvancedRoute() { return; } + console.debug("versionInfo", versionInfo, components.includes("app") && versionInfo.remote?.appVersion && versionInfo?.appUpdateAvailable, components.includes("system") && versionInfo.remote?.systemVersion && versionInfo?.systemUpdateAvailable); + console.debug("components", components); + console.debug("versionInfo.remote?.appVersion", versionInfo.remote?.appVersion); + console.debug("versionInfo.appUpdateAvailable", versionInfo?.appUpdateAvailable); + console.debug("versionInfo.remote?.systemVersion", versionInfo.remote?.systemVersion); + console.debug("versionInfo.systemUpdateAvailable", versionInfo?.systemUpdateAvailable); + + let hasUpdate = false; + const pageParams = new URLSearchParams(); - if (components.includes("app") && versionInfo.remote?.appVersion && versionInfo.appDowngradeAvailable) { + if (components.includes("app") && versionInfo.remote?.appVersion && versionInfo.appUpdateAvailable) { + hasUpdate = true; pageParams.set("custom_app_version", versionInfo.remote?.appVersion); } - if (components.includes("system") && versionInfo.remote?.systemVersion && versionInfo.systemDowngradeAvailable) { + if (components.includes("system") && versionInfo.remote?.systemVersion && versionInfo.systemUpdateAvailable) { + hasUpdate = true; pageParams.set("custom_system_version", versionInfo.remote?.systemVersion); } pageParams.set("reset_config", resetConfig.toString()); + if (!hasUpdate) { + handleVersionUpdateError("No update available"); + return; + } + // Navigate to update page navigateTo(`/settings/general/update?${pageParams.toString()}`); }, [ diff --git a/ui/src/routes/devices.$id.settings.general.update.tsx b/ui/src/routes/devices.$id.settings.general.update.tsx index ea2dde49..31aac2a0 100644 --- a/ui/src/routes/devices.$id.settings.general.update.tsx +++ b/ui/src/routes/devices.$id.settings.general.update.tsx @@ -443,7 +443,6 @@ function SystemUpToDateState({ function UpdateAvailableState({ versionInfo, - forceCustomUpdate, onConfirm, onClose, }: { @@ -462,13 +461,13 @@ function UpdateAvailableState({ {m.general_update_available_description()}

- {(forceCustomUpdate ? versionInfo?.systemDowngradeAvailable : versionInfo?.systemUpdateAvailable) ? ( + {versionInfo?.systemUpdateAvailable ? ( <> {m.general_update_system_type()}: {versionInfo?.local?.systemVersion} {versionInfo?.remote?.systemVersion}
) : null} - {(forceCustomUpdate ? versionInfo?.appDowngradeAvailable : versionInfo?.appUpdateAvailable) ? ( + {versionInfo?.appUpdateAvailable ? ( <> {m.general_update_application_type()}: {versionInfo?.local?.appVersion} {versionInfo?.remote?.appVersion} diff --git a/ui/src/utils/jsonrpc.ts b/ui/src/utils/jsonrpc.ts index b219a30e..51d12127 100644 --- a/ui/src/utils/jsonrpc.ts +++ b/ui/src/utils/jsonrpc.ts @@ -220,9 +220,7 @@ export interface SystemVersionInfo { local: VersionInfo; remote?: VersionInfo; systemUpdateAvailable: boolean; - systemDowngradeAvailable: boolean; appUpdateAvailable: boolean; - appDowngradeAvailable: boolean; error?: string; }