final frontend parts

pull/33/head
Laurin Weger 2 months ago
parent bb6d118f34
commit 18101e4fae
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 8
      ng-app/src/lib/components/CopyToClipboard.svelte
  2. 17
      ng-app/src/locales/en.json
  3. 2
      ng-app/src/routes/ScanQR.svelte
  4. 152
      ng-app/src/routes/WalletInfo.svelte
  5. 56
      ng-app/src/routes/WalletLogin.svelte
  6. 27
      ng-app/src/routes/WalletLoginQr.svelte
  7. 54
      ng-app/src/routes/WalletLoginTextCode.svelte

@ -11,7 +11,8 @@
<script lang="ts"> <script lang="ts">
export let value: string = ""; export let value: string = "";
export let id: string; export let id: string | undefined = undefined;
export let rows: number = 3;
let has_success: boolean = false; let has_success: boolean = false;
@ -37,10 +38,11 @@
<div class="relative"> <div class="relative">
<textarea <textarea
{id} {id}
rows="3" {rows}
style="resize: none;" style="resize: none;"
{value} {value}
class="col-span-6 pr-11 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" class="col-span-6 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500"
class:pr-11={!tauri_platform}
disabled disabled
readonly readonly
/> />

@ -29,19 +29,20 @@
"remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?", "remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?",
"create_text_code": "Generate TextCode to export", "create_text_code": "Generate TextCode to export",
"scan_qr.title": "Export by scanning QR-Code", "scan_qr.title": "Export by scanning QR-Code",
"scan_qr.notes": "Scan the QR-Code on the device that you want to transfer your wallet to.<br />.", "scan_qr.notes": "Scan the QR-Code on the device that you want to transfer your wallet to.",
"scan_qr.scan_btn": "Scan QR Code ", "scan_qr.scan_btn": "Scan QR Code ",
"scan_qr.scanner.title": "Scan your QR Code", "scan_qr.scanner.title": "Scan your QR Code",
"scan_qr.scanner.loading": "Loading scanner", "scan_qr.scanner.loading": "Loading scanner",
"scan_qr.syncing": "Synchronizing wallet", "scan_qr.syncing": "Synchronizing wallet",
"scan_qr.scan_successful": "Success!<br />Your wallet has been synchronized to the new device.", "scan_qr.scan_successful": "Success!<br />Your wallet has been transferred to the new device.",
"gen_qr.title": "Export with generated QR-Code", "gen_qr.title": "Export with generated QR-Code",
"gen_qr.notes": "Use the following QR-Code to scan with the device that you want to transfer your wallet to.", "gen_qr.notes": "Use the following QR-Code to scan with the device that you want to transfer your wallet to.",
"gen_qr.img_title": "Your Export QR Code to Scan", "gen_qr.img_title": "Your Export QR Code to Scan",
"gen_qr.img_alt": "Your Export QR Code to Scan", "gen_qr.img_alt": "Your Export QR Code to Scan",
"gen_qr.gen_button": "Display QR Code", "gen_qr.gen_button": "Show QR Code",
"gen_text_code.title": "Export with TextCode", "gen_text_code.title": "Export with TextCode",
"gen_text_code.gen_btn": "Generate TextCode" "gen_text_code.gen_btn": "Generate TextCode",
"gen_text_code.label": "Your TextCode:"
}, },
"settings": { "settings": {
"title": "Settings" "title": "Settings"
@ -241,7 +242,8 @@
"wallet_login": { "wallet_login": {
"select_wallet": "Select a wallet to login with", "select_wallet": "Select a wallet to login with",
"from_import.title": "Your wallet has been transferred", "from_import.title": "Your wallet has been transferred",
"from_import.description": "Your wallet has been transferred!<br />To finish the import, please log in.", "from_import.description": "Your wallet has been received:",
"from_import.instruction": "To finish the import, please log in.",
"with_another_wallet": "Log in with another wallet", "with_another_wallet": "Log in with another wallet",
"import_wallet": "Import your wallet", "import_wallet": "Import your wallet",
"import_file": "Import a Wallet File", "import_file": "Import a Wallet File",
@ -256,7 +258,7 @@
"scan.button": "Scan QR-Code", "scan.button": "Scan QR-Code",
"scan.modal.title": "Scan Wallet QR-Code", "scan.modal.title": "Scan Wallet QR-Code",
"gen.button": "Generate", "gen.button": "Generate",
"gen.description": "To import your wallet from another device, you have to display a QR-Code here on this device, and then scan it with your other device. On the other device, go to<br /><span class=\"path\">User Panel > Wallet > Scan QR</span> to export.", "gen.description": "To import your wallet from another device, you have to generate a QR-Code here on this device, and then scan it with your other device. On the other device, go to<br /><span class=\"path\">User Panel > Wallet > Scan QR</span> to export.",
"gen.generated": "Scan this QR-Code from the the other device.", "gen.generated": "Scan this QR-Code from the the other device.",
"success_btn": "Continue to Login" "success_btn": "Continue to Login"
}, },
@ -349,7 +351,8 @@
"InvalidTarget": "Cannot resolve target.", "InvalidTarget": "Cannot resolve target.",
"ExportWalletTimeOut": "Export of wallet has expired.", "ExportWalletTimeOut": "Export of wallet has expired.",
"ConnectionError": "Could not connect to the server.", "ConnectionError": "Could not connect to the server.",
"IncompatibleQrCode": "You scanned a NextGraph QR-Code that is of the wrong type" "IncompatibleQrCode": "You scanned a NextGraph QR-Code that is of the wrong type.",
"NotARendezVous": "You scanned an invalid QR-Code."
}, },
"connectivity": { "connectivity": {
"stopped": "Stopped", "stopped": "Stopped",

@ -82,7 +82,7 @@
}); });
</script> </script>
<div class="text-center"> <div class="text-center max-w-4xl mx-auto">
<div> <div>
<h2 class="text-xl mb-6">{$t("pages.scan_qr.scanning")}</h2> <h2 class="text-xl mb-6">{$t("pages.scan_qr.scanning")}</h2>
</div> </div>

@ -28,6 +28,7 @@
Link, Link,
Camera, Camera,
CheckBadge, CheckBadge,
ExclamationTriangle,
} from "svelte-heros-v2"; } from "svelte-heros-v2";
import { onDestroy, onMount, tick } from "svelte"; import { onDestroy, onMount, tick } from "svelte";
import { Sidebar, SidebarGroup, SidebarWrapper } from "flowbite-svelte"; import { Sidebar, SidebarGroup, SidebarWrapper } from "flowbite-svelte";
@ -43,8 +44,7 @@
} from "../store"; } from "../store";
import { default as ng } from "../api"; import { default as ng } from "../api";
import CopyToClipboard from "../lib/components/CopyToClipboard.svelte";
let WebQRScannerClassPromise: Promise<typeof Html5QrcodeScanner>;
let tauri_platform = import.meta.env.TAURI_PLATFORM; let tauri_platform = import.meta.env.TAURI_PLATFORM;
let error; let error;
@ -55,12 +55,13 @@
let sub_menu: "scan_qr" | "generate_qr" | "text_code" | null = null; let sub_menu: "scan_qr" | "generate_qr" | "text_code" | null = null;
let generation_state: "loading" | "generated" | null = null; let generation_state: "before_start" | "loading" | "generated" =
let generated_qr: string | undefined = undefined; "before_start";
let generated_qr: string | undefined = undefined;
let generated_text_code: string | null = null; let generated_text_code: string | null = null;
let scanner_state: null | "scanned" | "success" = null; let scanner_state: "before_start" | "scanned" | "success" = "before_start";
async function scrollToTop() { async function scrollToTop() {
await tick(); await tick();
@ -85,19 +86,19 @@
async function open_gen_menu() { async function open_gen_menu() {
sub_menu = "generate_qr"; sub_menu = "generate_qr";
generation_state = null; generation_state = "before_start";
} }
function open_textcode_menu() { function open_textcode_menu() {
sub_menu = "text_code"; sub_menu = "text_code";
scanner_state = null; scanner_state = "before_start";
} }
async function generate_qr_code() { async function generate_qr_code() {
generation_state = "loading"; generation_state = "loading";
generated_qr = await ng.wallet_export_get_qrcode( generated_qr = await ng.wallet_export_get_qrcode(
$active_session.session_id, $active_session.session_id,
container.clientWidth Math.ceil(container.clientWidth * 0.9)
); );
generation_state = "generated"; generation_state = "generated";
} }
@ -129,7 +130,8 @@
sub_menu = null; sub_menu = null;
generated_qr = undefined; generated_qr = undefined;
generated_text_code = null; generated_text_code = null;
generation_state = null; generation_state = "before_start";
scanner_state = "before_start";
} }
let downloading = false; let downloading = false;
@ -399,7 +401,7 @@
<li <li
tabindex="0" tabindex="0"
role="menuitem" role="menuitem"
class="text-left flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700" class="mb-2 text-left flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={to_main_menu} on:keypress={to_main_menu}
on:click={to_main_menu} on:click={to_main_menu}
> >
@ -410,21 +412,23 @@
<span class="ml-3">{$t("buttons.back")}</span> <span class="ml-3">{$t("buttons.back")}</span>
</li> </li>
<!-- NOTES ABOUT QR--> {#if scanner_state === "before_start"}
<li class="text-left"> <!-- NOTES ABOUT QR-->
{@html $t("pages.wallet_info.scan_qr.notes")}
</li>
<!-- Warning if offline -->
{#if !$online}
<li class="text-left"> <li class="text-left">
<Alert color="red"> {@html $t("pages.wallet_info.scan_qr.notes")}
{@html $t("wallet_sync.offline_warning")} <br />
</Alert> {@html $t("wallet_sync.server_transfer_notice")}
</li> </li>
{/if}
{#if !scanner_state} <!-- Warning if offline -->
{#if !$online}
<li class="text-left">
<Alert color="red">
{@html $t("wallet_sync.offline_warning")}
</Alert>
</li>
{/if}
<Button <Button
on:click={open_scanner} on:click={open_scanner}
disabled={false || !$online} disabled={false || !$online}
@ -493,17 +497,15 @@
</li> </li>
{/if} {/if}
{#if !generated_qr || generation_state === "loading"} {#if generation_state === "before_start"}
<Button <Button
on:click={generate_qr_code} on:click={generate_qr_code}
disabled={generation_state === "loading" || !$online}
class="w-full text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" class="w-full text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
> >
{#if generation_state === "loading"}
<Spinner class="mr-2" size="6" />
{/if}
{$t("pages.wallet_info.gen_qr.gen_button")} {$t("pages.wallet_info.gen_qr.gen_button")}
</Button> </Button>
{:else if generation_state === "loading"}
<Spinner class="mx-auto" size="6" />
{:else} {:else}
<!-- QR Code --> <!-- QR Code -->
<div class="w-full"> <div class="w-full">
@ -534,8 +536,8 @@
<span class="ml-3">{$t("buttons.back")}</span> <span class="ml-3">{$t("buttons.back")}</span>
</li> </li>
<!-- Warning to better use QR codes or wallet downloads --> <!-- Warning to prefer QR codes or wallet downloads -->
<div class="text-left"> <div class="text-left my-4">
<Alert color="yellow"> <Alert color="yellow">
{@html $t("wallet_sync.textcode.usage_warning")} {@html $t("wallet_sync.textcode.usage_warning")}
</Alert> </Alert>
@ -543,35 +545,32 @@
<!-- Warning if offline --> <!-- Warning if offline -->
{#if !$online} {#if !$online}
<li class="text-left"> <li class="text-left my-4">
<Alert color="red"> <Alert color="red">
{@html $t("wallet_sync.offline_warning")} {@html $t("wallet_sync.offline_warning")}
</Alert> </Alert>
</li> </li>
{/if} {/if}
{#if generation_state !== "generated"} <div class="mt-4">
<Button {#if generation_state === "before_start"}
on:click={generate_text_code} <Button
disabled={generation_state === "loading" || !$online} on:click={generate_text_code}
class="w-full text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" disabled={!$online}
> class="my-4 w-full text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
{#if generation_state === "loading"} >
<Spinner class="mr-2" size="6" /> {$t("pages.wallet_info.gen_text_code.gen_btn")}
{/if} </Button>
{$t("pages.wallet_info.gen_text_code.gen_btn")} {:else if generation_state == "loading"}
</Button> <Spinner class="mx-auto" size="6" />
{:else} {:else}
<!-- TextCode Code --> <!-- TextCode Code -->
<div> <label>{$t("pages.wallet_info.gen_text_code.label")}</label>
<textarea <div>
rows="6" <CopyToClipboard rows={8} value={generated_text_code} />
value={generated_text_code} </div>
class="col-span-6 pr-11 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" {/if}
readonly </div>
/>
</div>
{/if}
</SidebarGroup> </SidebarGroup>
{/if} {/if}
</SidebarWrapper> </SidebarWrapper>
@ -579,48 +578,13 @@
</div> </div>
{#if error} {#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800"> <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg <ExclamationTriangle class="animate-bounce mt-10 h-16 w-16 mx-auto" />
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none" <p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
stroke="currentColor" {@html $t("errors.error_occurred", {
stroke-width="1.5" values: { message: display_error(error) },
viewBox="0 0 24 24" })}
xmlns="http://www.w3.org/2000/svg" </p>
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
{#if error == "AlreadyExists"}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.AlreadyExists")}
</p>
<a use:link href="/">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.login")}
</button>
</a>
{:else}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", {
values: { message: display_error(error) },
})}
</p>
<a use:link href="/">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.back_to_homepage")}
</button>
</a>
{/if}
</div> </div>
{/if} {/if}
</div> </div>

@ -36,7 +36,7 @@
display_error, display_error,
wallet_from_import, wallet_from_import,
} from "../store"; } from "../store";
import { CheckBadge, QrCode } from "svelte-heros-v2"; import { CheckBadge, ExclamationTriangle, QrCode } from "svelte-heros-v2";
let tauri_platform = import.meta.env.TAURI_PLATFORM; let tauri_platform = import.meta.env.TAURI_PLATFORM;
@ -113,8 +113,8 @@
} }
function start_login_from_import() { function start_login_from_import() {
// Login button clicked, `wallet` is was set onMount. // Login button was clicked and `wallet` was set in `onMount`.
// Unset, to show login screen. // Unset variable from store, to show login screen.
wallet_from_import.set(null); wallet_from_import.set(null);
} }
@ -218,21 +218,7 @@
<CenteredLayout displayFooter={!wallet}> <CenteredLayout displayFooter={!wallet}>
{#if error} {#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800"> <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg <ExclamationTriangle class="animate-bounce mt-10 h-16 w-16 mx-auto" />
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5"> <p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", { {@html $t("errors.error_occurred", {
@ -260,35 +246,40 @@
</h2> </h2>
</div> </div>
<CheckBadge class="w-full h-6" /> <span class="text-green-800">
<CheckBadge class="w-full mt-4" size="3em" />
<div> <div class="mt-4">
{@html $t("pages.wallet_login.from_import.description")} {@html $t("pages.wallet_login.from_import.description")}
</div> </div>
</span>
<!-- Show wallet security image and phrase. --> <!-- Show wallet security image and phrase. -->
<!--
<div <div
class="wallet-box" class="wallet-box mt-4 mx-auto"
role="button" role="button"
tabindex="0" tabindex="0"
title={$wallet_from_import[0]} on:click={start_login_from_import}
on:keypress={start_login_from_import}
> >
<span class="securitytxt" <span class="securitytxt"
>{$wallet_from_import[1].wallet.V0.content.security_txt} >{$wallet_from_import.V0.content.security_txt}
</span> </span>
<img <img
alt={$wallet_from_import[1].wallet.V0.content.security_txt} alt={$wallet_from_import.V0.content.security_txt}
class="securityimg" class="securityimg"
src={convert_img_to_url( src={convert_img_to_url($wallet_from_import.V0.content.security_img)}
$wallet_from_import[1].wallet.V0.content.security_img
)}
/> />
</div> </div>
-->
<!-- Login to finish import instructions-->
<div class="my-4">
{@html $t("pages.wallet_login.from_import.instruction")}
</div>
<div> <div>
<button <button
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2" class="mt-4 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2"
on:click={start_login_from_import} on:click={start_login_from_import}
> >
{$t("buttons.login")} {$t("buttons.login")}
@ -313,7 +304,6 @@
class="wallet-box" class="wallet-box"
role="button" role="button"
tabindex="0" tabindex="0"
title={wallet_entry[0]}
on:click={() => { on:click={() => {
select(wallet_entry[0]); select(wallet_entry[0]);
}} }}

@ -1,7 +1,12 @@
<script lang="ts"> <script lang="ts">
import { t } from "svelte-i18n"; import { t } from "svelte-i18n";
import { Alert, Modal, Spinner } from "flowbite-svelte"; import { Alert, Modal, Spinner } from "flowbite-svelte";
import { ArrowLeft, Camera, QrCode } from "svelte-heros-v2"; import {
ArrowLeft,
Camera,
ExclamationTriangle,
QrCode,
} from "svelte-heros-v2";
import { onDestroy, onMount } from "svelte"; import { onDestroy, onMount } from "svelte";
import { push } from "svelte-spa-router"; import { push } from "svelte-spa-router";
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
@ -41,7 +46,7 @@
} catch { } catch {
has_camera = false; has_camera = false;
} }
has_camera = false;
login_method = has_camera ? "scan" : "gen"; login_method = has_camera ? "scan" : "gen";
} else { } else {
// TODO: There does not seem to be an API for checking, if the native device // TODO: There does not seem to be an API for checking, if the native device
@ -68,7 +73,7 @@
gen_state = "generating"; gen_state = "generating";
try { try {
const [qr_code_el, code] = await ng.wallet_import_rendezvous( const [qr_code_el, code] = await ng.wallet_import_rendezvous(
top.clientWidth Math.ceil(top.clientWidth * 0.9)
); );
rendezvous_code = code; rendezvous_code = code;
qr_code_html = qr_code_el; qr_code_html = qr_code_el;
@ -127,11 +132,15 @@
</Alert> </Alert>
</div> </div>
{:else if error} {:else if error}
<Alert color="red"> <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
{@html $t("wallet_sync.error", { <ExclamationTriangle class="animate-bounce mt-10 h-16 w-16 mx-auto" />
values: { error: display_error(error) },
})} <p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
</Alert> {@html $t("errors.error_occurred", {
values: { message: display_error(error) },
})}
</p>
</div>
{:else if login_method === "scan"} {:else if login_method === "scan"}
{#if scan_state === "before_start"} {#if scan_state === "before_start"}
<!-- Scan Mode --> <!-- Scan Mode -->
@ -168,7 +177,7 @@
</div> </div>
<!-- Generated QR Code --> <!-- Generated QR Code -->
<div> <div class="my-4 my-auto">
{@html qr_code_html} {@html qr_code_html}
</div> </div>
{/if} {/if}

@ -4,31 +4,33 @@
import { import {
ArrowLeft, ArrowLeft,
ArrowRightCircle, ArrowRightCircle,
Camera, CheckCircle,
CheckBadge, ExclamationTriangle,
QrCode,
} from "svelte-heros-v2"; } from "svelte-heros-v2";
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
import { onMount } from "svelte"; import { display_error, wallet_from_import } from "../store";
import { push } from "svelte-spa-router"; import { push } from "svelte-spa-router";
import { online, scanned_qr_code } from "../store"; import ng from "../api";
let top; let top;
let gen_state: let error;
| "before_start" let state: "importing" | null = null;
| "generating"
| "generated"
| "success"
| Error = "before_start";
let textcode: string | undefined = undefined; let textcode: string | undefined = undefined;
// TODO: Check connectivity to sync service. // TODO: Check connectivity to sync service.
let connected = true; let connected = true;
const textcode_submit = () => { const textcode_submit = async () => {
scanned_qr_code.set(textcode); state = "importing";
window.history.go(-1); try {
const imported_wallet = await ng.wallet_import_from_code(textcode);
wallet_from_import.set(imported_wallet);
// Login in with imported wallet.
push("#/wallet/login");
} catch (e) {
error = e;
}
}; };
</script> </script>
@ -42,7 +44,7 @@
<h2 class="text-xl mb-6">{$t("pages.wallet_login_textcode.title")}</h2> <h2 class="text-xl mb-6">{$t("pages.wallet_login_textcode.title")}</h2>
</div> </div>
<div class="text-left"> <div class="text-left my-4">
<Alert color="yellow"> <Alert color="yellow">
{@html $t("wallet_sync.textcode.usage_warning")} {@html $t("wallet_sync.textcode.usage_warning")}
</Alert> </Alert>
@ -58,7 +60,7 @@
{/if} {/if}
<!-- Notes about TextCode entering --> <!-- Notes about TextCode entering -->
<div class="text-left text-sm mb-4"> <div class="text-left text-sm mt-4">
{@html $t("pages.wallet_login_textcode.description")} {@html $t("pages.wallet_login_textcode.description")}
<br /> <br />
{@html $t("wallet_sync.server_transfer_notice")} {@html $t("wallet_sync.server_transfer_notice")}
@ -68,9 +70,24 @@
<textarea <textarea
rows="6" rows="6"
bind:value={textcode} bind:value={textcode}
class="col-span-6 pr-11 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" disabled={state === "importing"}
class="my-4 col-span-6 pr-11 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500"
/> />
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<ExclamationTriangle class="animate-bounce mt-10 h-16 w-16 mx-auto" />
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", {
values: { message: display_error(error) },
})}
</p>
</div>
{:else if state === "importing"}
<Spinner class="mx-auto" />
{/if}
<div class="mx-auto"> <div class="mx-auto">
<!-- Submit Button--> <!-- Submit Button-->
<div class="my-4 mx-1"> <div class="my-4 mx-1">
@ -78,8 +95,9 @@
class="mt-4 w-full text-white bg-primary-700 disabled:bg-primary-700/50 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" class="mt-4 w-full text-white bg-primary-700 disabled:bg-primary-700/50 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
on:click={textcode_submit} on:click={textcode_submit}
disabled={!connected || !textcode} disabled={!connected || !textcode}
class:hidden={state === "importing" || error}
> >
<ArrowRightCircle <CheckCircle
tabindex="-1" tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white" class="w-8 h-8 mr-2 -ml-1 transition duration-75 focus:outline-none group-hover:text-gray-900 dark:group-hover:text-white"
/> />

Loading…
Cancel
Save