Skip to content

Commit 507db76

Browse files
committed
Merge branch 'frontend-navigate-back'
2 parents f4f4de1 + 2dddbd3 commit 507db76

File tree

18 files changed

+140
-127
lines changed

18 files changed

+140
-127
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright 2024 Shift Crypto AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { ReactNode, useCallback } from 'react';
18+
import { useNavigate } from 'react-router-dom';
19+
import { useEsc } from '@/hooks/keyboard';
20+
import { Button } from '@/components/forms/button';
21+
22+
type TBackButton = {
23+
children: ReactNode;
24+
className?: string;
25+
disabled?: boolean;
26+
enableEsc?: boolean;
27+
};
28+
29+
export const BackButton = ({
30+
children,
31+
className,
32+
disabled,
33+
enableEsc,
34+
}: TBackButton) => {
35+
const navigate = useNavigate();
36+
37+
const handleBack = useCallback(() => {
38+
if (!disabled) {
39+
navigate(-1);
40+
}
41+
}, [disabled, navigate]);
42+
43+
useEsc(useCallback(() => enableEsc && handleBack(), [enableEsc, handleBack]));
44+
45+
return (
46+
<Button
47+
disabled={disabled}
48+
className={className}
49+
onClick={handleBack}
50+
secondary
51+
>
52+
{children}
53+
</Button>
54+
);
55+
};

frontends/web/src/components/forms/button.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type TProps = TButtonStyleProp & {
3737
children: ReactNode;
3838
}
3939

40+
type TButtonLink = LinkProps & TProps;
41+
4042
export const ButtonLink = ({
4143
primary,
4244
secondary,
@@ -46,14 +48,14 @@ export const ButtonLink = ({
4648
children,
4749
disabled,
4850
...props
49-
}: LinkProps & TProps) => {
51+
}: TButtonLink) => {
5052
const classNames = [
5153
style[
5254
(primary && 'primary')
53-
|| (secondary && 'secondary')
54-
|| (transparent && 'transparent')
55-
|| (danger && 'danger')
56-
|| 'button'
55+
|| (secondary && 'secondary')
56+
|| (transparent && 'transparent')
57+
|| (danger && 'danger')
58+
|| 'button'
5759
], className
5860
].join(' ');
5961

@@ -75,6 +77,8 @@ export const ButtonLink = ({
7577
);
7678
};
7779

80+
type TButton = TProps & ComponentPropsWithoutRef<'button'>;
81+
7882
export const Button = ({
7983
type = 'button',
8084
primary,
@@ -84,13 +88,14 @@ export const Button = ({
8488
className = '',
8589
children,
8690
...props
87-
}: TProps & ComponentPropsWithoutRef<'button'>) => {
91+
}: TButton) => {
8892
const classNames = [
89-
style[(primary && 'primary')
90-
|| (secondary && 'secondary')
91-
|| (transparent && 'transparent')
92-
|| (danger && 'danger')
93-
|| 'button'
93+
style[
94+
(primary && 'primary')
95+
|| (secondary && 'secondary')
96+
|| (transparent && 'transparent')
97+
|| (danger && 'danger')
98+
|| 'button'
9499
], className
95100
].join(' ');
96101

frontends/web/src/components/transactions/components/details.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export const TxDetailsDialog = ({
7777
}
7878
}, [accountCode, internalID, open, transactionInfo]);
7979

80+
if (transactionInfo === null) {
81+
return;
82+
}
83+
8084
// Amount and Confirmations info are displayed using props data
8185
// instead of transactionInfo because they are live updated.
8286
return (

frontends/web/src/routes/account/add/add.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const AddAccount = ({ accounts }: TAddAccountGuide) => {
8888
const back = () => {
8989
switch (step) {
9090
case 'select-coin':
91-
navigate('/settings/manage-accounts');
91+
navigate(-1);
9292
break;
9393
case 'choose-name':
9494
setStep('select-coin');

frontends/web/src/routes/account/info/info.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright 2018 Shift Devices AG
3-
* Copyright 2022 Shift Crypto AG
3+
* Copyright 2022-2024 Shift Crypto AG
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,14 +16,12 @@
1616
*/
1717

1818
import { useState } from 'react';
19-
import { useNavigate } from 'react-router-dom';
2019
import { useTranslation } from 'react-i18next';
2120
import { useLoad } from '@/hooks/api';
22-
import { useEsc } from '@/hooks/keyboard';
2321
import { getInfo, IAccount, AccountCode } from '@/api/account';
2422
import { isBitcoinBased } from '@/routes/account/utils';
25-
import { ButtonLink } from '@/components/forms';
2623
import { Header } from '@/components/layout';
24+
import { BackButton } from '@/components/backbutton/backbutton';
2725
import { SigningConfiguration } from './signingconfiguration';
2826
import { BitcoinBasedAccountInfoGuide } from './guide';
2927
import style from './info.module.css';
@@ -37,14 +35,11 @@ export const Info = ({
3735
accounts,
3836
code,
3937
}: TProps) => {
40-
const navigate = useNavigate();
4138
const { t } = useTranslation();
4239
const info = useLoad(getInfo(code));
4340
const [viewXPub, setViewXPub] = useState<number>(0);
4441
const account = accounts.find(({ code: accountCode }) => accountCode === code);
4542

46-
useEsc(() => navigate(`/account/${code}`));
47-
4843
if (!account || !info) {
4944
return null;
5045
}
@@ -91,11 +86,9 @@ export const Info = ({
9186
code={code}
9287
info={config}
9388
signingConfigIndex={viewXPub}>
94-
<ButtonLink
95-
secondary
96-
to={`/account/${code}`}>
89+
<BackButton enableEsc>
9790
{t('button.back')}
98-
</ButtonLink>
91+
</BackButton>
9992
</SigningConfiguration>
10093
</div>
10194
</div>

frontends/web/src/routes/account/receive/receive-bb01.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616
*/
1717

1818
import React, { useEffect, useRef, useState } from 'react';
19-
import { useNavigate } from 'react-router-dom';
2019
import { useTranslation } from 'react-i18next';
2120
import { useLoad } from '@/hooks/api';
22-
import { useEsc } from '@/hooks/keyboard';
2321
import * as accountApi from '@/api/account';
2422
import { getScriptName, isEthereumBased } from '@/routes/account/utils';
2523
import { alertUser } from '@/components/alert/Alert';
2624
import { CopyableInput } from '@/components/copy/Copy';
2725
import { Dialog, DialogButtons } from '@/components/dialog/dialog';
28-
import { Button, ButtonLink, Radio } from '@/components/forms';
26+
import { Button, Radio } from '@/components/forms';
27+
import { BackButton } from '@/components/backbutton/backbutton';
2928
import { Message } from '@/components/message/message';
3029
import { ReceiveGuide } from './components/guide';
3130
import { Header } from '@/components/layout';
@@ -63,7 +62,6 @@ export const Receive = ({
6362
code,
6463
deviceID,
6564
}: TProps) => {
66-
const navigate = useNavigate();
6765
const { t } = useTranslation();
6866
const [verifying, setVerifying] = useState<boolean>(false);
6967
const [activeIndex, setActiveIndex] = useState<number>(0);
@@ -80,8 +78,6 @@ export const Receive = ({
8078
const receiveAddresses = useLoad(accountApi.getReceiveAddressList(code));
8179
const secureOutput = useLoad(accountApi.hasSecureOutput(code));
8280

83-
useEsc(() => !verifying && navigate(`/account/${code}`));
84-
8581
const availableScriptTypes = useRef<accountApi.ScriptType[]>();
8682

8783
useEffect(() => {
@@ -241,11 +237,9 @@ export const Receive = ({
241237
disabled={verifying || secureOutput === undefined}
242238
forceVerification={forceVerification}
243239
onClick={() => verifyAddress(currentAddressIndex)}/>
244-
<ButtonLink
245-
secondary
246-
to={`/account/${code}`}>
240+
<BackButton enableEsc={!verifying}>
247241
{t('button.back')}
248-
</ButtonLink>
242+
</BackButton>
249243
</div>
250244
{ forceVerification && verifying && (
251245
<div className={style.hide}></div>

frontends/web/src/routes/account/receive/receive.tsx

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright 2018 Shift Devices AG
3-
* Copyright 2023 Shift Crypto AG
3+
* Copyright 2023-2024 Shift Crypto AG
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,15 +16,14 @@
1616
*/
1717

1818
import React, { useEffect, useRef, useState } from 'react';
19-
import { useNavigate } from 'react-router-dom';
2019
import { useTranslation } from 'react-i18next';
2120
import { useLoad } from '@/hooks/api';
22-
import { useEsc } from '@/hooks/keyboard';
2321
import * as accountApi from '@/api/account';
2422
import { getScriptName, isEthereumBased } from '@/routes/account/utils';
2523
import { CopyableInput } from '@/components/copy/Copy';
2624
import { Dialog, DialogButtons } from '@/components/dialog/dialog';
27-
import { Button, ButtonLink, Radio } from '@/components/forms';
25+
import { Button, Radio } from '@/components/forms';
26+
import { BackButton } from '@/components/backbutton/backbutton';
2827
import { Message } from '@/components/message/message';
2928
import { ReceiveGuide } from './components/guide';
3029
import { Header } from '@/components/layout';
@@ -114,7 +113,6 @@ export const Receive = ({
114113
accounts,
115114
code,
116115
}: TProps) => {
117-
const navigate = useNavigate();
118116
const { t } = useTranslation();
119117
const [verifying, setVerifying] = useState<false | 'secure' | 'insecure'>(false);
120118
const [activeIndex, setActiveIndex] = useState<number>(0);
@@ -134,8 +132,6 @@ export const Receive = ({
134132

135133
const hasManyScriptTypes = availableScriptTypes.current && availableScriptTypes.current.length > 1;
136134

137-
useEsc(() => !addressTypeDialog && !verifying && navigate(`/account/${code}`));
138-
139135
useEffect(() => {
140136
if (receiveAddresses) {
141137
// All script types that are present in the addresses delivered by the backend. Will be empty for if there are no such addresses, e.g. in Ethereum.
@@ -280,11 +276,9 @@ export const Receive = ({
280276
primary>
281277
{t('receive.verifyBitBox02')}
282278
</Button>
283-
<ButtonLink
284-
secondary
285-
to={`/account/${code}`}>
279+
<BackButton enableEsc={!addressTypeDialog && !verifying}>
286280
{t('button.back')}
287-
</ButtonLink>
281+
</BackButton>
288282
</div>
289283
{ verifying && (
290284
<div className={style.hide}></div>

frontends/web/src/routes/account/send/send.tsx

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ import { getDeviceInfo } from '@/api/bitbox01';
2525
import { alertUser } from '@/components/alert/Alert';
2626
import { Balance } from '@/components/balance/balance';
2727
import { HideAmountsButton } from '@/components/hideamountsbutton/hideamountsbutton';
28-
import { Button, ButtonLink } from '@/components/forms';
28+
import { Button } from '@/components/forms';
29+
import { BackButton } from '@/components/backbutton/backbutton';
2930
import { Column, ColumnButtons, Grid, GuideWrapper, GuidedContent, Header, Main } from '@/components/layout';
3031
import { Status } from '@/components/status/status';
3132
import { translate, TranslateProps } from '@/decorators/translate';
3233
import { getConfig } from '@/utils/config';
3334
import { FeeTargets } from './feetargets';
34-
import { route } from '@/utils/route';
3535
import { signConfirm, signProgress, TSignProgress } from '@/api/devicessync';
3636
import { UnsubscribeList, unsubscribe } from '@/utils/subscriptions';
3737
import { isBitcoinBased, findAccount } from '@/routes/account/utils';
@@ -166,26 +166,14 @@ class Send extends Component<Props, State> {
166166
}
167167
}),
168168
];
169-
170-
this.registerEvents();
171169
}
172170

173171
public componentWillUnmount() {
174-
this.unregisterEvents();
175172
unsubscribe(this.unsubscribeList);
176173
// Wipe proposed tx note.
177174
accountApi.proposeTxNote(this.getAccount()!.code, '');
178175
}
179176

180-
private registerEvents = () => document.addEventListener('keydown', this.handleKeyDown);
181-
private unregisterEvents = () => document.removeEventListener('keydown', this.handleKeyDown);
182-
183-
private handleKeyDown = (e: KeyboardEvent) => {
184-
if (e.key === 'Escape' && !this.state.activeCoinControl && !this.state.activeScanQR) {
185-
route(`/account/${this.props.code}`);
186-
}
187-
};
188-
189177
private send = async () => {
190178
if (this.state.noMobileChannelError) {
191179
alertUser(this.props.t('warning.sendPairing'));
@@ -330,7 +318,7 @@ class Send extends Component<Props, State> {
330318
this.convertToFiat(result.amount.amount);
331319
}
332320
} else {
333-
const errorHandling = txProposalErrorHandling(this.registerEvents, this.unregisterEvents, result.errorCode);
321+
const errorHandling = txProposalErrorHandling(result.errorCode);
334322
this.setState({ ...errorHandling, isUpdatingProposal: false });
335323
}
336324
};
@@ -484,7 +472,7 @@ class Send extends Component<Props, State> {
484472
};
485473

486474
public render() {
487-
const { t, code } = this.props;
475+
const { t } = this.props;
488476
const {
489477
balance,
490478
proposedFee,
@@ -637,11 +625,11 @@ class Send extends Component<Props, State> {
637625
disabled={!this.getValidTxInputData() || !valid || isUpdatingProposal}>
638626
{t('send.button')}
639627
</Button>
640-
<ButtonLink
641-
secondary
642-
to={`/account/${code}`}>
628+
<BackButton
629+
disabled={activeCoinControl || activeScanQR}
630+
enableEsc>
643631
{t('button.back')}
644-
</ButtonLink>
632+
</BackButton>
645633
</ColumnButtons>
646634
</Column>
647635
</Grid>

0 commit comments

Comments
 (0)