diff --git a/client/src/state/Settings/SettingsReducer.ts b/client/src/state/Settings/SettingsReducer.ts index b47e547c4..de4ab37b1 100644 --- a/client/src/state/Settings/SettingsReducer.ts +++ b/client/src/state/Settings/SettingsReducer.ts @@ -17,7 +17,8 @@ export const initialState: ISettingsState = { autoUpdates: false, language: 'en', email: '', - token: '' + token: '', + allowPrerelease: false }; export default function settingsReducer( diff --git a/client/src/state/Settings/SettingsTypes.ts b/client/src/state/Settings/SettingsTypes.ts index 2f9692ec0..d5cda4906 100644 --- a/client/src/state/Settings/SettingsTypes.ts +++ b/client/src/state/Settings/SettingsTypes.ts @@ -12,6 +12,7 @@ export interface ISettingsState { language: string; email: string; token: string; + allowPrerelease: boolean; } export const SETTINGS_GET_SETTINGS_REQUEST = 'SETTINGS_GET_SETTINGS_REQUEST'; diff --git a/client/src/views/Launchpad.tsx b/client/src/views/Launchpad.tsx index ef8f97dc9..23e06ea69 100644 --- a/client/src/views/Launchpad.tsx +++ b/client/src/views/Launchpad.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { History } from 'history'; @@ -19,6 +19,7 @@ import { useTranslation } from 'react-i18next'; import MainSection from './components/MainSection'; import { Link } from 'react-router-dom'; +import { IState } from '../state'; import { track } from '../state/track/actions'; declare var window: { @@ -63,6 +64,9 @@ export default function Launchpad() { const { t } = useTranslation(); const dispatch = useDispatch(); const history = useHistory(); + const allowPrerelease = useSelector( + (state: IState) => state.settings.allowPrerelease + ); window.h = history; @@ -207,57 +211,61 @@ export default function Launchpad() { - - - - - - - - - + + + + - Lumi Run - - + + + + Lumi Run (Beta) + + + {t('run.description')} + + + + + + - - - + {t('analytics.startPage.start')} + + + + + + )} diff --git a/client/src/views/components/RunSetupDialog.tsx b/client/src/views/components/RunSetupDialog.tsx index 3db88951d..d5f641cc2 100644 --- a/client/src/views/components/RunSetupDialog.tsx +++ b/client/src/views/components/RunSetupDialog.tsx @@ -120,7 +120,7 @@ export default function RunSetupDialog(props: IRunSetupDialogProps) { open={open} > - Lumi Run + Lumi Run (Beta) {t('run.description')} diff --git a/client/src/views/components/Settings/GeneralSettingsList.tsx b/client/src/views/components/Settings/GeneralSettingsList.tsx index ad24859ab..ac0515cc4 100644 --- a/client/src/views/components/Settings/GeneralSettingsList.tsx +++ b/client/src/views/components/Settings/GeneralSettingsList.tsx @@ -15,6 +15,7 @@ import BugReportIcon from '@material-ui/icons/BugReport'; import InsertChartIcon from '@material-ui/icons/InsertChart'; import TranslateIcon from '@material-ui/icons/Translate'; +import UpdateIcon from '@material-ui/icons/Update'; import { actions, IState } from '../../../state'; import LanguageList from './LanguageList'; @@ -95,6 +96,33 @@ export default function SettingsGeneralSettingsList() { /> + + + + + + + + dispatch( + actions.settings.changeSetting({ + allowPrerelease: !settings.allowPrerelease + }) + ) + } + checked={settings.allowPrerelease} + inputProps={{ + 'aria-labelledby': + 'switch-list-label-prerelease-updates' + }} + /> + + diff --git a/locales/lumi/en.json b/locales/lumi/en.json index 0b0e55dc5..e7914a17a 100644 --- a/locales/lumi/en.json +++ b/locales/lumi/en.json @@ -12,6 +12,10 @@ }, "messages": { "econnrefused": "Connection Refused" } }, + "prerelease": { + "title": "Prerelease Features", + "description": "Enable experimental features before they are released" + }, "auth": { "set_email": "Set Email", "email": "Email", diff --git a/server/src/boot/defaultSettings.ts b/server/src/boot/defaultSettings.ts index ff690a965..7be4963f3 100644 --- a/server/src/boot/defaultSettings.ts +++ b/server/src/boot/defaultSettings.ts @@ -9,5 +9,6 @@ export default { autoUpdates: false, language: 'en', email: '', - token: '' + token: '', + allowPrerelease: false }; diff --git a/server/src/settingsCache.ts b/server/src/settingsCache.ts index 44c5c1fa2..b6f899b32 100644 --- a/server/src/settingsCache.ts +++ b/server/src/settingsCache.ts @@ -1,4 +1,5 @@ interface ISettingsState { + allowPrerelease: boolean; autoUpdates: boolean; bugTracking: boolean; email: string; diff --git a/server/src/updater.ts b/server/src/updater.ts index 2e7da01c0..9b6866bcc 100644 --- a/server/src/updater.ts +++ b/server/src/updater.ts @@ -4,6 +4,7 @@ import SocketIO from 'socket.io'; import * as Sentry from '@sentry/electron'; import fsExtra from 'fs-extra'; import IServerConfig from './IServerConfig'; +import settingsCache from './settingsCache'; let updateAvailable: boolean = false; let updating: boolean = false; @@ -31,6 +32,8 @@ export default async function boot( websocket: SocketIO.Server, serverConfig: IServerConfig ): Promise { + autoUpdater.allowPrerelease = settingsCache.getSettings().allowPrerelease; + autoUpdater.on('update-downloaded', async () => { updateAvailable = true;