From 7adefed653a2c3d484f30a6e2339873999177ace Mon Sep 17 00:00:00 2001 From: Julius Jurgelenas Date: Sat, 15 Jun 2024 23:28:26 +0300 Subject: [PATCH 1/2] Rename developer mode to "expert mode". Move "expert mode" config item to context api. --- src/i18n/locales/en/messages.json | 5 ++-- src/ui/components/DeviceOptionsForm/index.tsx | 6 ++-- .../components/FirmwareVersionForm/index.tsx | 12 ++++---- src/ui/components/Sidebar/index.tsx | 6 ++-- src/ui/context/AppStateProvider.tsx | 24 +++++++++++++--- src/ui/hooks/useAppState.tsx | 2 +- src/ui/hooks/useDeveloperMode.tsx | 28 ------------------- src/ui/models/AppState.tsx | 1 + src/ui/storage/index.ts | 16 +++++------ src/ui/views/SettingsView/index.tsx | 20 ++++++++----- 10 files changed, 57 insertions(+), 63 deletions(-) delete mode 100644 src/ui/hooks/useDeveloperMode.tsx diff --git a/src/i18n/locales/en/messages.json b/src/i18n/locales/en/messages.json index 234c4932a..e57087667 100644 --- a/src/i18n/locales/en/messages.json +++ b/src/i18n/locales/en/messages.json @@ -209,8 +209,9 @@ "Settings": "Settings", "LanguageSelector": "Language selector", "CurrentLanguage": "Current language", - "DeveloperMode": "Developer Mode", - "DeveloperOptions": "Developer Options" + "ExpertMode": "Expert Mode", + "ApplicationOptions": "Application Options", + "ExpertModeDescription": "Enable Expert Mode to unlock advanced features including additional firmware sources, the ability to build firmware with manual user-defined parameters, and access to serial monitor screen for detailed diagnostics." }, "SupportView": { "Support": "Support", diff --git a/src/ui/components/DeviceOptionsForm/index.tsx b/src/ui/components/DeviceOptionsForm/index.tsx index 417d6b609..4d17e52ea 100644 --- a/src/ui/components/DeviceOptionsForm/index.tsx +++ b/src/ui/components/DeviceOptionsForm/index.tsx @@ -20,7 +20,7 @@ import { } from '../../gql/generated/types'; import ShowAlerts from '../ShowAlerts'; import Loader from '../Loader'; -import useDeveloperMode from '../../hooks/useDeveloperMode'; +import useAppState from '../../hooks/useAppState'; const styles: Record> = { categoryTitle: { @@ -243,11 +243,11 @@ const DeviceOptionsForm: FunctionComponent = ( }); }; - const { isDeveloperModeEnabled } = useDeveloperMode(); + const { isExpertModeEnabled } = useAppState(); return ( <> - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( > = { tabs: { @@ -405,7 +405,7 @@ const FirmwareVersionForm: FunctionComponent = ( const showBetaFpvAlert = localPath?.toLocaleLowerCase()?.indexOf('betafpv') > -1; - const { isDeveloperModeEnabled } = useDeveloperMode(); + const { isExpertModeEnabled } = useAppState(); return ( <> @@ -419,25 +419,25 @@ const FirmwareVersionForm: FunctionComponent = ( label={t('FirmwareVersionForm.OfficialReleases')} value={FirmwareSource.GitTag} /> - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( )} - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( )} - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( )} - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( > = { const Sidebar: FunctionComponent = () => { const location = useLocation(); - const { isDeveloperModeEnabled } = useDeveloperMode(); const configuratorActive = matchPath(location.pathname, '/configurator') !== null; const backpackActive = matchPath(location.pathname, '/backpack') !== null; @@ -53,7 +51,7 @@ const Sidebar: FunctionComponent = () => { matchPath(location.pathname, '/serial-monitor') !== null; const settingsActive = matchPath(location.pathname, '/settings') !== null; const supportActive = matchPath(location.pathname, '/support') !== null; - const { appStatus } = useAppState(); + const { appStatus, isExpertModeEnabled } = useAppState(); const navigationEnabled = appStatus !== AppStatus.Busy; @@ -103,7 +101,7 @@ const Sidebar: FunctionComponent = () => { - {isDeveloperModeEnabled && ( + {isExpertModeEnabled && ( void; }>({ - appState: { appStatus: AppStatus.Interactive }, + appState: { + appStatus: AppStatus.Interactive, + isExpertModeEnabled: false, + }, setAppState: () => {}, }); @@ -17,10 +21,22 @@ interface AppStateProviderContextProps { const AppStateProvider: FunctionComponent = ({ children, }) => { - const [appState, setAppState] = useState({ - appStatus: AppStatus.Interactive, + const [appState, setAppState] = useState(() => { + const storage = new ApplicationStorage(); + return { + appStatus: AppStatus.Interactive, + isExpertModeEnabled: storage.getExpertModeEnabled() ?? false, + }; }); - const value = useMemo(() => ({ appState, setAppState }), [appState]); + const preSetAppState = (state: AppState) => { + const storage = new ApplicationStorage(); + storage.setExpertModeEnabled(state.isExpertModeEnabled); + setAppState(state); + }; + const value = useMemo( + () => ({ appState, setAppState: preSetAppState }), + [appState] + ); return ( {children} diff --git a/src/ui/hooks/useAppState.tsx b/src/ui/hooks/useAppState.tsx index 67c040026..75bf49f91 100644 --- a/src/ui/hooks/useAppState.tsx +++ b/src/ui/hooks/useAppState.tsx @@ -13,5 +13,5 @@ export default function useAppState() { setAppState({ ...appState, appStatus: mode }); }; - return { ...appState, setAppStatus }; + return { ...appState, appState, setAppStatus, setAppState }; } diff --git a/src/ui/hooks/useDeveloperMode.tsx b/src/ui/hooks/useDeveloperMode.tsx deleted file mode 100644 index d46139caf..000000000 --- a/src/ui/hooks/useDeveloperMode.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useState, useEffect } from 'react'; -import ApplicationStorage from '../storage'; - -export default function useDeveloperMode() { - const [isDeveloperModeEnabled, setDeveloperModeEnabled] = useState(false); - - useEffect(() => { - (async () => { - const storage = new ApplicationStorage(); - setDeveloperModeEnabled( - (await storage.getDeveloperModeEnabled()) ?? false - ); - })(); - }, []); - - const setDeveloperMode = () => { - setDeveloperModeEnabled(() => { - const storage = new ApplicationStorage(); - storage.setDeveloperModeEnabled(!isDeveloperModeEnabled); - return !isDeveloperModeEnabled; - }); - }; - - return { - isDeveloperModeEnabled, - setDeveloperMode, - }; -} diff --git a/src/ui/models/AppState.tsx b/src/ui/models/AppState.tsx index 580cf1820..4f0f5928a 100644 --- a/src/ui/models/AppState.tsx +++ b/src/ui/models/AppState.tsx @@ -2,4 +2,5 @@ import AppStatus from './enum/AppStatus'; export default interface AppState { appStatus: AppStatus; + isExpertModeEnabled: boolean; } diff --git a/src/ui/storage/index.ts b/src/ui/storage/index.ts index fe7404f80..137a764e4 100644 --- a/src/ui/storage/index.ts +++ b/src/ui/storage/index.ts @@ -59,9 +59,9 @@ export interface IApplicationStorage { getShowSensitiveFieldData(field: string): Promise; - setDeveloperModeEnabled(value: boolean): Promise; + setExpertModeEnabled(value: boolean): void; - getDeveloperModeEnabled(): Promise; + getExpertModeEnabled(): boolean | null; } const DEVICE_OPTIONS_BY_TARGET_KEYSPACE = 'device_options'; @@ -72,7 +72,7 @@ const WIFI_SSID_KEY = 'wifi_ssid'; const WIFI_PASSWORD_KEY = 'wifi_password'; const REGULATORY_DOMAIN_900_KEY = 'regulatory_domain_900'; const REGULATORY_DOMAIN_2400_KEY = 'regulatory_domain_2400'; -const DEVELOPER_MODE = 'developer_mode'; +const EXPERT_MODE = 'expert_mode'; export default class ApplicationStorage implements IApplicationStorage { async saveDeviceOptions( @@ -223,18 +223,18 @@ export default class ApplicationStorage implements IApplicationStorage { return null; } - async setDeveloperModeEnabled(value: boolean): Promise { - localStorage.setItem(DEVELOPER_MODE, JSON.stringify(value)); + setExpertModeEnabled(value: boolean): void { + localStorage.setItem(EXPERT_MODE, JSON.stringify(value)); } - async getDeveloperModeEnabled(): Promise { - const value = localStorage.getItem(DEVELOPER_MODE); + getExpertModeEnabled(): boolean | null { + const value = localStorage.getItem(EXPERT_MODE); if (value) { try { return JSON.parse(value); } catch (e) { - console.error(`failed to parse state for ${DEVELOPER_MODE}`, e); + console.error(`failed to parse state for ${EXPERT_MODE}`, e); return null; } } diff --git a/src/ui/views/SettingsView/index.tsx b/src/ui/views/SettingsView/index.tsx index aa1d0c2b1..c57b1f626 100644 --- a/src/ui/views/SettingsView/index.tsx +++ b/src/ui/views/SettingsView/index.tsx @@ -14,7 +14,7 @@ import CardTitle from '../../components/CardTitle'; import MainLayout from '../../layouts/MainLayout'; import Omnibox, { Option } from '../../components/Omnibox'; import locales from '../../../i18n/locales.json'; -import useDeveloperMode from '../../hooks/useDeveloperMode'; +import useAppState from '../../hooks/useAppState'; const SettingsView: FunctionComponent = () => { const { t, i18n } = useTranslation(); @@ -47,8 +47,13 @@ const SettingsView: FunctionComponent = () => { }; } - const { isDeveloperModeEnabled, setDeveloperMode } = useDeveloperMode(); - + const { appState, setAppState } = useAppState(); + const setExpertMode = () => { + setAppState({ + ...appState, + isExpertModeEnabled: !appState.isExpertModeEnabled, + }); + }; return ( @@ -69,20 +74,21 @@ const SettingsView: FunctionComponent = () => { } - title={t('SettingsView.DeveloperOptions')} + title={t('SettingsView.ApplicationOptions')} /> { - setDeveloperMode(); + setExpertMode(); }} /> } - label={t('SettingsView.DeveloperMode')} + label={<>{t('SettingsView.ExpertMode')}} /> +

{t('SettingsView.ExpertModeDescription')}

From 37b51ea1c2be595704ece7899acb3b97cd49ec0a Mon Sep 17 00:00:00 2001 From: Julius Jurgelenas Date: Sat, 15 Jun 2024 23:46:53 +0300 Subject: [PATCH 2/2] fix Report from Mike: "Saving log files doesn't work for me. No file generated. I had to go through the clipboard." --- src/main/main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/main.ts b/src/main/main.ts index be0b13d4f..49ed99a0d 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -574,7 +574,8 @@ ipcMain.on( ipcMain.handle( IpcRequest.SaveFile, - async (_, arg: SaveFileRequestBody): Promise => { + async (_, args: [SaveFileRequestBody]): Promise => { + const arg = args[0]; const result = await dialog.showSaveDialog({ title: 'Save File', defaultPath: arg.defaultPath,