diff options
Diffstat (limited to 'gui/src/renderer')
| -rw-r--r-- | gui/src/renderer/app.tsx | 30 | ||||
| -rw-r--r-- | gui/src/renderer/components/Settings.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/components/SplitTunnelingSettings.tsx | 80 | ||||
| -rw-r--r-- | gui/src/renderer/components/Switch.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/TransitionContainer.tsx | 1 | ||||
| -rw-r--r-- | gui/src/renderer/components/cell/Selector.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/cell/SettingsSelect.tsx | 1 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/actions.ts | 6 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 4 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/actions.ts | 16 | ||||
| -rw-r--r-- | gui/src/renderer/redux/userinterface/reducers.ts | 8 |
11 files changed, 92 insertions, 62 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index 92c4cb5698..3aa73698dc 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -4,7 +4,10 @@ import { bindActionCreators } from 'redux'; import { StyleSheetManager } from 'styled-components'; import { closeToExpiry, hasExpired } from '../shared/account-expiry'; -import { ILinuxSplitTunnelingApplication, IWindowsApplication } from '../shared/application-types'; +import { + ILinuxSplitTunnelingApplication, + ISplitTunnelingApplication, +} from '../shared/application-types'; import { AccessMethodSetting, AccountToken, @@ -185,7 +188,7 @@ export default class AppRenderer { this.storeAutoStart(autoStart); }); - IpcRendererEventChannel.windowsSplitTunneling.listen((applications: IWindowsApplication[]) => { + IpcRendererEventChannel.splitTunneling.listen((applications: ISplitTunnelingApplication[]) => { this.reduxActions.settings.setSplitTunnelingApplications(applications); }); @@ -242,6 +245,7 @@ export default class AppRenderer { this.storeAutoStart(initialState.autoStart); this.setChangelog(initialState.changelog, initialState.forceShowChanges); this.setCurrentApiAccessMethod(initialState.currentApiAccessMethod); + this.reduxActions.userInterface.setIsMacOs13OrNewer(initialState.isMacOs13OrNewer); if (initialState.macOsScrollbarVisibility !== undefined) { this.reduxActions.userInterface.setMacOsScrollbarVisibility( @@ -258,9 +262,9 @@ export default class AppRenderer { this.checkContentHeight(true); }); - if (initialState.windowsSplitTunnelingApplications) { + if (initialState.splitTunnelingApplications) { this.reduxActions.settings.setSplitTunnelingApplications( - initialState.windowsSplitTunnelingApplications, + initialState.splitTunnelingApplications, ); } @@ -334,11 +338,11 @@ export default class AppRenderer { public launchExcludedApplication = (application: ILinuxSplitTunnelingApplication | string) => IpcRendererEventChannel.linuxSplitTunneling.launchApplication(application); public setSplitTunnelingState = (state: boolean) => - IpcRendererEventChannel.windowsSplitTunneling.setState(state); - public addSplitTunnelingApplication = (application: string | IWindowsApplication) => - IpcRendererEventChannel.windowsSplitTunneling.addApplication(application); - public forgetManuallyAddedSplitTunnelingApplication = (application: IWindowsApplication) => - IpcRendererEventChannel.windowsSplitTunneling.forgetManuallyAddedApplication(application); + IpcRendererEventChannel.splitTunneling.setState(state); + public addSplitTunnelingApplication = (application: string | ISplitTunnelingApplication) => + IpcRendererEventChannel.splitTunneling.addApplication(application); + public forgetManuallyAddedSplitTunnelingApplication = (application: ISplitTunnelingApplication) => + IpcRendererEventChannel.splitTunneling.forgetManuallyAddedApplication(application); public setObfuscationSettings = (obfuscationSettings: ObfuscationSettings) => IpcRendererEventChannel.settings.setObfuscationSettings(obfuscationSettings); public setDaitaSettings = (daitaSettings: IDaitaSettings) => @@ -513,12 +517,12 @@ export default class AppRenderer { return IpcRendererEventChannel.autoStart.set(autoStart); }; - public getWindowsSplitTunnelingApplications(updateCache = false) { - return IpcRendererEventChannel.windowsSplitTunneling.getApplications(updateCache); + public getSplitTunnelingApplications(updateCache = false) { + return IpcRendererEventChannel.splitTunneling.getApplications(updateCache); } - public removeSplitTunnelingApplication(application: IWindowsApplication) { - void IpcRendererEventChannel.windowsSplitTunneling.removeApplication(application); + public removeSplitTunnelingApplication(application: ISplitTunnelingApplication) { + void IpcRendererEventChannel.splitTunneling.removeApplication(application); } public async showLaunchDaemonSettings() { diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx index 8f68a1c462..34fb3eb0c1 100644 --- a/gui/src/renderer/components/Settings.tsx +++ b/gui/src/renderer/components/Settings.tsx @@ -26,8 +26,10 @@ export default function Support() { const loginState = useSelector((state) => state.account.status); const connectedToDaemon = useSelector((state) => state.userInterface.connectedToDaemon); + const isMacOs13OrNewer = useSelector((state) => state.userInterface.isMacOs13OrNewer); const showSubSettings = loginState.type === 'ok' && connectedToDaemon; + const showSplitTunneling = window.env.platform !== 'darwin' || isMacOs13OrNewer; return ( <BackAction action={history.pop}> @@ -59,7 +61,7 @@ export default function Support() { <VpnSettingsButton /> </Cell.Group> - {(window.env.platform === 'linux' || window.env.platform === 'win32') && ( + {showSplitTunneling && ( <Cell.Group> <SplitTunnelingButton /> </Cell.Group> diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx index cb4de70deb..2cee823b3e 100644 --- a/gui/src/renderer/components/SplitTunnelingSettings.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx @@ -6,7 +6,7 @@ import { colors, strings } from '../../config.json'; import { IApplication, ILinuxSplitTunnelingApplication, - IWindowsApplication, + ISplitTunnelingApplication, } from '../../shared/application-types'; import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; @@ -91,10 +91,8 @@ function PlatformSpecificSplitTunnelingSettings(props: IPlatformSplitTunnelingSe switch (window.env.platform) { case 'linux': return <LinuxSplitTunnelingSettings {...props} />; - case 'win32': - return <WindowsSplitTunnelingSettings {...props} />; default: - throw new Error(`Split tunneling not implemented on ${window.env.platform}`); + return <SplitTunnelingSettings {...props} />; } } @@ -300,12 +298,12 @@ function LinuxApplicationRow(props: ILinuxApplicationRowProps) { ); } -export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps) { +export function SplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps) { const { addSplitTunnelingApplication, removeSplitTunnelingApplication, forgetManuallyAddedSplitTunnelingApplication, - getWindowsSplitTunnelingApplications, + getSplitTunnelingApplications, setSplitTunnelingState, } = useAppContext(); const splitTunnelingEnabled = useSelector((state: IReduxState) => state.settings.splitTunneling); @@ -314,13 +312,13 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett ); const [searchTerm, setSearchTerm] = useState(''); - const [applications, setApplications] = useState<IWindowsApplication[]>(); + const [applications, setApplications] = useState<ISplitTunnelingApplication[]>(); useAsyncEffect(async () => { - const { fromCache, applications } = await getWindowsSplitTunnelingApplications(); + const { fromCache, applications } = await getSplitTunnelingApplications(); setApplications(applications); if (fromCache) { - const { applications } = await getWindowsSplitTunnelingApplications(true); + const { applications } = await getSplitTunnelingApplications(true); setApplications(applications); } }, []); @@ -345,7 +343,7 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett }, [applications, splitTunnelingApplications, searchTerm]); const addApplication = useCallback( - async (application: IWindowsApplication | string) => { + async (application: ISplitTunnelingApplication | string) => { if (!splitTunnelingEnabled) { await setSplitTunnelingState(true); } @@ -354,26 +352,26 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett [addSplitTunnelingApplication, splitTunnelingEnabled, setSplitTunnelingState], ); - const addApplicationAndUpdate = useCallback( - async (application: IWindowsApplication | string) => { + const addBrowsedForApplication = useCallback( + async (application: string) => { await addApplication(application); - const { applications } = await getWindowsSplitTunnelingApplications(); + const { applications } = await getSplitTunnelingApplications(); setApplications(applications); }, - [addApplication, getWindowsSplitTunnelingApplications], + [addApplication, getSplitTunnelingApplications], ); const forgetManuallyAddedApplicationAndUpdate = useCallback( - async (application: IWindowsApplication) => { + async (application: ISplitTunnelingApplication) => { await forgetManuallyAddedSplitTunnelingApplication(application); - const { applications } = await getWindowsSplitTunnelingApplications(); + const { applications } = await getSplitTunnelingApplications(); setApplications(applications); }, - [forgetManuallyAddedSplitTunnelingApplication, getWindowsSplitTunnelingApplications], + [forgetManuallyAddedSplitTunnelingApplication, getSplitTunnelingApplications], ); const removeApplication = useCallback( - async (application: IWindowsApplication) => { + async (application: ISplitTunnelingApplication) => { if (!splitTunnelingEnabled) { await setSplitTunnelingState(true); } @@ -385,8 +383,8 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett const filePickerCallback = useFilePicker( messages.pgettext('split-tunneling-view', 'Add'), props.setBrowsing, - addApplicationAndUpdate, - { name: 'Executables', extensions: ['exe', 'lnk'] }, + addBrowsedForApplication, + getFilePickerOptionsForPlatform(), ); const addWithFilePicker = useCallback(async () => { @@ -395,21 +393,17 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett }, [filePickerCallback, props.scrollToTop]); const excludedRowRenderer = useCallback( - (application: IWindowsApplication) => ( - <WindowsApplicationRow application={application} onRemove={removeApplication} /> + (application: ISplitTunnelingApplication) => ( + <ApplicationRow application={application} onRemove={removeApplication} /> ), [removeApplication], ); const includedRowRenderer = useCallback( - (application: IWindowsApplication) => { + (application: ISplitTunnelingApplication) => { const onForget = application.deletable ? forgetManuallyAddedApplicationAndUpdate : undefined; return ( - <WindowsApplicationRow - application={application} - onAdd={addApplication} - onDelete={onForget} - /> + <ApplicationRow application={application} onAdd={addApplication} onDelete={onForget} /> ); }, [addApplication, forgetManuallyAddedApplicationAndUpdate], @@ -452,6 +446,7 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett <Accordion expanded={showSplitSection}> <Cell.Section sectionTitle={excludedTitle}> <ApplicationList + data-testid="split-applications" applications={filteredSplitApplications} rowRenderer={excludedRowRenderer} /> @@ -461,6 +456,7 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett <Accordion expanded={showNonSplitSection}> <Cell.Section sectionTitle={allTitle}> <ApplicationList + data-testid="non-split-applications" applications={filteredNonSplitApplications} rowRenderer={includedRowRenderer} /> @@ -490,6 +486,7 @@ export function WindowsSplitTunnelingSettings(props: IPlatformSplitTunnelingSett interface IApplicationListProps<T extends IApplication> { applications: T[] | undefined; rowRenderer: (application: T) => React.ReactElement; + 'data-testid'?: string; } function ApplicationList<T extends IApplication>(props: IApplicationListProps<T>) { @@ -501,8 +498,11 @@ function ApplicationList<T extends IApplication>(props: IApplicationListProps<T> ); } else { return ( - <StyledListContainer> - <List items={props.applications} getKey={applicationGetKey}> + <StyledListContainer data-testid={props['data-testid']}> + <List + data-testid={props['data-testid']} + items={props.applications.sort((a, b) => a.name.localeCompare(b.name))} + getKey={applicationGetKey}> {props.rowRenderer} </List> </StyledListContainer> @@ -514,14 +514,14 @@ function applicationGetKey<T extends IApplication>(application: T): string { return application.absolutepath; } -interface IWindowsApplicationRowProps { - application: IWindowsApplication; - onAdd?: (application: IWindowsApplication) => void; - onRemove?: (application: IWindowsApplication) => void; - onDelete?: (application: IWindowsApplication) => void; +interface IApplicationRowProps { + application: ISplitTunnelingApplication; + onAdd?: (application: ISplitTunnelingApplication) => void; + onRemove?: (application: ISplitTunnelingApplication) => void; + onDelete?: (application: ISplitTunnelingApplication) => void; } -function WindowsApplicationRow(props: IWindowsApplicationRowProps) { +function ApplicationRow(props: IApplicationRowProps) { const onAdd = useCallback(() => { props.onAdd?.(props.application); }, [props.onAdd, props.application]); @@ -576,3 +576,11 @@ function WindowsApplicationRow(props: IWindowsApplicationRowProps) { function includesSearchTerm(application: IApplication, searchTerm: string) { return application.name.toLowerCase().includes(searchTerm.toLowerCase()); } + +function getFilePickerOptionsForPlatform(): + | { name: string; extensions: Array<string> } + | undefined { + return window.env.platform === 'win32' + ? { name: 'Executables', extensions: ['exe', 'lnk'] } + : undefined; +} diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx index f87bf2a52b..595bc422a2 100644 --- a/gui/src/renderer/components/Switch.tsx +++ b/gui/src/renderer/components/Switch.tsx @@ -5,9 +5,7 @@ import { colors } from '../../config.json'; interface IProps { id?: string; - // eslint-disable-next-line @typescript-eslint/naming-convention 'aria-labelledby'?: string; - // eslint-disable-next-line @typescript-eslint/naming-convention 'aria-describedby'?: string; isOn: boolean; onChange?: (isOn: boolean) => void; diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 9773c64512..3e7007e3c8 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -48,7 +48,6 @@ interface StyledTransitionContentProps { export const StyledTransitionContent = styled.div.attrs< StyledTransitionContentProps, - // eslint-disable-next-line @typescript-eslint/naming-convention { 'data-testid': string } >({ 'data-testid': 'transition-content', diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx index 5e5d685a59..6bfeeb3887 100644 --- a/gui/src/renderer/components/cell/Selector.tsx +++ b/gui/src/renderer/components/cell/Selector.tsx @@ -16,7 +16,6 @@ export interface SelectorItem<T> { label: string; value: T; disabled?: boolean; - // eslint-disable-next-line @typescript-eslint/naming-convention 'data-testid'?: string; } @@ -136,7 +135,6 @@ interface SelectorCellProps<T> { onSelect: (value: T) => void; children: React.ReactNode | Array<React.ReactNode>; forwardedRef?: React.Ref<HTMLButtonElement>; - // eslint-disable-next-line @typescript-eslint/naming-convention 'data-testid'?: string; } diff --git a/gui/src/renderer/components/cell/SettingsSelect.tsx b/gui/src/renderer/components/cell/SettingsSelect.tsx index 4286cda1e2..f0d918ded6 100644 --- a/gui/src/renderer/components/cell/SettingsSelect.tsx +++ b/gui/src/renderer/components/cell/SettingsSelect.tsx @@ -87,7 +87,6 @@ interface SettingsSelectProps<T extends string> { items: Array<SettingsSelectItem<T>>; onUpdate: (value: T) => void; direction?: 'down' | 'up'; - // eslint-disable-next-line @typescript-eslint/naming-convention 'data-testid'?: string; } diff --git a/gui/src/renderer/redux/settings/actions.ts b/gui/src/renderer/redux/settings/actions.ts index ba6e4ce5a8..d2a3fb1c4a 100644 --- a/gui/src/renderer/redux/settings/actions.ts +++ b/gui/src/renderer/redux/settings/actions.ts @@ -1,4 +1,4 @@ -import { IWindowsApplication } from '../../../shared/application-types'; +import { ISplitTunnelingApplication } from '../../../shared/application-types'; import { AccessMethodSetting, ApiAccessMethodSettings, @@ -100,7 +100,7 @@ export interface IUpdateSplitTunnelingStateAction { export interface ISetSplitTunnelingApplicationsAction { type: 'SET_SPLIT_TUNNELING_APPLICATIONS'; - applications: IWindowsApplication[]; + applications: ISplitTunnelingApplication[]; } export interface ISetObfuscationSettings { @@ -281,7 +281,7 @@ function updateSplitTunnelingState(enabled: boolean): IUpdateSplitTunnelingState } function setSplitTunnelingApplications( - applications: IWindowsApplication[], + applications: ISplitTunnelingApplication[], ): ISetSplitTunnelingApplicationsAction { return { type: 'SET_SPLIT_TUNNELING_APPLICATIONS', diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts index 18873eea20..eae413fe22 100644 --- a/gui/src/renderer/redux/settings/reducers.ts +++ b/gui/src/renderer/redux/settings/reducers.ts @@ -1,5 +1,5 @@ import { getDefaultApiAccessMethods } from '../../../main/default-settings'; -import { IWindowsApplication } from '../../../shared/application-types'; +import { ISplitTunnelingApplication } from '../../../shared/application-types'; import { AccessMethodSetting, ApiAccessMethodSettings, @@ -115,7 +115,7 @@ export interface ISettingsReduxState { }; dns: IDnsOptions; splitTunneling: boolean; - splitTunnelingApplications: IWindowsApplication[]; + splitTunnelingApplications: ISplitTunnelingApplication[]; obfuscationSettings: ObfuscationSettings; customLists: CustomLists; apiAccessMethods: ApiAccessMethodSettings; diff --git a/gui/src/renderer/redux/userinterface/actions.ts b/gui/src/renderer/redux/userinterface/actions.ts index cc43990980..238835318e 100644 --- a/gui/src/renderer/redux/userinterface/actions.ts +++ b/gui/src/renderer/redux/userinterface/actions.ts @@ -56,6 +56,11 @@ export interface ISetSelectLocationView { selectLocationView: LocationType; } +export interface ISetIsMacOs13OrNewer { + type: 'SET_IS_MACOS13_OR_NEWER'; + isMacOs13OrNewer: boolean; +} + export type UserInterfaceAction = | IUpdateLocaleAction | IUpdateWindowArrowPositionAction @@ -67,7 +72,8 @@ export type UserInterfaceAction = | ISetChangelog | ISetForceShowChanges | ISetIsPerformingPostUpgrade - | ISetSelectLocationView; + | ISetSelectLocationView + | ISetIsMacOs13OrNewer; function updateLocale(locale: string): IUpdateLocaleAction { return { @@ -147,6 +153,13 @@ function setSelectLocationView(selectLocationView: LocationType): ISetSelectLoca }; } +function setIsMacOs13OrNewer(isMacOs13OrNewer: boolean): ISetIsMacOs13OrNewer { + return { + type: 'SET_IS_MACOS13_OR_NEWER', + isMacOs13OrNewer, + }; +} + export default { updateLocale, updateWindowArrowPosition, @@ -159,4 +172,5 @@ export default { setForceShowChanges, setIsPerformingPostUpgrade, setSelectLocationView, + setIsMacOs13OrNewer, }; diff --git a/gui/src/renderer/redux/userinterface/reducers.ts b/gui/src/renderer/redux/userinterface/reducers.ts index 622b7814aa..89427e9b06 100644 --- a/gui/src/renderer/redux/userinterface/reducers.ts +++ b/gui/src/renderer/redux/userinterface/reducers.ts @@ -15,6 +15,7 @@ export interface IUserInterfaceReduxState { forceShowChanges: boolean; isPerformingPostUpgrade: boolean; selectLocationView: LocationType; + isMacOs13OrNewer: boolean; } const initialState: IUserInterfaceReduxState = { @@ -28,6 +29,7 @@ const initialState: IUserInterfaceReduxState = { forceShowChanges: false, isPerformingPostUpgrade: false, selectLocationView: LocationType.exit, + isMacOs13OrNewer: true, }; export default function ( @@ -80,6 +82,12 @@ export default function ( selectLocationView: action.selectLocationView, }; + case 'SET_IS_MACOS13_OR_NEWER': + return { + ...state, + isMacOs13OrNewer: action.isMacOs13OrNewer, + }; + default: return state; } |
