diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2020-05-27 17:47:08 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2020-05-27 17:47:08 +0200 |
| commit | 3a801671a2dab9a6359ca0cc0b581193fb3649b7 (patch) | |
| tree | ef576608e6a643630aa3bc3762523e84c36452f6 /gui/src | |
| parent | e7824eb7d2c8368f6aefa157155e9e5a3beb7a76 (diff) | |
| parent | a03dc3d0a0dc22b234c49a61590173aa8a401c9d (diff) | |
| download | mullvadvpn-3a801671a2dab9a6359ca0cc0b581193fb3649b7.tar.xz mullvadvpn-3a801671a2dab9a6359ca0cc0b581193fb3649b7.zip | |
Merge branch 'convert-app-button-to-styled-components'
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/components/Account.tsx | 15 | ||||
| -rw-r--r-- | gui/src/renderer/components/AccountStyles.tsx | 12 | ||||
| -rw-r--r-- | gui/src/renderer/components/AdvancedSettings.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/components/AppButton.tsx | 208 | ||||
| -rw-r--r-- | gui/src/renderer/components/AppButtonStyles.tsx | 92 | ||||
| -rw-r--r-- | gui/src/renderer/components/ExpiredAccountErrorView.tsx | 18 | ||||
| -rw-r--r-- | gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx | 11 | ||||
| -rw-r--r-- | gui/src/renderer/components/Login.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/MultiButton.tsx | 71 | ||||
| -rw-r--r-- | gui/src/renderer/components/NotificationBanner.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/RedeemVoucher.tsx | 11 | ||||
| -rw-r--r-- | gui/src/renderer/components/Settings.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/Support.tsx | 27 | ||||
| -rw-r--r-- | gui/src/renderer/components/SupportStyles.tsx | 12 | ||||
| -rw-r--r-- | gui/src/renderer/components/TunnelControl.tsx | 40 | ||||
| -rw-r--r-- | gui/src/renderer/components/WireguardKeys.tsx | 6 |
16 files changed, 234 insertions, 299 deletions
diff --git a/gui/src/renderer/components/Account.tsx b/gui/src/renderer/components/Account.tsx index 7863040f83..352ed1dad3 100644 --- a/gui/src/renderer/components/Account.tsx +++ b/gui/src/renderer/components/Account.tsx @@ -1,21 +1,22 @@ import * as React from 'react'; import AccountExpiry from '../../shared/account-expiry'; import { messages } from '../../shared/gettext'; -import styles, { +import { AccountContainer, AccountFooter, AccountOutOfTime, AccountRow, AccountRowLabel, AccountRowValue, + StyledBuyCreditButton, StyledContainer, + StyledRedeemVoucherButton, } from './AccountStyles'; import AccountTokenLabel from './AccountTokenLabel'; import * as AppButton from './AppButton'; import { Layout } from './Layout'; import { ModalContainer } from './Modal'; import { BackBarItem, NavigationBar, NavigationItems } from './NavigationBar'; -import { RedeemVoucherButton } from './RedeemVoucher'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; import { AccountToken } from '../../shared/daemon-rpc-types'; @@ -73,16 +74,16 @@ export default class Account extends React.Component<IProps> { <AccountFooter> <AppButton.BlockingButton disabled={this.props.isOffline} - onPress={this.props.onBuyMore}> - <AppButton.GreenButton style={styles.button}> + onClick={this.props.onBuyMore}> + <StyledBuyCreditButton> <AppButton.Label>{messages.gettext('Buy more credit')}</AppButton.Label> <AppButton.Icon source="icon-extLink" height={16} width={16} /> - </AppButton.GreenButton> + </StyledBuyCreditButton> </AppButton.BlockingButton> - <RedeemVoucherButton style={styles.button} /> + <StyledRedeemVoucherButton /> - <AppButton.RedButton onPress={this.props.onLogout}> + <AppButton.RedButton onClick={this.props.onLogout}> {messages.pgettext('account-view', 'Log out')} </AppButton.RedButton> </AccountFooter> diff --git a/gui/src/renderer/components/AccountStyles.tsx b/gui/src/renderer/components/AccountStyles.tsx index 970309e4f8..f66485e3d6 100644 --- a/gui/src/renderer/components/AccountStyles.tsx +++ b/gui/src/renderer/components/AccountStyles.tsx @@ -1,7 +1,8 @@ -import { Styles } from 'reactxp'; import styled from 'styled-components'; import { colors } from '../../config.json'; +import * as AppButton from './AppButton'; import { Container } from './Layout'; +import { RedeemVoucherButton } from './RedeemVoucher'; export const StyledContainer = styled(Container)({ backgroundColor: colors.darkBlue, @@ -51,8 +52,9 @@ export const AccountFooter = styled.div({ padding: '0 24px', }); -export default { - button: Styles.createViewStyle({ - marginBottom: 24, - }), +const buttonStyle = { + marginBottom: 24, }; + +export const StyledRedeemVoucherButton = styled(RedeemVoucherButton)(buttonStyle); +export const StyledBuyCreditButton = styled(AppButton.GreenButton)(buttonStyle); diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx index 4fa10adde9..0645f03ff7 100644 --- a/gui/src/renderer/components/AdvancedSettings.tsx +++ b/gui/src/renderer/components/AdvancedSettings.tsx @@ -402,10 +402,10 @@ export default class AdvancedSettings extends Component<IProps, IState> { <ModalAlert type={ModalAlertType.Info} buttons={[ - <AppButton.RedButton key="confirm" onPress={this.confirmEnableBlockWhenDisconnected}> + <AppButton.RedButton key="confirm" onClick={this.confirmEnableBlockWhenDisconnected}> {messages.pgettext('advanced-settings-view', 'Enable anyway')} </AppButton.RedButton>, - <AppButton.BlueButton key="back" onPress={this.hideConfirmBlockWhenDisconnectedAlert}> + <AppButton.BlueButton key="back" onClick={this.hideConfirmBlockWhenDisconnectedAlert}> {messages.gettext('Back')} </AppButton.BlueButton>, ]}> diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx index e1c37c014b..c0731917d0 100644 --- a/gui/src/renderer/components/AppButton.tsx +++ b/gui/src/renderer/components/AppButton.tsx @@ -1,56 +1,31 @@ import log from 'electron-log'; -import * as React from 'react'; -import { Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp'; +import React, { useContext } from 'react'; +import styled from 'styled-components'; import { colors } from '../../config.json'; -import consumePromise from '../../shared/promise'; -import styles from './AppButtonStyles'; +import { + StyledButton, + StyledButtonContent, + StyledLabel, + StyledLabelContainer, +} from './AppButtonStyles'; import ImageView from './ImageView'; const ButtonContext = React.createContext({ textAdjustment: 0, - textRef: React.createRef<PrivateLabel>(), + textRef: React.createRef<HTMLDivElement>(), }); interface ILabelProps { children?: React.ReactText; } -interface IPrivateLabelProps { - textAdjustment: number; - children?: React.ReactText; -} - -class PrivateLabel extends Component<IPrivateLabelProps> { - public render() { - const { textAdjustment, children } = this.props; - const textAdjustmentStyle = Styles.createViewStyle( - { - paddingRight: textAdjustment > 0 ? textAdjustment : 0, - paddingLeft: textAdjustment < 0 ? Math.abs(textAdjustment) : 0, - }, - false, - ); - - return ( - <View style={[styles.labelContainer, textAdjustmentStyle]}> - <Text style={styles.label}>{children}</Text> - </View> - ); - } -} - -export class Label extends Component<ILabelProps> { - public render() { - return ( - <ButtonContext.Consumer> - {(context) => ( - <PrivateLabel ref={context.textRef} textAdjustment={context.textAdjustment}> - {this.props.children} - </PrivateLabel> - )} - </ButtonContext.Consumer> - ); - } +export function Label(props: ILabelProps) { + const { textAdjustment, textRef } = useContext(ButtonContext); + return ( + <StyledLabelContainer ref={textRef} textAdjustment={textAdjustment}> + <StyledLabel>{props.children}</StyledLabel> + </StyledLabelContainer> + ); } interface IIconProps { @@ -59,100 +34,74 @@ interface IIconProps { height?: number; } -export class Icon extends Component<IIconProps> { - public render() { - return ( - <ImageView - source={this.props.source} - width={this.props.width} - height={this.props.height} - tintColor={colors.white} - /> - ); - } +export function Icon(props: IIconProps) { + return <ImageView {...props} tintColor={colors.white} />; } -interface IProps { +export interface IProps { children?: React.ReactNode; - style?: Types.StyleRuleSetRecursive<Types.ButtonStyleRuleSet>; + className?: string; disabled?: boolean; - onPress?: () => void; + onClick?: () => void; textOffset?: number; } interface IState { - hovered: boolean; textAdjustment: number; } -class BaseButton extends Component<IProps, IState> { +class BaseButton extends React.Component<IProps, IState> { public state: IState = { - hovered: false, textAdjustment: 0, }; - private containerRef = React.createRef<View>(); - private textViewRef = React.createRef<PrivateLabel>(); + private buttonRef = React.createRef<HTMLButtonElement>(); + private textRef = React.createRef<HTMLDivElement>(); public componentDidMount() { - consumePromise(this.forceUpdateTextAdjustment()); + this.updateTextAdjustment(); } - public render() { - const { children, style, ...otherProps } = this.props; + public componentDidUpdate() { + this.updateTextAdjustment(); + } + public render() { return ( <ButtonContext.Provider value={{ textAdjustment: this.state.textAdjustment, - textRef: this.textViewRef, + textRef: this.textRef, }}> - <Button - {...otherProps} - style={[styles.common, this.backgroundStyle(), style]} - onHoverStart={this.onHoverStart} - onHoverEnd={this.onHoverEnd}> - <View style={styles.content} ref={this.containerRef} onLayout={this.onLayout}> - {React.Children.map(children, (child) => + <StyledButton + ref={this.buttonRef} + disabled={this.props.disabled} + onClick={this.props.onClick} + className={this.props.className}> + <StyledButtonContent> + {React.Children.map(this.props.children, (child) => typeof child === 'string' ? <Label>{child as string}</Label> : child, )} - </View> - </Button> + </StyledButtonContent> + </StyledButton> </ButtonContext.Provider> ); } - protected backgroundStyle = (): Types.ButtonStyleRuleSet => { - throw new Error('Implement backgroundStyle in subclasses.'); - }; - protected onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null); - protected onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null); - - private async forceUpdateTextAdjustment() { - const containerView = this.containerRef.current; - if (containerView) { - const containerLayout = await UserInterface.measureLayoutRelativeToAncestor( - containerView, - this, - ); + private updateTextAdjustment() { + const textOffset = this.props.textOffset ?? 0; - await this.updateTextAdjustment(containerLayout); - } - } - - private async updateTextAdjustment(containerLayout: Types.LayoutInfo) { - const textOffset = this.props.textOffset || 0; - const labelView = this.textViewRef.current; + const buttonRect = this.buttonRef.current?.getBoundingClientRect(); + const textRect = this.textRef.current?.getBoundingClientRect(); - if (labelView) { - // calculate the title layout frame - const labelLayout = await UserInterface.measureLayoutRelativeToAncestor(labelView, this); + if (buttonRect && textRect) { + const leftDiff = textRect.left - buttonRect.left; // calculate the remaining space at the right hand side - const trailingSpace = containerLayout.width - (labelLayout.x + labelLayout.width); + const trailingSpace = buttonRect.width - (leftDiff + textRect.width); // calculate text adjustment - const textAdjustment = labelLayout.x - trailingSpace - textOffset; + const textAdjustment = leftDiff - trailingSpace - textOffset; // re-render the view with the new text adjustment if it changed if (this.state.textAdjustment !== textAdjustment) { @@ -160,10 +109,6 @@ class BaseButton extends Component<IProps, IState> { } } } - - private onLayout = (containerLayout: Types.ViewOnLayoutEvent) => { - consumePromise(this.updateTextAdjustment(containerLayout)); - }; } interface IBlockingState { @@ -172,11 +117,11 @@ interface IBlockingState { interface IBlockingProps { children?: React.ReactNode; - onPress: () => Promise<void>; + onClick: () => Promise<void>; disabled?: boolean; } -export class BlockingButton extends Component<IBlockingProps, IBlockingState> { +export class BlockingButton extends React.Component<IBlockingProps, IBlockingState> { public state = { isBlocked: false, }; @@ -187,7 +132,7 @@ export class BlockingButton extends Component<IBlockingProps, IBlockingState> { return React.cloneElement(child as React.ReactElement, { ...child.props, disabled: this.state.isBlocked || this.props.disabled, - onPress: this.onPress, + onClick: this.onClick, }); } else { return child; @@ -195,36 +140,49 @@ export class BlockingButton extends Component<IBlockingProps, IBlockingState> { }); } - private onPress = () => { + private onClick = () => { this.setState({ isBlocked: true }, async () => { try { - await this.props.onPress(); + await this.props.onClick(); } catch (error) { - log.error(`onPress() failed - ${error}`); + log.error(`onClick() failed - ${error}`); } this.setState({ isBlocked: false }); }); }; } -export class RedButton extends BaseButton { - protected backgroundStyle = () => (this.state.hovered ? styles.redHover : styles.red); -} +export const RedButton = styled(BaseButton)({ + backgroundColor: colors.red, + ':not(:disabled):hover': { + backgroundColor: colors.red95, + }, +}); -export class GreenButton extends BaseButton { - protected backgroundStyle = () => (this.state.hovered ? styles.greenHover : styles.green); -} +export const GreenButton = styled(BaseButton)({ + backgroundColor: colors.green, + ':not(:disabled):hover': { + backgroundColor: colors.green90, + }, +}); -export class BlueButton extends BaseButton { - protected backgroundStyle = () => (this.state.hovered ? styles.blueHover : styles.blue); -} +export const BlueButton = styled(BaseButton)({ + backgroundColor: colors.blue80, + ':not(:disabled):hover': { + backgroundColor: colors.blue60, + }, +}); -export class TransparentButton extends BaseButton { - protected backgroundStyle = () => - this.state.hovered ? styles.transparentHover : styles.transparent; -} +export const TransparentButton = styled(BaseButton)({ + backgroundColor: colors.white20, + ':not(:disabled):hover': { + backgroundColor: colors.white40, + }, +}); -export class RedTransparentButton extends BaseButton { - protected backgroundStyle = () => - this.state.hovered ? styles.redTransparentHover : styles.redTransparent; -} +export const RedTransparentButton = styled(BaseButton)({ + backgroundColor: colors.red60, + ':not(:disabled):hover': { + backgroundColor: colors.red80, + }, +}); diff --git a/gui/src/renderer/components/AppButtonStyles.tsx b/gui/src/renderer/components/AppButtonStyles.tsx index e9594e3994..e8100ca82c 100644 --- a/gui/src/renderer/components/AppButtonStyles.tsx +++ b/gui/src/renderer/components/AppButtonStyles.tsx @@ -1,57 +1,39 @@ -import { Styles } from 'reactxp'; +import styled from 'styled-components'; import { colors } from '../../config.json'; -export default { - red: Styles.createButtonStyle({ - backgroundColor: colors.red, - }), - redHover: Styles.createButtonStyle({ - backgroundColor: colors.red95, - }), - green: Styles.createButtonStyle({ - backgroundColor: colors.green, - }), - greenHover: Styles.createButtonStyle({ - backgroundColor: colors.green90, - }), - blue: Styles.createButtonStyle({ - backgroundColor: colors.blue80, - }), - blueHover: Styles.createButtonStyle({ - backgroundColor: colors.blue60, - }), - transparent: Styles.createButtonStyle({ - backgroundColor: colors.white20, - }), - transparentHover: Styles.createButtonStyle({ - backgroundColor: colors.white40, - }), - redTransparent: Styles.createButtonStyle({ - backgroundColor: colors.red60, - }), - redTransparentHover: Styles.createButtonStyle({ - backgroundColor: colors.red80, - }), - common: Styles.createViewStyle({ - cursor: 'default', - borderRadius: 4, - }), - content: Styles.createViewStyle({ - flex: 1, - flexDirection: 'row', - alignItems: 'center', - padding: 9, - }), - labelContainer: Styles.createViewStyle({ - flex: 1, - }), - label: Styles.createTextStyle({ - fontFamily: 'DINPro', - fontSize: 20, - fontWeight: '900', - lineHeight: 26, - flex: 1, - color: colors.white, - textAlign: 'center', - }), -}; +export const StyledLabelContainer = styled.div((props: { textAdjustment: number }) => ({ + display: 'flex', + flex: 1, + paddingRight: `${props.textAdjustment > 0 ? props.textAdjustment : 0}px`, + paddingLeft: `${props.textAdjustment < 0 ? Math.abs(props.textAdjustment) : 0}px`, +})); + +export const StyledLabel = styled.span({ + fontFamily: 'DINPro', + fontSize: '20px', + fontWeight: 900, + lineHeight: '26px', + flex: 1, + color: colors.white, + textAlign: 'center', +}); + +export const StyledButton = styled.button({ + display: 'flex', + cursor: 'default', + borderRadius: 4, + border: 'none', + padding: 0, + ':disabled': { + opacity: 0.5, + }, +}); + +export const StyledButtonContent = styled.div({ + display: 'flex', + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + padding: 9, +}); diff --git a/gui/src/renderer/components/ExpiredAccountErrorView.tsx b/gui/src/renderer/components/ExpiredAccountErrorView.tsx index 55adb81a82..61140016ea 100644 --- a/gui/src/renderer/components/ExpiredAccountErrorView.tsx +++ b/gui/src/renderer/components/ExpiredAccountErrorView.tsx @@ -12,6 +12,8 @@ import CustomScrollbars from './CustomScrollbars'; import styles, { ModalCellContainer, StyledAccountTokenLabel, + StyledBuyCreditButton, + StyledDisconnectButton, } from './ExpiredAccountErrorViewStyles'; import ImageView from './ImageView'; import { ModalAlert, ModalAlertType, ModalMessage } from './Modal'; @@ -63,10 +65,10 @@ export default class ExpiredAccountErrorView extends Component< <View style={styles.footer}> {this.getRecoveryAction() === RecoveryAction.disconnect && ( - <AppButton.BlockingButton onPress={this.props.onDisconnect}> - <AppButton.RedButton style={styles.button}> + <AppButton.BlockingButton onClick={this.props.onDisconnect}> + <StyledDisconnectButton> {messages.pgettext('connect-view', 'Disconnect')} - </AppButton.RedButton> + </StyledDisconnectButton> </AppButton.BlockingButton> )} @@ -74,7 +76,7 @@ export default class ExpiredAccountErrorView extends Component< <AppButton.GreenButton disabled={this.getRecoveryAction() === RecoveryAction.disconnect} - onPress={this.onOpenRedeemVoucherAlert}> + onClick={this.onOpenRedeemVoucherAlert}> {messages.pgettext('connect-view', 'Redeem voucher')} </AppButton.GreenButton> </View> @@ -160,11 +162,11 @@ export default class ExpiredAccountErrorView extends Component< return ( <AppButton.BlockingButton disabled={this.getRecoveryAction() === RecoveryAction.disconnect} - onPress={this.onOpenExternalPayment}> - <AppButton.GreenButton style={styles.button}> + onClick={this.onOpenExternalPayment}> + <StyledBuyCreditButton> <AppButton.Label>{buttonText}</AppButton.Label> <AppButton.Icon source="icon-extLink" height={16} width={16} /> - </AppButton.GreenButton> + </StyledBuyCreditButton> </AppButton.BlockingButton> ); } @@ -184,7 +186,7 @@ export default class ExpiredAccountErrorView extends Component< buttons={[ <AppButton.BlueButton key="cancel" - onPress={this.onCloseBlockWhenDisconnectedInstructions}> + onClick={this.onCloseBlockWhenDisconnectedInstructions}> {messages.gettext('Close')} </AppButton.BlueButton>, ]}> diff --git a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx index 352a29db78..a8049095c3 100644 --- a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx +++ b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx @@ -2,6 +2,7 @@ import { Styles } from 'reactxp'; import styled from 'styled-components'; import { colors } from '../../config.json'; import AccountTokenLabel from './AccountTokenLabel'; +import * as AppButton from './AppButton'; import * as Cell from './Cell'; export const StyledAccountTokenLabel = styled(AccountTokenLabel)({ @@ -16,6 +17,13 @@ export const ModalCellContainer = styled(Cell.Container)({ marginTop: '16px', }); +const buttonStyle = { + marginBottom: 24, +}; + +export const StyledBuyCreditButton = styled(AppButton.GreenButton)(buttonStyle); +export const StyledDisconnectButton = styled(AppButton.RedButton)(buttonStyle); + export default { // plain CSS style scrollview: { @@ -79,7 +87,4 @@ export default { height: 68, justifyContent: 'center', }), - button: Styles.createViewStyle({ - marginBottom: 24, - }), }; diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx index 9d317091ac..f22f72be67 100644 --- a/gui/src/renderer/components/Login.tsx +++ b/gui/src/renderer/components/Login.tsx @@ -400,7 +400,7 @@ export default class Login extends Component<IProps, IState> { {messages.pgettext('login-view', "Don't have an account number?")} </Text> <AppButton.BlueButton - onPress={this.props.createNewAccount} + onClick={this.props.createNewAccount} disabled={!this.allowInteraction()}> {messages.pgettext('login-view', 'Create account')} </AppButton.BlueButton> diff --git a/gui/src/renderer/components/MultiButton.tsx b/gui/src/renderer/components/MultiButton.tsx index efd21ee9ca..a9f1d09dee 100644 --- a/gui/src/renderer/components/MultiButton.tsx +++ b/gui/src/renderer/components/MultiButton.tsx @@ -1,49 +1,40 @@ -import * as React from 'react'; -import { Component, Styles, Types, View } from 'reactxp'; +import React from 'react'; +import styled from 'styled-components'; +import * as AppButton from './AppButton'; const SIDE_BUTTON_WIDTH = 50; -const styles = { - buttonRow: Styles.createViewStyle({ - flexDirection: 'row', - }), - mainButton: Styles.createViewStyle({ - flex: 1, - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }), - sideButton: Styles.createViewStyle({ - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - width: SIDE_BUTTON_WIDTH, - alignItems: 'center', - marginLeft: 1, - }), -}; +const ButtonRow = styled.div({ + display: 'flex', + flexDirection: 'row', +}); -interface IProps { - mainButton: React.ComponentType<IMainButtonProps>; - sideButton: React.ComponentType<ISideButtonProps>; -} +const MainButton = styled.button({ + display: 'flex', + flex: 1, + borderTopRightRadius: 0, + borderBottomRightRadius: 0, +}); -export interface IMainButtonProps { - textOffset: number; - style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>; -} +const SideButton = styled.button({ + display: 'flex', + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + width: SIDE_BUTTON_WIDTH, + alignItems: 'center', + marginLeft: 1, +}); -export interface ISideButtonProps { - style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>; +interface IMultiButtonProps { + mainButton: React.ComponentType<AppButton.IProps>; + sideButton: React.ComponentType<AppButton.IProps>; } -export class MultiButton extends Component<IProps> { - public render() { - const { mainButton: MainButton, sideButton: SideButton } = this.props; - - return ( - <View style={styles.buttonRow}> - <MainButton textOffset={SIDE_BUTTON_WIDTH} style={styles.mainButton} /> - <SideButton style={styles.sideButton} /> - </View> - ); - } +export function MultiButton(props: IMultiButtonProps) { + return ( + <ButtonRow> + <MainButton as={props.mainButton} textOffset={SIDE_BUTTON_WIDTH} /> + <SideButton as={props.sideButton} /> + </ButtonRow> + ); } diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx index 360c910403..5831676fcf 100644 --- a/gui/src/renderer/components/NotificationBanner.tsx +++ b/gui/src/renderer/components/NotificationBanner.tsx @@ -105,7 +105,7 @@ export class NotificationOpenLinkAction extends Component<INotifcationOpenLinkAc public render() { return ( - <BlockingButton onPress={this.props.onPress}> + <BlockingButton onClick={this.props.onPress}> <Button style={styles.actionButton} onHoverStart={this.onHoverStart} diff --git a/gui/src/renderer/components/RedeemVoucher.tsx b/gui/src/renderer/components/RedeemVoucher.tsx index da7a398bb0..4fdb57b64e 100644 --- a/gui/src/renderer/components/RedeemVoucher.tsx +++ b/gui/src/renderer/components/RedeemVoucher.tsx @@ -1,6 +1,5 @@ import React, { useCallback, useContext, useState } from 'react'; import { useSelector } from 'react-redux'; -import { Types } from 'reactxp'; import { VoucherResponse } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; import { useScheduler } from '../../shared/scheduler'; @@ -178,7 +177,7 @@ export function RedeemVoucherSubmitButton() { const disabled = submitting || response?.type === 'success'; return ( - <AppButton.GreenButton key="cancel" disabled={!valueValid || disabled} onPress={onSubmit}> + <AppButton.GreenButton key="cancel" disabled={!valueValid || disabled} onClick={onSubmit}> {messages.pgettext('redeem-voucher-view', 'Redeem')} </AppButton.GreenButton> ); @@ -196,7 +195,7 @@ export function RedeemVoucherAlert(props: IRedeemVoucherAlertProps) { <ModalAlert buttons={[ <RedeemVoucherSubmitButton key="submit" />, - <AppButton.BlueButton key="cancel" disabled={cancelDisabled} onPress={props.onClose}> + <AppButton.BlueButton key="cancel" disabled={cancelDisabled} onClick={props.onClose}> {messages.pgettext('redeem-voucher-alert', 'Cancel')} </AppButton.BlueButton>, ]}> @@ -208,19 +207,19 @@ export function RedeemVoucherAlert(props: IRedeemVoucherAlertProps) { } interface IRedeemVoucherButtonProps { - style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>; + className?: string; } export function RedeemVoucherButton(props: IRedeemVoucherButtonProps) { const isBlocked = useSelector((state: IReduxState) => state.connection.isBlocked); const [showAlert, setShowAlert] = useState(false); - const onPress = useCallback(() => setShowAlert(true), []); + const onClick = useCallback(() => setShowAlert(true), []); const onClose = useCallback(() => setShowAlert(false), []); return ( <> - <AppButton.GreenButton disabled={isBlocked} onPress={onPress} style={props.style}> + <AppButton.GreenButton disabled={isBlocked} onClick={onClick} className={props.className}> {messages.pgettext('redeem-voucher-alert', 'Redeem voucher')} </AppButton.GreenButton> {showAlert && ( diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx index 644190a4db..4a7684f405 100644 --- a/gui/src/renderer/components/Settings.tsx +++ b/gui/src/renderer/components/Settings.tsx @@ -89,7 +89,7 @@ export default class Settings extends Component<IProps> { private renderQuitButton() { return ( <View style={styles.quitButtonFooter}> - <AppButton.RedButton onPress={this.props.onQuit}> + <AppButton.RedButton onClick={this.props.onQuit}> {messages.pgettext('settings-view', 'Quit app')} </AppButton.RedButton> </View> diff --git a/gui/src/renderer/components/Support.tsx b/gui/src/renderer/components/Support.tsx index 244f939a5e..ee0514e67f 100644 --- a/gui/src/renderer/components/Support.tsx +++ b/gui/src/renderer/components/Support.tsx @@ -8,7 +8,7 @@ import { Container, Layout } from './Layout'; import { ModalAlert, ModalAlertType, ModalContainer } from './Modal'; import { BackBarItem, NavigationBar, NavigationItems } from './NavigationBar'; import SettingsHeader, { HeaderSubTitle, HeaderTitle } from './SettingsHeader'; -import styles from './SupportStyles'; +import styles, { StyledBlueButton } from './SupportStyles'; import { AccountToken } from '../../shared/daemon-rpc-types'; import { ISupportReportForm } from '../redux/support/actions'; @@ -231,10 +231,10 @@ export default class Support extends Component<ISupportProps, ISupportState> { type={ModalAlertType.Warning} message={message} buttons={[ - <AppButton.RedButton key="proceed" onPress={this.onSend}> + <AppButton.RedButton key="proceed" onClick={this.onSend}> {messages.pgettext('support-view', 'Send anyway')} </AppButton.RedButton>, - <AppButton.BlueButton key="cancel" onPress={this.onCancelNoEmailDialog}> + <AppButton.BlueButton key="cancel" onClick={this.onCancelNoEmailDialog}> {messages.gettext('Back')} </AppButton.BlueButton>, ]} @@ -261,14 +261,14 @@ export default class Support extends Component<ISupportProps, ISupportState> { <AppButton.GreenButton key="upgrade" disabled={this.props.isOffline} - onPress={this.openDownloadLink}> + onClick={this.openDownloadLink}> <AppButton.Label>{messages.pgettext('support-view', 'Upgrade app')}</AppButton.Label> <AppButton.Icon height={16} width={16} source="icon-extLink" /> </AppButton.GreenButton>, - <AppButton.RedButton key="proceed" onPress={this.acknowledgeOutdateVersion}> + <AppButton.RedButton key="proceed" onClick={this.acknowledgeOutdateVersion}> {messages.pgettext('support-view', 'Continue anyway')} </AppButton.RedButton>, - <AppButton.BlueButton key="cancel" onPress={this.props.onClose}> + <AppButton.BlueButton key="cancel" onClick={this.props.onClose}> {messages.gettext('Cancel')} </AppButton.BlueButton>, ]} @@ -301,18 +301,15 @@ export default class Support extends Component<ISupportProps, ISupportState> { </View> </View> <View style={styles.support__footer}> - <AppButton.BlueButton - style={styles.view_logs_button} - onPress={this.onViewLog} - disabled={this.state.disableActions}> + <StyledBlueButton onClick={this.onViewLog} disabled={this.state.disableActions}> <AppButton.Label> {messages.pgettext('support-view', 'View app logs')} </AppButton.Label> <AppButton.Icon source="icon-extLink" height={16} width={16} /> - </AppButton.BlueButton> + </StyledBlueButton> <AppButton.GreenButton disabled={!this.validate() || this.state.disableActions} - onPress={this.onSend}> + onClick={this.onSend}> {messages.pgettext('support-view', 'Send')} </AppButton.GreenButton> </View> @@ -406,10 +403,10 @@ export default class Support extends Component<ISupportProps, ISupportState> { </View> </View> <View style={styles.support__footer}> - <AppButton.BlueButton style={styles.edit_message_button} onPress={this.handleEditMessage}> + <StyledBlueButton onClick={this.handleEditMessage}> {messages.pgettext('support-view', 'Edit message')} - </AppButton.BlueButton> - <AppButton.GreenButton onPress={this.onSend}> + </StyledBlueButton> + <AppButton.GreenButton onClick={this.onSend}> {messages.pgettext('support-view', 'Try again')} </AppButton.GreenButton> </View> diff --git a/gui/src/renderer/components/SupportStyles.tsx b/gui/src/renderer/components/SupportStyles.tsx index d883c806ba..5c5915bcd4 100644 --- a/gui/src/renderer/components/SupportStyles.tsx +++ b/gui/src/renderer/components/SupportStyles.tsx @@ -1,5 +1,11 @@ import { Styles } from 'reactxp'; +import styled from 'styled-components'; import { colors } from '../../config.json'; +import * as AppButton from './AppButton'; + +export const StyledBlueButton = styled(AppButton.BlueButton)({ + marginBottom: 16, +}); export default { support: Styles.createViewStyle({ @@ -51,12 +57,6 @@ export default { alignItems: 'center', marginBottom: 32, }), - view_logs_button: Styles.createViewStyle({ - marginBottom: 16, - }), - edit_message_button: Styles.createViewStyle({ - marginBottom: 16, - }), support__form_email: Styles.createTextStyle({ flex: 1, borderRadius: 4, diff --git a/gui/src/renderer/components/TunnelControl.tsx b/gui/src/renderer/components/TunnelControl.tsx index bb2c06ef62..7043c900c8 100644 --- a/gui/src/renderer/components/TunnelControl.tsx +++ b/gui/src/renderer/components/TunnelControl.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Component, Styles, Types, View } from 'reactxp'; +import styled from 'styled-components'; import { colors } from '../../config.json'; import { TunnelState } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; @@ -7,7 +8,7 @@ import ConnectionPanelContainer from '../containers/ConnectionPanelContainer'; import * as AppButton from './AppButton'; import ImageView from './ImageView'; import Marquee from './Marquee'; -import { IMainButtonProps, ISideButtonProps, MultiButton } from './MultiButton'; +import { MultiButton } from './MultiButton'; import SecuredLabel, { SecuredDisplayStyle } from './SecuredLabel'; interface ITunnelControlProps { @@ -21,6 +22,10 @@ interface ITunnelControlProps { onSelectLocation: () => void; } +const SwitchLocationButton = styled(AppButton.TransparentButton)({ + marginBottom: 16, +}); + const styles = { body: Styles.createViewStyle({ paddingTop: 0, @@ -39,9 +44,6 @@ const styles = { wrapper: Styles.createViewStyle({ flex: 1, }), - switch_location_button: Styles.createViewStyle({ - marginBottom: 16, - }), status_security: Styles.createTextStyle({ fontFamily: 'Open Sans', fontSize: 16, @@ -76,49 +78,45 @@ export default class TunnelControl extends Component<ITunnelControlProps> { const SwitchLocation = () => { return ( - <AppButton.TransparentButton - style={styles.switch_location_button} - onPress={this.props.onSelectLocation}> + <SwitchLocationButton onClick={this.props.onSelectLocation}> {messages.pgettext('tunnel-control', 'Switch location')} - </AppButton.TransparentButton> + </SwitchLocationButton> ); }; const SelectedLocation = () => ( - <AppButton.TransparentButton - style={styles.switch_location_button} - onPress={this.props.onSelectLocation}> + <SwitchLocationButton onClick={this.props.onSelectLocation}> <AppButton.Label>{this.props.selectedRelayName}</AppButton.Label> <AppButton.Icon height={12} width={7} source="icon-chevron" /> - </AppButton.TransparentButton> + </SwitchLocationButton> ); const Connect = () => ( - <AppButton.GreenButton onPress={this.props.onConnect}> + <AppButton.GreenButton onClick={this.props.onConnect}> {messages.pgettext('tunnel-control', 'Secure my connection')} </AppButton.GreenButton> ); - const Disconnect = (props: IMainButtonProps) => ( - <AppButton.RedTransparentButton onPress={this.props.onDisconnect} {...props}> + const Disconnect = (props: React.ComponentProps<typeof AppButton.RedTransparentButton>) => ( + <AppButton.RedTransparentButton onClick={this.props.onDisconnect} {...props}> {messages.pgettext('tunnel-control', 'Disconnect')} </AppButton.RedTransparentButton> ); - const Cancel = (props: IMainButtonProps) => ( - <AppButton.RedTransparentButton onPress={this.props.onDisconnect} {...props}> + const Cancel = (props: React.ComponentProps<typeof AppButton.RedTransparentButton>) => ( + <AppButton.RedTransparentButton onClick={this.props.onDisconnect} {...props}> {messages.pgettext('tunnel-control', 'Cancel')} </AppButton.RedTransparentButton> ); - const Dismiss = (props: IMainButtonProps) => ( - <AppButton.RedTransparentButton onPress={this.props.onDisconnect} {...props}> + const Dismiss = (props: React.ComponentProps<typeof AppButton.RedTransparentButton>) => ( + <AppButton.RedTransparentButton onClick={this.props.onDisconnect} {...props}> {messages.pgettext('tunnel-control', 'Dismiss')} </AppButton.RedTransparentButton> ); - const Reconnect = (props: ISideButtonProps) => ( - <AppButton.RedTransparentButton onPress={this.props.onReconnect} {...props}> + const Reconnect = (props: React.ComponentProps<typeof AppButton.RedTransparentButton>) => ( + <AppButton.RedTransparentButton onClick={this.props.onReconnect} {...props}> <ImageView height={22} width={22} source="icon-reload" tintColor="white" /> </AppButton.RedTransparentButton> ); diff --git a/gui/src/renderer/components/WireguardKeys.tsx b/gui/src/renderer/components/WireguardKeys.tsx index 5af224be35..b11ffe59c0 100644 --- a/gui/src/renderer/components/WireguardKeys.tsx +++ b/gui/src/renderer/components/WireguardKeys.tsx @@ -119,7 +119,7 @@ export default class WireguardKeys extends Component<IProps, IState> { <View style={styles.wgkeys__row}> <AppButton.BlueButton disabled={this.isVerifyButtonDisabled()} - onPress={this.getOnVerifyKeyCb()}> + onClick={this.getOnVerifyKeyCb()}> <AppButton.Label> {messages.pgettext('wireguard-key-view', 'Verify key')} </AppButton.Label> @@ -128,7 +128,7 @@ export default class WireguardKeys extends Component<IProps, IState> { <View style={styles.wgkeys__row}> <AppButton.BlockingButton disabled={this.props.isOffline} - onPress={this.props.onVisitWebsiteKey}> + onClick={this.props.onVisitWebsiteKey}> <AppButton.BlueButton> <AppButton.Label> {messages.pgettext('wireguard-key-view', 'Manage keys')} @@ -203,7 +203,7 @@ export default class WireguardKeys extends Component<IProps, IState> { return this.busyButton(messages.pgettext('wireguard-key-view', 'Generating key')); } return ( - <AppButton.GreenButton disabled={this.props.isOffline} onPress={generateKey}> + <AppButton.GreenButton disabled={this.props.isOffline} onClick={generateKey}> <AppButton.Label>{buttonText}</AppButton.Label> </AppButton.GreenButton> ); |
