diff options
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/app.tsx | 8 | ||||
| -rw-r--r-- | gui/src/renderer/components/LinuxSplitTunnelingSettings.tsx | 37 |
2 files changed, 40 insertions, 5 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index 9ba1e61252..4c79cc2192 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -20,7 +20,7 @@ import { ILinuxSplitTunnelingApplication } from '../shared/application-types'; import { messages, relayLocations } from '../shared/gettext'; import { IGuiSettingsState, SYSTEM_PREFERRED_LOCALE_KEY } from '../shared/gui-settings-state'; import log, { ConsoleOutput } from '../shared/logging'; -import { IRelayListPair } from '../shared/ipc-schema'; +import { IRelayListPair, LaunchApplicationResult } from '../shared/ipc-schema'; import consumePromise from '../shared/promise'; import History from './lib/history'; import { loadTranslations } from './lib/load-translations'; @@ -419,8 +419,10 @@ export default class AppRenderer { return IpcRendererEventChannel.splitTunneling.getApplications(); } - public launchExcludedApplication(application: ILinuxSplitTunnelingApplication | string) { - consumePromise(IpcRendererEventChannel.splitTunneling.launchApplication(application)); + public launchExcludedApplication( + application: ILinuxSplitTunnelingApplication | string, + ): Promise<LaunchApplicationResult> { + return IpcRendererEventChannel.splitTunneling.launchApplication(application); } public collectProblemReport(toRedact: string[]): Promise<string> { diff --git a/gui/src/renderer/components/LinuxSplitTunnelingSettings.tsx b/gui/src/renderer/components/LinuxSplitTunnelingSettings.tsx index 3c07e7eca0..cb7c497011 100644 --- a/gui/src/renderer/components/LinuxSplitTunnelingSettings.tsx +++ b/gui/src/renderer/components/LinuxSplitTunnelingSettings.tsx @@ -107,9 +107,20 @@ export default function LinuxSplitTunnelingSettings() { const [applications, setApplications] = useState<ILinuxSplitTunnelingApplication[]>(); const [applicationListHeight, setApplicationListHeight] = useState<number>(); const [browsing, setBrowsing] = useState(false); + const [browseError, setBrowseError] = useState<string>(); const applicationListRef = useRef() as React.RefObject<HTMLDivElement>; + const launchApplication = useCallback( + async (application: ILinuxSplitTunnelingApplication | string) => { + const result = await launchExcludedApplication(application); + if ('error' in result) { + setBrowseError(result.error); + } + }, + [], + ); + const launchWithFilePicker = useCallback(async () => { setBrowsing(true); const file = await showOpenDialog({ @@ -119,10 +130,12 @@ export default function LinuxSplitTunnelingSettings() { setBrowsing(false); if (file.filePaths[0]) { - launchExcludedApplication(file.filePaths[0]); + await launchApplication(file.filePaths[0]); } }, []); + const hideBrowseFailureDialog = useCallback(() => setBrowseError(undefined), []); + useEffect(() => { consumePromise(getSplitTunnelingApplications().then(setApplications)); }, []); @@ -181,7 +194,7 @@ export default function LinuxSplitTunnelingSettings() { <ApplicationRow key={application.absolutepath} application={application} - launchApplication={launchExcludedApplication} + launchApplication={launchApplication} /> )) )} @@ -196,6 +209,26 @@ export default function LinuxSplitTunnelingSettings() { </NavigationContainer> </StyledContainer> </Layout> + {browseError && ( + <ModalAlert + type={ModalAlertType.warning} + iconColor={colors.red} + message={sprintf( + // TRANSLATORS: Error message showed in a dialog when an application failes to launch. + messages.pgettext( + 'split-tunneling-view', + 'Unable to launch selection. %(detailedErrorMessage)s', + ), + { detailedErrorMessage: browseError }, + )} + buttons={[ + <AppButton.BlueButton key="close" onClick={hideBrowseFailureDialog}> + {messages.gettext('Close')} + </AppButton.BlueButton>, + ]} + close={hideBrowseFailureDialog} + /> + )} </ModalContainer> </> ); |
