diff --git a/src/behaviours/preferences/__snapshots__/closing-preferences.test.tsx.snap b/src/behaviours/preferences/__snapshots__/closing-preferences.test.tsx.snap index 740e01edbb..5cdee87f39 100644 --- a/src/behaviours/preferences/__snapshots__/closing-preferences.test.tsx.snap +++ b/src/behaviours/preferences/__snapshots__/closing-preferences.test.tsx.snap @@ -356,13 +356,12 @@ exports[`preferences - closing-preferences given accessing preferences directly class="Select__control css-1s2u09g-control" >
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
- Select... + Stable
= { }, }; -export interface UpdateChannelInfo { - label: string; -} - -export const updateChannels = readonly(new Map([ - ["latest", { - label: "Stable", - }], - ["beta", { - label: "Beta", - }], - ["alpha", { - label: "Alpha", - }], -])); -export const defaultUpdateChannel = new SemVer(getAppVersion()).prerelease[0]?.toString() || "latest"; - -const updateChannel: PreferenceDescription = { - fromStore(val) { - return !val || !updateChannels.has(val) - ? defaultUpdateChannel - : val; - }, - toStore(val) { - if (!updateChannels.has(val) || val === defaultUpdateChannel) { - return undefined; - } - - return val; - }, -}; - export type ExtensionRegistryLocation = "default" | "npmrc" | "custom"; export type ExtensionRegistry = { @@ -365,7 +330,7 @@ export type UserStoreFlatModel = { export type UserPreferencesModel = { [field in keyof typeof DESCRIPTORS]: PreferencesModelType; -}; +} & { updateChannel: string }; export const DESCRIPTORS = { httpsProxy, @@ -385,6 +350,5 @@ export const DESCRIPTORS = { editorConfiguration, terminalCopyOnSelect, terminalConfig, - updateChannel, extensionRegistryUrl, }; diff --git a/src/common/user-store/user-store.injectable.ts b/src/common/user-store/user-store.injectable.ts index cd44cc60e5..3b4aba0b56 100644 --- a/src/common/user-store/user-store.injectable.ts +++ b/src/common/user-store/user-store.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { ipcMain } from "electron"; import userStoreFileNameMigrationInjectable from "./file-name-migration.injectable"; import { UserStore } from "./user-store"; +import selectedUpdateChannelInjectable from "../application-update/selected-update-channel/selected-update-channel.injectable"; const userStoreInjectable = getInjectable({ id: "user-store", @@ -17,7 +18,9 @@ const userStoreInjectable = getInjectable({ di.inject(userStoreFileNameMigrationInjectable); } - return UserStore.createInstance(); + return UserStore.createInstance({ + selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable), + }); }, causesSideEffects: true, diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index 35982b9183..31beabcec4 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -15,15 +15,22 @@ import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils"; import { DESCRIPTORS } from "./preferences-helpers"; import type { UserPreferencesModel, StoreType } from "./preferences-helpers"; import logger from "../../main/logger"; +import type { SelectedUpdateChannel } from "../application-update/selected-update-channel/selected-update-channel.injectable"; +import type { UpdateChannelId } from "../application-update/update-channels"; export interface UserStoreModel { lastSeenAppVersion: string; preferences: UserPreferencesModel; } +interface Dependencies { + selectedUpdateChannel: SelectedUpdateChannel; +} + export class UserStore extends BaseStore /* implements UserStoreFlatModel (when strict null is enabled) */ { readonly displayName = "UserStore"; - constructor() { + + constructor(private dependencies: Dependencies) { super({ configName: "lens-user-store", migrations, @@ -63,7 +70,6 @@ export class UserStore extends BaseStore /* implements UserStore @observable kubectlBinariesPath!: StoreType; @observable terminalCopyOnSelect!: StoreType; @observable terminalConfig!: StoreType; - @observable updateChannel!: StoreType; @observable extensionRegistryUrl!: StoreType; /** @@ -171,6 +177,11 @@ export class UserStore extends BaseStore /* implements UserStore this[key] = newVal; } } + + // TODO: Switch to action-based saving instead saving stores by reaction + if (preferences?.updateChannel) { + this.dependencies.selectedUpdateChannel.setValue(preferences?.updateChannel as UpdateChannelId); + } } toJSON(): UserStoreModel { @@ -181,7 +192,12 @@ export class UserStore extends BaseStore /* implements UserStore return toJS({ lastSeenAppVersion: this.lastSeenAppVersion, - preferences, + + preferences: { + ...preferences, + + updateChannel: this.dependencies.selectedUpdateChannel.value.get().id, + }, }); } } diff --git a/src/renderer/components/+preferences/application.tsx b/src/renderer/components/+preferences/application.tsx index bbda49f1a0..d3c0fd4414 100644 --- a/src/renderer/components/+preferences/application.tsx +++ b/src/renderer/components/+preferences/application.tsx @@ -12,7 +12,7 @@ import type { UserStore } from "../../../common/user-store"; import { Input } from "../input"; import { Switch } from "../switch"; import moment from "moment-timezone"; -import { updateChannels, defaultExtensionRegistryUrl, defaultUpdateChannel, defaultLocaleTimezone, defaultExtensionRegistryUrlLocation } from "../../../common/user-store/preferences-helpers"; +import { defaultExtensionRegistryUrl, defaultLocaleTimezone, defaultExtensionRegistryUrlLocation } from "../../../common/user-store/preferences-helpers"; import type { IComputedValue } from "mobx"; import { runInAction } from "mobx"; import { isUrl } from "../input/input_validators"; @@ -24,11 +24,17 @@ import { Preferences } from "./preferences"; import userStoreInjectable from "../../../common/user-store/user-store.injectable"; import themeStoreInjectable from "../../themes/store.injectable"; import { defaultThemeId } from "../../../common/vars"; +import { updateChannels } from "../../../common/application-update/update-channels"; +import { map, toPairs } from "lodash/fp"; +import { pipeline } from "@ogre-tools/fp"; +import type { SelectedUpdateChannel } from "../../../common/application-update/selected-update-channel/selected-update-channel.injectable"; +import selectedUpdateChannelInjectable from "../../../common/application-update/selected-update-channel/selected-update-channel.injectable"; interface Dependencies { appPreferenceItems: IComputedValue; userStore: UserStore; themeStore: ThemeStore; + selectedUpdateChannel: SelectedUpdateChannel; } const timezoneOptions = moment.tz.names() @@ -36,10 +42,16 @@ const timezoneOptions = moment.tz.names() value: timezone, label: timezone.replace("_", " "), })); -const updateChannelOptions = Array.from(updateChannels, ([channel, { label }]) => ({ - value: channel, - label, -})); + +const updateChannelOptions = pipeline( + toPairs(updateChannels), + + map(([, channel]) => ({ + value: channel.id, + label: channel.label, + })), +); + const extensionInstallRegistryOptions = [ { value: "default", @@ -55,7 +67,7 @@ const extensionInstallRegistryOptions = [ }, ] as const; -const NonInjectedApplication: React.FC = ({ appPreferenceItems, userStore, themeStore }) => { +const NonInjectedApplication: React.FC = ({ appPreferenceItems, userStore, themeStore, selectedUpdateChannel }) => { const [customUrl, setCustomUrl] = React.useState(userStore.extensionRegistryUrl.customUrl || ""); const themeOptions = [ { @@ -144,8 +156,8 @@ const NonInjectedApplication: React.FC = ({ appPreferenceItems, us