summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-09-17 10:18:52 +0200
committerAndrej Mihajlov <and@mullvad.net>2019-09-17 10:18:52 +0200
commite3596cc4f8e8b3d37e780ec7c23b3cffe375fc7b (patch)
tree11fa5bd3920270ec0f390baaf900b409700f00d6
parent34d71197d52d8050a05d4cc715568409a06c888c (diff)
parente901869aee45d171e189bb0cae3af478cb325a4c (diff)
downloadmullvadvpn-e3596cc4f8e8b3d37e780ec7c23b3cffe375fc7b.tar.xz
mullvadvpn-e3596cc4f8e8b3d37e780ec7c23b3cffe375fc7b.zip
Merge branch 'select-location-ux'
-rw-r--r--gui/src/renderer/components/Account.tsx12
-rw-r--r--gui/src/renderer/components/AdvancedSettings.tsx19
-rw-r--r--gui/src/renderer/components/CustomScrollbars.tsx9
-rw-r--r--gui/src/renderer/components/NavigationBar.tsx178
-rw-r--r--gui/src/renderer/components/Preferences.tsx19
-rw-r--r--gui/src/renderer/components/SelectLocation.tsx125
-rw-r--r--gui/src/renderer/components/SelectLocationStyles.tsx16
-rw-r--r--gui/src/renderer/components/Settings.tsx13
-rw-r--r--gui/src/renderer/components/SettingsHeader.tsx33
-rw-r--r--gui/src/renderer/components/Support.tsx12
-rw-r--r--gui/src/renderer/components/WireguardKeys.tsx12
11 files changed, 184 insertions, 264 deletions
diff --git a/gui/src/renderer/components/Account.tsx b/gui/src/renderer/components/Account.tsx
index efe8ff2d13..fb4eb6bf35 100644
--- a/gui/src/renderer/components/Account.tsx
+++ b/gui/src/renderer/components/Account.tsx
@@ -6,7 +6,7 @@ import styles from './AccountStyles';
import * as AppButton from './AppButton';
import ClipboardLabel from './ClipboardLabel';
import { Container, Layout } from './Layout';
-import { BackBarItem, NavigationBar } from './NavigationBar';
+import { BackBarItem, NavigationBar, NavigationItems } from './NavigationBar';
import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import { AccountToken } from '../../shared/daemon-rpc-types';
@@ -28,10 +28,12 @@ export default class Account extends Component<IProps> {
<Container>
<View style={styles.account}>
<NavigationBar>
- <BackBarItem action={this.props.onClose}>
- {// TRANSLATORS: Back button in navigation bar
- messages.pgettext('account-nav', 'Settings')}
- </BackBarItem>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {// TRANSLATORS: Back button in navigation bar
+ messages.pgettext('account-nav', 'Settings')}
+ </BackBarItem>
+ </NavigationItems>
</NavigationBar>
<View style={styles.account__container}>
diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx
index 6abf4c4958..c9a985789b 100644
--- a/gui/src/renderer/components/AdvancedSettings.tsx
+++ b/gui/src/renderer/components/AdvancedSettings.tsx
@@ -11,6 +11,7 @@ import {
BackBarItem,
NavigationBar,
NavigationContainer,
+ NavigationItems,
NavigationScrollbars,
TitleBarItem,
} from './NavigationBar';
@@ -162,14 +163,16 @@ export default class AdvancedSettings extends Component<IProps, IState> {
<View style={styles.advanced_settings}>
<NavigationContainer>
<NavigationBar>
- <BackBarItem action={this.props.onClose}>
- {// TRANSLATORS: Back button in navigation bar
- messages.pgettext('advanced-settings-nav', 'Settings')}
- </BackBarItem>
- <TitleBarItem>
- {// TRANSLATORS: Title label in navigation bar
- messages.pgettext('advanced-settings-nav', 'Advanced')}
- </TitleBarItem>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {// TRANSLATORS: Back button in navigation bar
+ messages.pgettext('advanced-settings-nav', 'Settings')}
+ </BackBarItem>
+ <TitleBarItem>
+ {// TRANSLATORS: Title label in navigation bar
+ messages.pgettext('advanced-settings-nav', 'Advanced')}
+ </TitleBarItem>
+ </NavigationItems>
</NavigationBar>
<View style={styles.advanced_settings__container}>
diff --git a/gui/src/renderer/components/CustomScrollbars.tsx b/gui/src/renderer/components/CustomScrollbars.tsx
index 8928e9891b..fc91d7d239 100644
--- a/gui/src/renderer/components/CustomScrollbars.tsx
+++ b/gui/src/renderer/components/CustomScrollbars.tsx
@@ -86,6 +86,15 @@ export default class CustomScrollbars extends React.Component<IProps, IState> {
}
}
+ public getScrollPosition(): [number, number] {
+ const scroll = this.scrollableRef.current;
+ if (scroll) {
+ return [scroll.scrollLeft, scroll.scrollTop];
+ } else {
+ return [0, 0];
+ }
+ }
+
public componentDidMount() {
this.updateScrollbarsHelper({
position: true,
diff --git a/gui/src/renderer/components/NavigationBar.tsx b/gui/src/renderer/components/NavigationBar.tsx
index dd36c08850..cba9df0786 100644
--- a/gui/src/renderer/components/NavigationBar.tsx
+++ b/gui/src/renderer/components/NavigationBar.tsx
@@ -1,5 +1,4 @@
import * as React from 'react';
-import * as ReactDOM from 'react-dom';
import { Animated, Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp';
import { colors } from '../../config.json';
import CustomScrollbars, { IScrollEvent } from './CustomScrollbars';
@@ -12,9 +11,9 @@ const styles = {
paddingHorizontal: 12,
paddingBottom: 12,
}),
- content: Styles.createViewStyle({
+ wrapper: Styles.createViewStyle({
flex: 1,
- flexDirection: 'row',
+ flexDirection: 'column',
}),
separator: Styles.createViewStyle({
backgroundColor: 'rgba(0, 0, 0, 0.2)',
@@ -34,6 +33,10 @@ const styles = {
paddingTop: 12,
}),
},
+ navigationItems: Styles.createViewStyle({
+ flex: 1,
+ flexDirection: 'row',
+ }),
navigationBarTitle: {
container: Styles.createViewStyle({
flex: 1,
@@ -100,7 +103,7 @@ const styles = {
paddingVertical: 4,
}),
selected: Styles.createButtonStyle({
- backgroundColor: colors.blue,
+ backgroundColor: colors.green,
}),
hover: Styles.createButtonStyle({
backgroundColor: colors.blue40,
@@ -113,13 +116,6 @@ const styles = {
}),
},
},
- stickyContentHolder: Styles.createViewStyle({
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- backgroundColor: colors.darkBlue,
- }),
};
interface INavigationScrollContextValue {
@@ -178,15 +174,8 @@ export class NavigationContainer extends Component {
}
private updateBarAppearance(event: IScrollEvent) {
- // detect if any of child elements provide a sticky context
- // in that case the navigation bar does not draw the separator line
- // since the sticky content is expected to include it.
- const hasSticky = React.Children.toArray(this.props.children).some((child) => {
- return React.isValidElement(child) && child.type === StickyContentContainer;
- });
-
// that's where SettingsHeader.HeaderTitle intersects the navigation bar
- const showsBarSeparator = event.scrollTop > 11 && !hasSticky;
+ const showsBarSeparator = event.scrollTop > 11;
// that's when SettingsHeader.HeaderTitle goes behind the navigation bar
const showsBarTitle = event.scrollTop > 20;
@@ -344,87 +333,6 @@ class PrivateBarItemAnimationContainer extends Component<IPrivateBarItemAnimatio
}
}
-interface IStickyContentContext {
- container: HTMLDivElement | null;
- holder: React.Ref<View>;
- isSticky: boolean;
-}
-
-const StickyContentContext = React.createContext<IStickyContentContext>({
- container: null,
- holder: React.createRef<View>(),
- isSticky: false,
-});
-
-export class StickyContentContainer extends Component<{
- style: Types.StyleRuleSet<Types.ViewStyle>;
-}> {
- public static contextType = NavigationScrollContext;
- public context!: React.ContextType<typeof NavigationScrollContext>;
-
- public state = {
- container: null,
- holder: React.createRef<View>(),
- isSticky: false,
- };
-
- public componentDidMount() {
- if (this.context.navigationContainer) {
- this.context.navigationContainer.addScrollEventListener(this.onScroll);
- }
- }
-
- public componentWillUnmount() {
- if (this.context.navigationContainer) {
- this.context.navigationContainer.removeScrollEventListener(this.onScroll);
- }
- }
-
- public render() {
- return (
- <div
- ref={this.onRef}
- style={{
- position: 'relative',
- display: 'flex',
- flexDirection: 'column',
- overflow: 'hidden',
- }}>
- <View style={this.props.style}>
- <StickyContentContext.Provider value={this.state}>
- {this.props.children}
- </StickyContentContext.Provider>
- </View>
- </div>
- );
- }
-
- private onScroll = async (_scrollEvent: IScrollEvent) => {
- const holder = this.state.holder.current;
-
- if (holder) {
- let layout: Types.LayoutInfo;
-
- try {
- layout = await UserInterface.measureLayoutRelativeToAncestor(holder, this);
- } catch {
- // TODO: handle error
- return;
- }
-
- const isSticky = layout.y <= 0;
-
- if (this.state.isSticky !== isSticky) {
- this.setState({ isSticky });
- }
- }
- };
-
- private onRef = (ref: HTMLDivElement | null) => {
- this.setState({ container: ref });
- };
-}
-
interface IScopeBarProps {
defaultSelectedIndex: number;
onChange?: (selectedIndex: number) => void;
@@ -493,67 +401,6 @@ export class ScopeBar extends Component<IScopeBarProps, IScopeBarState> {
}
}
-interface IStickyContentHolderProps {
- style?: Types.ViewStyleRuleSet;
-}
-
-interface IStickyContentHolderState {
- contentHeight: number;
-}
-
-export class StickyContentHolder extends Component<
- IStickyContentHolderProps,
- IStickyContentHolderState
-> {
- public state = {
- contentHeight: 0,
- };
-
- public render() {
- return (
- <StickyContentContext.Consumer>
- {(stickyContext) => {
- const contentStyle = stickyContext.isSticky ? styles.stickyContentHolder : undefined;
- const contentPlaceholderStyle = stickyContext.isSticky
- ? Styles.createViewStyle(
- {
- height: this.state.contentHeight,
- },
- false,
- )
- : undefined;
-
- const children = (
- <View style={contentStyle} onLayout={this.onLayout}>
- {this.props.children}
- {stickyContext.isSticky ? <NavigationBarSeparator /> : undefined}
- </View>
- );
-
- return (
- <View style={this.props.style} ref={stickyContext.holder}>
- {stickyContext.isSticky && stickyContext.container ? (
- <React.Fragment>
- <View style={contentPlaceholderStyle} />
- {ReactDOM.createPortal(children, stickyContext.container)}
- </React.Fragment>
- ) : (
- children
- )}
- </View>
- );
- }}
- </StickyContentContext.Consumer>
- );
- }
-
- private onLayout = async (layout: Types.LayoutInfo) => {
- if (this.state.contentHeight !== layout.height) {
- this.setState({ contentHeight: layout.height });
- }
- };
-}
-
interface IScopeBarItemProps {
children?: React.ReactText;
selected?: boolean;
@@ -598,6 +445,7 @@ function NavigationBarSeparator() {
interface INavigationBarProps {
children?: React.ReactNode;
+ alwaysDisplayBarTitle?: boolean;
}
export const NavigationBar = React.forwardRef(function NavigationBarT(
@@ -609,7 +457,7 @@ export const NavigationBar = React.forwardRef(function NavigationBarT(
{(context) => (
<PrivateNavigationBar
ref={ref}
- showsBarTitle={context.showsBarTitle}
+ showsBarTitle={props.alwaysDisplayBarTitle || context.showsBarTitle}
showsBarSeparator={context.showsBarSeparator}>
{props.children}
</PrivateNavigationBar>
@@ -635,6 +483,10 @@ const PrivateTitleBarItemContext = React.createContext({
measuringTextRef: React.createRef<Text>(),
});
+export function NavigationItems(props: { children: React.ReactNode }) {
+ return <View style={styles.navigationItems}>{props.children}</View>;
+}
+
class PrivateNavigationBar extends Component<
IPrivateNavigationBarProps,
IPrivateNavigationBarState
@@ -661,7 +513,7 @@ class PrivateNavigationBar extends Component<
public render() {
return (
<View style={[styles.navigationBar.default, this.getPlatformStyle()]}>
- <View style={styles.navigationBar.content} onLayout={this.onLayout}>
+ <View style={styles.navigationBar.wrapper} onLayout={this.onLayout}>
<PrivateTitleBarItemContext.Provider
value={{
titleAdjustment: this.state.titleAdjustment,
diff --git a/gui/src/renderer/components/Preferences.tsx b/gui/src/renderer/components/Preferences.tsx
index 2c6df58a99..b295c68308 100644
--- a/gui/src/renderer/components/Preferences.tsx
+++ b/gui/src/renderer/components/Preferences.tsx
@@ -7,6 +7,7 @@ import {
BackBarItem,
NavigationBar,
NavigationContainer,
+ NavigationItems,
NavigationScrollbars,
TitleBarItem,
} from './NavigationBar';
@@ -39,14 +40,16 @@ export default class Preferences extends Component<IProps> {
<View style={styles.preferences}>
<NavigationContainer>
<NavigationBar>
- <BackBarItem action={this.props.onClose}>
- {// TRANSLATORS: Back button in navigation bar
- messages.pgettext('preferences-nav', 'Settings')}
- </BackBarItem>
- <TitleBarItem>
- {// TRANSLATORS: Title label in navigation bar
- messages.pgettext('preferences-nav', 'Preferences')}
- </TitleBarItem>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {// TRANSLATORS: Back button in navigation bar
+ messages.pgettext('preferences-nav', 'Settings')}
+ </BackBarItem>
+ <TitleBarItem>
+ {// TRANSLATORS: Title label in navigation bar
+ messages.pgettext('preferences-nav', 'Preferences')}
+ </TitleBarItem>
+ </NavigationItems>
</NavigationBar>
<View style={styles.preferences__container}>
diff --git a/gui/src/renderer/components/SelectLocation.tsx b/gui/src/renderer/components/SelectLocation.tsx
index 7a1340c44f..0018446291 100644
--- a/gui/src/renderer/components/SelectLocation.tsx
+++ b/gui/src/renderer/components/SelectLocation.tsx
@@ -14,15 +14,14 @@ import {
CloseBarItem,
NavigationBar,
NavigationContainer,
+ NavigationItems,
NavigationScrollbars,
ScopeBar,
ScopeBarItem,
- StickyContentContainer,
- StickyContentHolder,
TitleBarItem,
} from './NavigationBar';
import styles from './SelectLocationStyles';
-import SettingsHeader, { HeaderSubTitle, HeaderTitle } from './SettingsHeader';
+import { HeaderSubTitle } from './SettingsHeader';
interface IProps {
locationScope: LocationScope;
@@ -43,13 +42,29 @@ export default class SelectLocation extends Component<IProps> {
private exitLocationList = React.createRef<LocationList>();
private bridgeLocationList = React.createRef<LocationList>();
+ private scrollPositionByScope: { [index: number]: [number, number] } = {};
+
public componentDidMount() {
this.scrollToSelectedCell();
}
- public componentDidUpdate(prevProps: IProps) {
+ public componentDidUpdate(prevProps: IProps, _prevState: {}, snapshot?: [number, number]) {
if (this.props.locationScope !== prevProps.locationScope) {
- this.scrollToSelectedCell();
+ this.restoreScrollPosition(this.props.locationScope);
+
+ if (snapshot) {
+ this.saveScrollPosition(prevProps.locationScope, snapshot);
+ }
+ }
+ }
+
+ public getSnapshotBeforeUpdate(_prevProps: IProps) {
+ const scrollView = this.scrollView.current;
+
+ if (scrollView) {
+ return scrollView.getScrollPosition();
+ } else {
+ return undefined;
}
}
@@ -59,51 +74,44 @@ export default class SelectLocation extends Component<IProps> {
<Container>
<View style={styles.select_location}>
<NavigationContainer>
- <NavigationBar>
- <CloseBarItem action={this.props.onClose} />
- <TitleBarItem>
- {// TRANSLATORS: Title label in navigation bar
- messages.pgettext('select-location-nav', 'Select location')}
- </TitleBarItem>
+ <NavigationBar alwaysDisplayBarTitle={true}>
+ <NavigationItems>
+ <CloseBarItem action={this.props.onClose} />
+ <TitleBarItem>
+ {// TRANSLATORS: Title label in navigation bar
+ messages.pgettext('select-location-nav', 'Select location')}
+ </TitleBarItem>
+ </NavigationItems>
+ <View style={styles.navigationBarAttachment}>
+ <HeaderSubTitle>
+ {this.props.allowBridgeSelection
+ ? messages.pgettext(
+ 'select-location-view',
+ 'While connected, your traffic will be routed through two secure locations, the entry point (a bridge server) and the exit point (a VPN server).',
+ )
+ : messages.pgettext(
+ 'select-location-view',
+ 'While connected, your real location is masked with a private and secure location in the selected region.',
+ )}
+ </HeaderSubTitle>
+ {this.props.allowBridgeSelection && (
+ <ScopeBar
+ style={styles.scopeBar}
+ defaultSelectedIndex={this.props.locationScope}
+ onChange={this.props.onChangeLocationScope}>
+ <ScopeBarItem>
+ {messages.pgettext('select-location-nav', 'Entry')}
+ </ScopeBarItem>
+ <ScopeBarItem>
+ {messages.pgettext('select-location-nav', 'Exit')}
+ </ScopeBarItem>
+ </ScopeBar>
+ )}
+ </View>
</NavigationBar>
- <StickyContentContainer style={styles.container}>
+ <View style={styles.container}>
<NavigationScrollbars ref={this.scrollView}>
<View style={styles.content}>
- <SettingsHeader
- style={this.props.allowBridgeSelection ? styles.headerWithScope : undefined}>
- <HeaderTitle>
- {messages.pgettext('select-location-view', 'Select location')}
- </HeaderTitle>
- <HeaderSubTitle>
- {this.props.locationScope === LocationScope.relay
- ? messages.pgettext(
- 'select-location-view',
- 'While connected, your real location is masked with a private and secure location in the selected region',
- )
- : messages.pgettext(
- 'select-location-view',
- 'While connected, your traffic will be routed through two secure locations, the entry point (a bridge server) and the exit point (a VPN server)',
- )}
- </HeaderSubTitle>
- </SettingsHeader>
-
- {this.props.allowBridgeSelection && (
- <StickyContentHolder style={styles.stickyHolder}>
- <View style={styles.stickyContent}>
- <ScopeBar
- defaultSelectedIndex={this.props.locationScope}
- onChange={this.props.onChangeLocationScope}>
- <ScopeBarItem>
- {messages.pgettext('select-location-nav', 'Entry')}
- </ScopeBarItem>
- <ScopeBarItem>
- {messages.pgettext('select-location-nav', 'Exit')}
- </ScopeBarItem>
- </ScopeBar>
- </View>
- </StickyContentHolder>
- )}
-
{this.props.locationScope === LocationScope.relay ? (
<LocationList
key={'exit-locations'}
@@ -135,7 +143,7 @@ export default class SelectLocation extends Component<IProps> {
)}
</View>
</NavigationScrollbars>
- </StickyContentContainer>
+ </View>
</NavigationContainer>
</View>
</Container>
@@ -143,6 +151,27 @@ export default class SelectLocation extends Component<IProps> {
);
}
+ public saveScrollPosition(scope: LocationScope, position: [number, number]) {
+ this.scrollPositionByScope[scope] = position;
+ }
+
+ public restoreScrollPosition(scope: LocationScope) {
+ const prevScrollPos = this.scrollPositionByScope[scope];
+
+ if (prevScrollPos) {
+ this.scrollToPosition(...prevScrollPos);
+ } else {
+ this.scrollToSelectedCell();
+ }
+ }
+
+ private scrollToPosition(x: number, y: number) {
+ const scrollView = this.scrollView.current;
+ if (scrollView) {
+ scrollView.scrollTo(x, y);
+ }
+ }
+
private scrollToSelectedCell() {
const ref =
this.props.locationScope === LocationScope.relay
diff --git a/gui/src/renderer/components/SelectLocationStyles.tsx b/gui/src/renderer/components/SelectLocationStyles.tsx
index bfda9c1055..ad6c116436 100644
--- a/gui/src/renderer/components/SelectLocationStyles.tsx
+++ b/gui/src/renderer/components/SelectLocationStyles.tsx
@@ -13,18 +13,12 @@ export default {
content: Styles.createViewStyle({
overflow: 'visible',
}),
- headerWithScope: Styles.createViewStyle({
- paddingBottom: 4,
+ navigationBarAttachment: Styles.createTextStyle({
+ marginTop: 8,
+ paddingHorizontal: 4,
}),
- stickyHolder: Styles.createViewStyle({
- marginTop: 4,
- }),
- stickyContent: Styles.createViewStyle({
- paddingHorizontal: 12,
- paddingBottom: 8,
-
- // NavigationBar already adds some spacing
- paddingTop: 0,
+ scopeBar: Styles.createViewStyle({
+ marginTop: 8,
}),
selectedCell: Styles.createViewStyle({
backgroundColor: colors.green,
diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx
index bf0e812a89..6c04d9a8e5 100644
--- a/gui/src/renderer/components/Settings.tsx
+++ b/gui/src/renderer/components/Settings.tsx
@@ -11,6 +11,7 @@ import {
CloseBarItem,
NavigationBar,
NavigationContainer,
+ NavigationItems,
NavigationScrollbars,
TitleBarItem,
} from './NavigationBar';
@@ -44,11 +45,13 @@ export default class Settings extends Component<IProps> {
<View style={styles.settings}>
<NavigationContainer>
<NavigationBar>
- <CloseBarItem action={this.props.onClose} />
- <TitleBarItem>
- {// TRANSLATORS: Title label in navigation bar
- messages.pgettext('settings-view-nav', 'Settings')}
- </TitleBarItem>
+ <NavigationItems>
+ <CloseBarItem action={this.props.onClose} />
+ <TitleBarItem>
+ {// TRANSLATORS: Title label in navigation bar
+ messages.pgettext('settings-view-nav', 'Settings')}
+ </TitleBarItem>
+ </NavigationItems>
</NavigationBar>
<View style={styles.settings__container}>
diff --git a/gui/src/renderer/components/SettingsHeader.tsx b/gui/src/renderer/components/SettingsHeader.tsx
index 57be8653c4..9ddfa171c2 100644
--- a/gui/src/renderer/components/SettingsHeader.tsx
+++ b/gui/src/renderer/components/SettingsHeader.tsx
@@ -20,7 +20,6 @@ const styles = {
color: colors.white,
}),
subtitle: Styles.createTextStyle({
- marginTop: 8,
fontFamily: 'Open Sans',
fontSize: 13,
fontWeight: '600',
@@ -29,26 +28,48 @@ const styles = {
lineHeight: 20,
letterSpacing: -0.2,
}),
+ spacer: Styles.createViewStyle({
+ height: 8,
+ }),
};
interface ISettingsHeaderProps {
style?: Types.ViewStyleRuleSet;
}
+interface ISettingsTextProps {
+ style?: Types.TextStyleRuleSet;
+}
+
export default class SettingsHeader extends Component<ISettingsHeaderProps> {
public render() {
- return <View style={[styles.header.default, this.props.style]}>{this.props.children}</View>;
+ return (
+ <View style={[styles.header.default, this.props.style]}>
+ {React.Children.map(this.props.children, (child, index) => {
+ if (React.isValidElement(child) && index > 0) {
+ return (
+ <React.Fragment>
+ <View style={styles.spacer} />
+ {child}
+ </React.Fragment>
+ );
+ } else {
+ return child;
+ }
+ })}
+ </View>
+ );
}
}
-export class HeaderTitle extends Component {
+export class HeaderTitle extends Component<ISettingsTextProps> {
public render() {
- return <Text style={[styles.title]}>{this.props.children}</Text>;
+ return <Text style={[styles.title, this.props.style]}>{this.props.children}</Text>;
}
}
-export class HeaderSubTitle extends Component {
+export class HeaderSubTitle extends Component<ISettingsTextProps> {
public render() {
- return <Text style={[styles.subtitle]}>{this.props.children}</Text>;
+ return <Text style={[styles.subtitle, this.props.style]}>{this.props.children}</Text>;
}
}
diff --git a/gui/src/renderer/components/Support.tsx b/gui/src/renderer/components/Support.tsx
index c3b7d42993..02f374737d 100644
--- a/gui/src/renderer/components/Support.tsx
+++ b/gui/src/renderer/components/Support.tsx
@@ -5,7 +5,7 @@ import * as AppButton from './AppButton';
import ImageView from './ImageView';
import { Container, Layout } from './Layout';
import { ModalAlert, ModalContainer, ModalContent } from './Modal';
-import { BackBarItem, NavigationBar } from './NavigationBar';
+import { BackBarItem, NavigationBar, NavigationItems } from './NavigationBar';
import SettingsHeader, { HeaderSubTitle, HeaderTitle } from './SettingsHeader';
import styles from './SupportStyles';
@@ -139,10 +139,12 @@ export default class Support extends Component<ISupportProps, ISupportState> {
<ModalContent>
<View style={styles.support}>
<NavigationBar>
- <BackBarItem action={this.props.onClose}>
- {// TRANSLATORS: Back button in navigation bar
- messages.pgettext('support-nav', 'Settings')}
- </BackBarItem>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {// TRANSLATORS: Back button in navigation bar
+ messages.pgettext('support-nav', 'Settings')}
+ </BackBarItem>
+ </NavigationItems>
</NavigationBar>
<View style={styles.support__container}>
{header}
diff --git a/gui/src/renderer/components/WireguardKeys.tsx b/gui/src/renderer/components/WireguardKeys.tsx
index 9ea386ec91..053b8567c7 100644
--- a/gui/src/renderer/components/WireguardKeys.tsx
+++ b/gui/src/renderer/components/WireguardKeys.tsx
@@ -8,7 +8,7 @@ import { IWgKey, WgKeyState } from '../redux/settings/reducers';
import * as AppButton from './AppButton';
import ImageView from './ImageView';
import { Container, Layout } from './Layout';
-import { BackBarItem, NavigationBar, NavigationContainer } from './NavigationBar';
+import { BackBarItem, NavigationBar, NavigationContainer, NavigationItems } from './NavigationBar';
import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import styles from './WireguardKeysStyles';
@@ -32,10 +32,12 @@ export default class WireguardKeys extends Component<IProps> {
<View style={styles.wgkeys}>
<NavigationContainer>
<NavigationBar>
- <BackBarItem action={this.props.onClose}>
- {// TRANSLATORS: Back button in navigation bar
- messages.pgettext('wireguard-keys-nav', 'Advanced')}
- </BackBarItem>
+ <NavigationItems>
+ <BackBarItem action={this.props.onClose}>
+ {// TRANSLATORS: Back button in navigation bar
+ messages.pgettext('wireguard-keys-nav', 'Advanced')}
+ </BackBarItem>
+ </NavigationItems>
</NavigationBar>
</NavigationContainer>