diff --git a/assets/locales/en/translation.json b/assets/locales/en/translation.json index dcae4b5ed..eeb11560e 100644 --- a/assets/locales/en/translation.json +++ b/assets/locales/en/translation.json @@ -74,6 +74,8 @@ "Privacy": "Privacy", "SendErrorReports": "Send error reports", "SendErrorReportsDescription": "Enabled by default in alpha releases to fix bugs and improve the app.", + "PreReleaseUpdates": "Pre-release Updates", + "PreReleaseUpdatesDescription": "Disabled by default. Enable to update and test pre-release versions of the app. Pre-releases are more likely to have issues.", "YouAreRunningNiceNode": "You are running NiceNode", "NoNotificationsYet": "No notifications yet", "WellLetYouKnow": "We’ll let you know when something interesting happens!", diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 2c7378326..d65b6f573 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -52,6 +52,7 @@ import { setThemeSetting, ThemeSetting, setIsEventReportingEnabled, + getSetIsPreReleaseUpdatesEnabled, } from './state/settings'; import { getSystemInfo } from './systemInfo'; import startPodman from './podman/start'; @@ -242,6 +243,12 @@ export const initialize = () => { return setIsEventReportingEnabled(isEventReportingEnabled); }, ); + ipcMain.handle( + 'getSetIsPreReleaseUpdatesEnabled', + (_event, isPreReleaseUpdatesEnabled?: boolean) => { + return getSetIsPreReleaseUpdatesEnabled(isPreReleaseUpdatesEnabled); + }, + ); // Notifications ipcMain.handle('getNotifications', getNotifications); diff --git a/src/main/preload.ts b/src/main/preload.ts index d02fec0b8..e5200ae30 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -151,6 +151,12 @@ contextBridge.exposeInMainWorld('electron', { setIsEventReportingEnabled: (isEventReportingEnabled: boolean) => { ipcRenderer.invoke('setIsEventReportingEnabled', isEventReportingEnabled); }, + getSetIsPreReleaseUpdatesEnabled: (isPreReleaseUpdatesEnabled?: boolean) => { + ipcRenderer.invoke( + 'getSetIsPreReleaseUpdatesEnabled', + isPreReleaseUpdatesEnabled, + ); + }, // Notifications getNotifications: () => ipcRenderer.invoke('getNotifications'), diff --git a/src/main/state/settings.ts b/src/main/state/settings.ts index 0018e403a..a38edd603 100644 --- a/src/main/state/settings.ts +++ b/src/main/state/settings.ts @@ -6,6 +6,7 @@ import { getPlatform, isLinux } from '../platform'; import store from './store'; import { setOpenAtLoginLinux } from '../util/linuxAutostartFile'; +import { setAllowPrerelease } from '../updater'; // export type Settings = Record; const SETTINGS_KEY = 'settings'; @@ -21,6 +22,7 @@ const APP_THEME_SETTING = 'appThemeSetting'; const APP_IS_OPEN_ON_STARTUP = 'appIsOpenOnStartup'; const APP_IS_NOTIFICATIONS_ENABLED = 'appIsNotificationsEnabled'; const APP_IS_EVENT_REPORTING_ENABLED = 'appIsEventReportingEnabled'; +const APP_IS_PRE_RELEASE_UPDATES_ENABLED = 'appIsPreReleaseUpdatesEnabled'; export type ThemeSetting = 'light' | 'dark' | 'auto'; export type Settings = { @@ -34,6 +36,7 @@ export type Settings = { [APP_IS_OPEN_ON_STARTUP]?: boolean; [APP_IS_NOTIFICATIONS_ENABLED]?: boolean; [APP_IS_EVENT_REPORTING_ENABLED]?: boolean; + [APP_IS_PRE_RELEASE_UPDATES_ENABLED]?: boolean; }; /** @@ -165,6 +168,25 @@ export const setIsEventReportingEnabled = ( ); }; +export const getSetIsPreReleaseUpdatesEnabled = ( + isPreReleaseUpdatesEnabled?: boolean, +) => { + if (isPreReleaseUpdatesEnabled !== undefined) { + logger.info( + `Setting isPreReleaseUpdatesEnabled to ${isPreReleaseUpdatesEnabled}`, + ); + store.set( + `${SETTINGS_KEY}.${APP_IS_PRE_RELEASE_UPDATES_ENABLED}`, + isPreReleaseUpdatesEnabled, + ); + setAllowPrerelease(isPreReleaseUpdatesEnabled); + } + const savedIsPreReleaseUpdatesEnabled: boolean = store.get( + `${SETTINGS_KEY}.${APP_IS_PRE_RELEASE_UPDATES_ENABLED}`, + ); + return savedIsPreReleaseUpdatesEnabled; +}; + // listen to OS theme updates nativeTheme.on('updated', () => { console.log("nativeTheme.on('updated')"); diff --git a/src/main/updater.ts b/src/main/updater.ts index a6a2643e8..dad8f85eb 100644 --- a/src/main/updater.ts +++ b/src/main/updater.ts @@ -5,6 +5,7 @@ import sleep from 'await-sleep'; import logger, { autoUpdateLogger } from './logger'; import { reportEvent } from './events'; import { i18nMain } from './i18nMain'; +import { getSetIsPreReleaseUpdatesEnabled } from './state/settings'; let notifyUserIfNoUpdateAvailable: boolean; @@ -89,6 +90,9 @@ export const initialize = (mainWindow: BrowserWindow) => { autoUpdater.logger = autoUpdateLogger; autoUpdater.autoDownload = false; autoUpdater.autoInstallOnAppQuit = false; + const isPreReleaseUpdatesEnabled = getSetIsPreReleaseUpdatesEnabled(); + logger.info(`isPreReleaseUpdatesEnabled: ${isPreReleaseUpdatesEnabled}`); + autoUpdater.allowPrerelease = isPreReleaseUpdatesEnabled; notifyUserIfNoUpdateAvailable = false; intiUpdateHandlers(mainWindow); }; @@ -97,3 +101,8 @@ export const checkForUpdates = (notifyIfNoUpdateAvailable: boolean) => { notifyUserIfNoUpdateAvailable = notifyIfNoUpdateAvailable; autoUpdater.checkForUpdatesAndNotify(); }; + +export const setAllowPrerelease = (isAllowPrerelease: boolean) => { + logger.info(`updater.allowPrerelease set to: ${isAllowPrerelease}`); + autoUpdater.allowPrerelease = isAllowPrerelease; +}; diff --git a/src/renderer/Presentational/ModalManager/PreferencesModal.tsx b/src/renderer/Presentational/ModalManager/PreferencesModal.tsx index b5149d968..9d2b7cc62 100644 --- a/src/renderer/Presentational/ModalManager/PreferencesModal.tsx +++ b/src/renderer/Presentational/ModalManager/PreferencesModal.tsx @@ -37,6 +37,7 @@ export const PreferencesModal = ({ modalOnClose }: Props) => { isOpenOnStartup, isNotificationsEnabled, isEventReportingEnabled, + isPreReleaseUpdatesEnabled, language, } = updatedConfig || (modalConfig as ModalConfig); @@ -54,6 +55,11 @@ export const PreferencesModal = ({ modalOnClose }: Props) => { await electron.setIsEventReportingEnabled(isEventReportingEnabled); setRemoteEventReportingEnabled(isEventReportingEnabled); } + if (isPreReleaseUpdatesEnabled !== undefined) { + await electron.getSetIsPreReleaseUpdatesEnabled( + isPreReleaseUpdatesEnabled, + ); + } if (language) { await electron.setLanguage(language); qSettings.refetch(); diff --git a/src/renderer/Presentational/Preferences/Preferences.tsx b/src/renderer/Presentational/Preferences/Preferences.tsx index 4d3d5571c..bf93bb862 100644 --- a/src/renderer/Presentational/Preferences/Preferences.tsx +++ b/src/renderer/Presentational/Preferences/Preferences.tsx @@ -35,6 +35,7 @@ export type Preference = | 'isOpenOnStartup' | 'isNotificationsEnabled' | 'isEventReportingEnabled' + | 'isPreReleaseUpdatesEnabled' | 'language'; export interface PreferencesProps { themeSetting?: ThemeSetting; @@ -42,6 +43,7 @@ export interface PreferencesProps { osDarkMode?: boolean; isNotificationsEnabled?: boolean; isEventReportingEnabled?: boolean; + isPreReleaseUpdatesEnabled?: boolean; version?: string; language?: string; onChange?: (preference: Preference, value: unknown) => void; @@ -53,6 +55,7 @@ const Preferences = ({ osDarkMode, isNotificationsEnabled, isEventReportingEnabled, + isPreReleaseUpdatesEnabled, version, language, onChange, @@ -245,6 +248,35 @@ const Preferences = ({ ]} /> +
+
{t('Advanced')}
+ + { + if (onChange) { + onChange('isPreReleaseUpdatesEnabled', newValue); + } + }} + /> + ), + }, + ], + }, + ]} + /> +
{t('YouAreRunningNiceNode')} {version} {process.env.NICENODE_ENV}
diff --git a/src/renderer/Presentational/Preferences/PreferencesWrapper.tsx b/src/renderer/Presentational/Preferences/PreferencesWrapper.tsx index 0ade20ae3..fdb40bba8 100644 --- a/src/renderer/Presentational/Preferences/PreferencesWrapper.tsx +++ b/src/renderer/Presentational/Preferences/PreferencesWrapper.tsx @@ -21,6 +21,8 @@ const PreferencesWrapper = ({ useState(); const [sIsEventReportingEnabled, setIsEventReportingEnabled] = useState(); + const [sIsPreReleaseUpdatesEnabled, setIsPreReleaseUpdatesEnabled] = + useState(); const [sNiceNodeVersion, setNiceNodeVersion] = useState(); const [sLanguageSetting, setLanguageSetting] = useState(); @@ -45,11 +47,14 @@ const PreferencesWrapper = ({ const isOpenAtStartupSetting = userSettings.appIsOpenOnStartup || false; const isEventReportingEnabled = userSettings.appIsEventReportingEnabled || false; + const isPreReleaseUpdatesEnabled = + userSettings.appIsPreReleaseUpdatesEnabled || false; setThemeSetting(themeSetting); setOsIsDarkMode(osIsDarkMode); setIsNotificationsEnabled(notificationsSetting); setIsOpenOnStartup(isOpenAtStartupSetting); setIsEventReportingEnabled(isEventReportingEnabled); + setIsPreReleaseUpdatesEnabled(isPreReleaseUpdatesEnabled); }; const getNiceNodeVersion = async () => { @@ -112,6 +117,12 @@ const PreferencesWrapper = ({ modalOnChangeConfig({ isEventReportingEnabled, }); + } else if (preference === 'isPreReleaseUpdatesEnabled') { + const isPreReleaseUpdatesEnabled = value as boolean; + setIsPreReleaseUpdatesEnabled(isPreReleaseUpdatesEnabled); + modalOnChangeConfig({ + isPreReleaseUpdatesEnabled, + }); } else if (preference === 'language') { const language = value as string; setLanguageSetting(language); @@ -132,6 +143,7 @@ const PreferencesWrapper = ({ version={sNiceNodeVersion} isNotificationsEnabled={sIsNotificationsEnabled} isEventReportingEnabled={sIsEventReportingEnabled} + isPreReleaseUpdatesEnabled={sIsPreReleaseUpdatesEnabled} language={sLanguageSetting} onChange={onChangePreference} /> diff --git a/src/renderer/preload.d.ts b/src/renderer/preload.d.ts index aa2c7543f..97d80492f 100644 --- a/src/renderer/preload.d.ts +++ b/src/renderer/preload.d.ts @@ -120,6 +120,9 @@ declare global { setIsOpenOnStartup(isOpenOnStartup: boolean): void; getSetIsNotificationsEnabled(isNotificationsEnabled?: boolean): void; setIsEventReportingEnabled(isEventReportingEnabled: boolean): void; + getSetIsPreReleaseUpdatesEnabled( + isPreReleaseUpdatesEnabled?: boolean, + ): void; // Notifications getNotifications(): any;