Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: created QR modal component #1339

Merged
merged 6 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/frontend/src/lib/components/send/QRCodeModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<script lang="ts">
import { i18n } from '$lib/stores/i18n.store';
import {
QRCodeReaderModal,
WizardModal,
type WizardStep,
type WizardSteps
} from '@dfinity/gix-components';
import { type Token } from '@dfinity/utils';
import { toastsError } from '$lib/stores/toasts.store';
import type { QrResponse, QrStatus } from '$lib/types/qr-code';
import { decodeQrCode } from '$lib/utils/qr-code.utils';

export let steps: WizardSteps;
export let currentStep: WizardStep | undefined = undefined;

let qrCodeStep = 'Scan QR Code';

let stepsPlusQr: WizardSteps;
$: stepsPlusQr = [
...steps,
{
name: qrCodeStep,
title: $i18n.send.text.scan_qr
}
];

let modal: WizardModal;

const goToStep = (stepName: string) => {
const stepNumber = Math.max(
stepsPlusQr.findIndex(({ name }) => name === stepName),
0
);
modal.set(stepNumber);
};

let resolveQrCodePromise:
| (({ status, code }: { status: QrStatus; code?: string }) => void)
| undefined = undefined;

export const scanQrCode = ({ expectedToken }: { expectedToken: Token }): Promise<QrResponse> => {
const prevStep = currentStep;
goToStep(qrCodeStep);

return new Promise<{ status: QrStatus; code?: string | undefined }>((resolve) => {
resolveQrCodePromise = resolve;
})
.then(({ status, code }) => {
if (status === 'token_incompatible') {
toastsError({
msg: { text: $i18n.send.error.incompatible_token }
});
return Promise.reject(new Error($i18n.send.error.incompatible_token));
}
return decodeQrCode({ status, code, expectedToken });
AntonioVentilii-DFINITY marked this conversation as resolved.
Show resolved Hide resolved
})
.finally(() => goToStep(prevStep?.name || steps[0].name));
};

const onQRCode = ({ detail: code }: CustomEvent<string>) => {
resolveQrCodePromise?.({ status: 'success', code });
resolveQrCodePromise = undefined;
};

const onCancel = () => {
resolveQrCodePromise?.({ status: 'cancelled' });
resolveQrCodePromise = undefined;
};
</script>

<WizardModal
steps={stepsPlusQr}
bind:currentStep
bind:this={modal}
on:nnsClose
testId="qr-code-modal"
disablePointerEvents={currentStep?.name === 'Sending'}
AntonioVentilii-DFINITY marked this conversation as resolved.
Show resolved Hide resolved
>
<svelte:fragment slot="title">{$i18n.send.text.scan_qr}</svelte:fragment>
{#if currentStep?.name === qrCodeStep}
<QRCodeReaderModal on:nnsCancel={onCancel} on:nnsQRCode={onQRCode} />
{/if}
</WizardModal>
6 changes: 4 additions & 2 deletions src/frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@
"destination_network": "Destination network",
"initializing_transaction": "Initializing transaction",
"convert_to_native_icp": "Convert to native ICP",
"open_qr_modal": "Start QR Code scan for transaction details"
"open_qr_modal": "Start QR Code scan for transaction details",
"scan_qr": "Scan QR Code"
},
"placeholder": {
"enter_eth_address": "Enter public address (0x)",
Expand Down Expand Up @@ -242,7 +243,8 @@
"erc20_data_undefined": "Erc20 transaction Data cannot be undefined or null.",
"data_undefined": "Transaction Data cannot be undefined or null.",
"no_identity_calculate_fee": "No identity provided to calculate the fee for its principal.",
"invalid_destination": "The destination is invalid. Please try again with a valid wallet address or destination."
"invalid_destination": "The destination is invalid. Please try again with a valid wallet address or destination.",
"incompatible_token": "The token is incompatible. Please try again with a compatible token."
}
},
"convert": {
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/src/lib/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ interface I18nSend {
initializing_transaction: string;
convert_to_native_icp: string;
open_qr_modal: string;
scan_qr: string;
};
placeholder: {
enter_eth_address: string;
Expand Down Expand Up @@ -217,6 +218,7 @@ interface I18nSend {
data_undefined: string;
no_identity_calculate_fee: string;
invalid_destination: string;
incompatible_token: string;
};
}

Expand Down