diff options
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/components/SelectLocation.tsx | 99 | ||||
| -rw-r--r-- | gui/src/renderer/components/SelectLocationStyles.tsx | 6 | ||||
| -rw-r--r-- | gui/src/renderer/containers/SelectLocationPage.tsx | 7 |
3 files changed, 79 insertions, 33 deletions
diff --git a/gui/src/renderer/components/SelectLocation.tsx b/gui/src/renderer/components/SelectLocation.tsx index cb73eeb2f0..34059f3e85 100644 --- a/gui/src/renderer/components/SelectLocation.tsx +++ b/gui/src/renderer/components/SelectLocation.tsx @@ -2,7 +2,12 @@ import React from 'react'; import { sprintf } from 'sprintf-js'; import { colors } from '../../config.json'; -import { LiftedConstraint, RelayLocation, TunnelProtocol } from '../../shared/daemon-rpc-types'; +import { + LiftedConstraint, + Ownership, + RelayLocation, + TunnelProtocol, +} from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; import { IRelayLocationRedux } from '../redux/settings/reducers'; import BridgeLocations, { SpecialBridgeLocationType } from './BridgeLocations'; @@ -25,13 +30,13 @@ import { } from './NavigationBar'; import { ScopeBarItem } from './ScopeBar'; import { - StyledClearProvidersButton, + StyledClearFilterButton, StyledContainer, StyledContent, + StyledFilter, StyledFilterIconButton, + StyledFilterRow, StyledNavigationBarAttachment, - StyledProviderCountRow, - StyledProvidersCount, StyledScopeBar, StyledSettingsHeader, } from './SelectLocationStyles'; @@ -47,6 +52,7 @@ interface IProps { allowEntrySelection: boolean; tunnelProtocol: LiftedConstraint<TunnelProtocol>; providers: string[]; + ownership: Ownership; onClose: () => void; onViewFilter: () => void; onSelectExitLocation: (location: RelayLocation) => void; @@ -54,6 +60,7 @@ interface IProps { onSelectBridgeLocation: (location: RelayLocation) => void; onSelectClosestToExit: () => void; onClearProviders: () => void; + onClearOwnership: () => void; } enum LocationScope { @@ -127,6 +134,9 @@ export default class SelectLocation extends React.Component<IProps, IState> { } public render() { + const showOwnershipFilter = this.props.ownership !== Ownership.any; + const showProvidersFilter = this.props.providers.length > 0; + const showFilters = showOwnershipFilter || showProvidersFilter; return ( <BackAction icon="close" action={this.props.onClose}> <Layout> @@ -167,32 +177,52 @@ export default class SelectLocation extends React.Component<IProps, IState> { {this.renderHeaderSubtitle()} </StyledSettingsHeader> - {this.props.providers.length > 0 && ( - <StyledProviderCountRow> + {showFilters && ( + <StyledFilterRow> {messages.pgettext('select-location-view', 'Filtered:')} - <StyledProvidersCount> - {sprintf( - messages.pgettext( - 'select-location-view', - 'Providers: %(numberOfProviders)d', - ), - { - numberOfProviders: this.props.providers.length, - }, - )} - <StyledClearProvidersButton - aria-label={messages.gettext('Clear')} - onClick={this.props.onClearProviders}> - <ImageView - height={16} - width={16} - source="icon-close" - tintColor={colors.white60} - tintHoverColor={colors.white80} - /> - </StyledClearProvidersButton> - </StyledProvidersCount> - </StyledProviderCountRow> + + {showOwnershipFilter && ( + <StyledFilter> + {this.ownershipFilterLabel()} + <StyledClearFilterButton + aria-label={messages.gettext('Clear')} + onClick={this.props.onClearOwnership}> + <ImageView + height={16} + width={16} + source="icon-close" + tintColor={colors.white60} + tintHoverColor={colors.white80} + /> + </StyledClearFilterButton> + </StyledFilter> + )} + + {showProvidersFilter && ( + <StyledFilter> + {sprintf( + messages.pgettext( + 'select-location-view', + 'Providers: %(numberOfProviders)d', + ), + { + numberOfProviders: this.props.providers.length, + }, + )} + <StyledClearFilterButton + aria-label={messages.gettext('Clear')} + onClick={this.props.onClearProviders}> + <ImageView + height={16} + width={16} + source="icon-close" + tintColor={colors.white60} + tintHoverColor={colors.white80} + /> + </StyledClearFilterButton> + </StyledFilter> + )} + </StyledFilterRow> )} {this.props.allowEntrySelection && ( <StyledScopeBar @@ -228,6 +258,17 @@ export default class SelectLocation extends React.Component<IProps, IState> { } } + private ownershipFilterLabel(): string { + switch (this.props.ownership) { + case Ownership.mullvadOwned: + return messages.pgettext('filter-view', 'Owned'); + case Ownership.rented: + return messages.pgettext('filter-view', 'Rented'); + default: + throw new Error('Only owned and rented should make label visible'); + } + } + private getLocationListRef(prevProps: IProps, prevState: IState) { if (prevState.locationScope === LocationScope.exit) { return this.exitLocationList.current; diff --git a/gui/src/renderer/components/SelectLocationStyles.tsx b/gui/src/renderer/components/SelectLocationStyles.tsx index ac7f684ff8..15211389f6 100644 --- a/gui/src/renderer/components/SelectLocationStyles.tsx +++ b/gui/src/renderer/components/SelectLocationStyles.tsx @@ -43,14 +43,14 @@ export const StyledSettingsHeader = styled(SettingsHeader)({ paddingBottom: '11px', }); -export const StyledProviderCountRow = styled.div({ +export const StyledFilterRow = styled.div({ ...tinyText, color: colors.white, marginLeft: '6px', marginBottom: '8px', }); -export const StyledProvidersCount = styled.div({ +export const StyledFilter = styled.div({ ...tinyText, display: 'inline-flex', alignItems: 'center', @@ -61,7 +61,7 @@ export const StyledProvidersCount = styled.div({ color: colors.white, }); -export const StyledClearProvidersButton = styled.div({ +export const StyledClearFilterButton = styled.div({ display: 'inline-block', borderWidth: 0, padding: 0, diff --git a/gui/src/renderer/containers/SelectLocationPage.tsx b/gui/src/renderer/containers/SelectLocationPage.tsx index f26e805d83..8fa036f245 100644 --- a/gui/src/renderer/containers/SelectLocationPage.tsx +++ b/gui/src/renderer/containers/SelectLocationPage.tsx @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import BridgeSettingsBuilder from '../../shared/bridge-settings-builder'; -import { LiftedConstraint, RelayLocation } from '../../shared/daemon-rpc-types'; +import { LiftedConstraint, Ownership, RelayLocation } from '../../shared/daemon-rpc-types'; import log from '../../shared/logging'; import RelaySettingsBuilder from '../../shared/relay-settings-builder'; import SelectLocation from '../components/SelectLocation'; @@ -44,6 +44,7 @@ const mapStateToProps = (state: IReduxState, props: IHistoryProps & IAppContext) ((tunnelProtocol === 'any' || tunnelProtocol === 'wireguard') && multihopEnabled); const providers = 'normal' in relaySettings ? relaySettings.normal.providers : []; + const ownership = 'normal' in relaySettings ? relaySettings.normal.ownership : Ownership.any; return { locale: state.userInterface.locale, @@ -55,6 +56,7 @@ const mapStateToProps = (state: IReduxState, props: IHistoryProps & IAppContext) allowEntrySelection, tunnelProtocol, providers, + ownership, onSelectEntryLocation: async (entryLocation: RelayLocation) => { // dismiss the view first @@ -118,6 +120,9 @@ const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAp onClearProviders: async () => { await props.app.updateRelaySettings({ normal: { providers: [] } }); }, + onClearOwnership: async () => { + await props.app.updateRelaySettings({ normal: { ownership: Ownership.any } }); + }, }; }; |
