diff --git a/ng-app/src/locales/en.json b/ng-app/src/locales/en.json index 0508f03..66d1e95 100644 --- a/ng-app/src/locales/en.json +++ b/ng-app/src/locales/en.json @@ -12,7 +12,6 @@ "personal": "Personal" }, "user_registered": { - "back_to_homepage": "Go Back to Homepage", "success": "You have been successfully registered.", "success_with_invitation": "You have been successfully registered to {invitation_name}." }, @@ -28,6 +27,7 @@ "remove_wallet": "Remove wallet from Device", "remove_wallet_modal.title": "Remove wallet?", "remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?", + "create_text_code": "Generate TextCode to export", "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.
.", "scan_qr.scan_btn": "Scan QR Code ", @@ -39,7 +39,9 @@ "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_alt": "Your Export QR Code to Scan", - "gen_qr.gen_button": "Display QR Code" + "gen_qr.gen_button": "Display QR Code", + "gen_text_code.title": "Export with TextCode", + "gen_text_code.gen_btn": "Generate TextCode" }, "settings": { "title": "Settings" @@ -115,7 +117,6 @@ "qr_code": "Wallet QRCode", "qr_modal_title": "My Wallet QRCode", "qr_modal_description": "Use this QRCode to log in with your wallet on new devices.", - "copy_wallet_link": "Copy Wallet Link", "keep_wallet": "Save to Device for Future Logins" }, "account_info": { @@ -239,6 +240,8 @@ }, "wallet_login": { "select_wallet": "Select a wallet to login with", + "from_import.title": "Your wallet has been transferred", + "from_import.description": "Your wallet has been transferred!
To finish the import, please log in.", "with_another_wallet": "Log in with another wallet", "import_wallet": "Import your wallet", "import_file": "Import a Wallet File", @@ -366,7 +369,7 @@ }, "wallet_sync": { "offline_warning": "You cannot transfer your wallet when offline.
Please make sure, you are connected first.", - "textcode.usage_warning": "You have to exchange this TextCode with the other device by any means available to you (email, other messenger apps, etc...). It is highly recommended to use a tool that is end-to-end encrypted. If you can, you should use instead the \"Import with QRCode\" option, as it is safer. If your devices are not connected to the internet, then you can use the \"Import a Wallet File\" option. In this case, you will transfer the wallet file with a USB key, from one device to the other, or for mobile, by connecting your mobile with the USB cable, to the computer, and then transferring the file with the File Transfer utility on Android, or AirDrop/Finder/iTunes on an iPhone/mac/PC. We do not recommend uploading your wallet file to any cloud service.", + "textcode.usage_warning": "You have to exchange this TextCode with the other device by any means available to you (email, other messenger apps, etc...). It is highly recommended to use a tool that is end-to-end encrypted. If you can, you should use the \"Import with QRCode\" option instead, as it is safer. If your devices are not connected to the internet, then you can use the \"Import a Wallet File\" option. In this case, you will transfer the wallet file with a USB key, from one device to the other, or for mobile, by connecting your mobile with the USB cable, to the computer, and then transferring the file with the File Transfer utility on Android, or AirDrop/Finder/iTunes on an iPhone/mac/PC. We do not recommend uploading your wallet file to any cloud service.", "server_transfer_notice": "Both devices need to be online.
During this wallet import, your wallet will be temporarily and securely stored on our servers for up to 5 minutes, using two levels of encryption.", "importing": "Importing wallet", "error": "An error occurred while synchronizing your wallet:
{error}" diff --git a/ng-app/src/routes/WalletCreate.svelte b/ng-app/src/routes/WalletCreate.svelte index 7b0a28f..1dde17e 100644 --- a/ng-app/src/routes/WalletCreate.svelte +++ b/ng-app/src/routes/WalletCreate.svelte @@ -44,7 +44,7 @@ } from "../wallet_emojis"; import { onMount, onDestroy, tick } from "svelte"; - import { wallets, set_active_session, has_wallets, display_error } from "../store"; + import { wallets, has_wallets, display_error } from "../store"; import Spinner from "../lib/components/Spinner.svelte"; const param = new URLSearchParams($querystring); @@ -223,7 +223,6 @@ } async function save_security() { - device_name = await ng.get_device_name(); options = { trusted: true, @@ -583,7 +582,7 @@ 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("bottons.back_to_homepage")} + {$t("buttons.back_to_homepage")} {/if} @@ -1442,9 +1441,7 @@ id="device-name-input" class="mt-2 bg-gray-50 border border-gray-300 text-xs 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-white dark:focus:ring-blue-500 dark:focus:border-blue-500" bind:value={device_name} - placeholder={$t( - "pages.login.device_name_placeholder" - )} + placeholder={$t("pages.login.device_name_placeholder")} type="text" /> {/if} diff --git a/ng-app/src/routes/WalletInfo.svelte b/ng-app/src/routes/WalletInfo.svelte index 0af73ae..db8e52e 100644 --- a/ng-app/src/routes/WalletInfo.svelte +++ b/ng-app/src/routes/WalletInfo.svelte @@ -26,17 +26,12 @@ NoSymbol, QrCode, Link, - ArrowDownOnSquare, Camera, CheckBadge, } from "svelte-heros-v2"; import { onMount, tick } from "svelte"; import { Sidebar, SidebarGroup, SidebarWrapper } from "flowbite-svelte"; import { t } from "svelte-i18n"; - import { - type Html5QrcodeResult, - type Html5QrcodeScanner, - } from "html5-qrcode"; import { close_active_wallet, @@ -44,6 +39,7 @@ active_wallet, display_error, online, + scanned_qr_code, } from "../store"; import { default as ng } from "../api"; @@ -55,47 +51,36 @@ let nonActiveClass = "flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"; - let top; + let container: HTMLElement; let sub_menu: "scan_qr" | "generate_qr" | "text_code" | null = null; - /** QR source / blob URL */ let generation_state: "loading" | "generated" | null = null; let generated_qr: string | undefined = undefined; let generated_text_code: string | null = null; - // TODO: do that only when needed // generated_text_code = await ng.wallet_export_get_textcode($active_session.session_id); - - let scanner_open = false; - let scanned_qr = null; - let scan_successful: null | true = null; - - let html5QrcodeScanner: Html5QrcodeScanner; - async function load_qr_scanner_lib() { - // Load in browser only - if (!tauri_platform && !WebQRScannerClassPromise) { - WebQRScannerClassPromise = new Promise((resolve) => { - import("html5-qrcode").then((lib) => resolve(lib.Html5QrcodeScanner)); - }); - } - // TODO: Load alternative for native apps? - } + + let scanner_state: null | "scanned" | "success" = null; async function scrollToTop() { await tick(); - top.scrollIntoView(); + container.scrollIntoView(); } onMount(async () => { if (!$active_session) { push("#/"); - } else { - await scrollToTop(); + return; + } + if ($scanned_qr_code) { + sub_menu = "scan_qr"; + on_qr_scanned($scanned_qr_code); + scanned_qr_code.set(""); } + await scrollToTop(); }); function open_scan_menu() { sub_menu = "scan_qr"; - load_qr_scanner_lib(); } async function open_gen_menu() { @@ -103,70 +88,48 @@ generation_state = null; } - async function gen_qr() { - generation_state = "loading"; // TODO: @niko = await ng.generate_export_qr(); - // ToRemove: - setTimeout(() => { - generation_state = "generated"; - generated_qr = "dummy"; - // TODO: generated_qr = await ng.wallet_export_get_qrcode($active_session.session_id, 250); - }, 3000); + function open_textcode_menu() { + sub_menu = "text_code"; + scanner_state = null; + } + + async function generate_qr_code() { + generation_state = "loading"; + generated_qr = await ng.wallet_export_get_qrcode( + $active_session.session_id, + container.clientWidth + ); + generation_state = "generated"; } async function on_qr_scanned(text: string) { - scanned_qr = text; - // TODO: API calls for synchronization @niko - // - // example : - // try { - // await ng.wallet_export_rendezvous($active_session.session_id, text); - // } catch (e) { - // console.error(e); - // } - // ToRemove: - setTimeout(() => { - scan_successful = true; - }, 2_000); + try { + await ng.wallet_export_rendezvous($active_session.session_id, text); + scanner_state = "success"; + } catch (e) { + error = e; + } } async function open_scanner() { - scanner_open = true; - - const onScanSuccess = ( - decoded_text: string, - decoded_result: Html5QrcodeResult - ) => { - // handle the scanned code as you like, for example: - on_qr_scanned(decoded_text); - close_scanner(); - // console.log(`Code matched = ${decoded_text}`, decodedResult); - }; - - const WebQRScanner = await WebQRScannerClassPromise; - html5QrcodeScanner = new WebQRScanner( - "scanner-div", - { fps: 10, qrbox: { width: 300, height: 300 }, formatsToSupport: [0] }, - false - ); - html5QrcodeScanner.render(onScanSuccess, undefined); - - // Auto-Request camera permissions (there's no native way, unfortunately...) - setTimeout(() => { - // Auto-start by clicking button - document.getElementById("html5-qrcode-button-camera-permission")?.click(); - }, 100); + push("#/wallet/scanqr"); } - function close_scanner() { - scanner_open = false; - if (html5QrcodeScanner) html5QrcodeScanner.clear(); - html5QrcodeScanner = null; + async function generate_text_code() { + generation_state = "loading"; + generated_text_code = await ng.wallet_export_get_textcode( + $active_session.session_id + ); + generation_state = "generated"; } function to_main_menu() { + // TODO: Destroy QR- or TextCode + sub_menu = null; - generated_qr = "loading"; + generated_qr = undefined; generated_text_code = null; + generation_state = null; } let downloading = false; @@ -211,8 +174,8 @@ -
-
+
+
{/if} + + +
  • - - - {#if false} - - {/if} - - - {#if false} - - {/if} {:else if sub_menu === "scan_qr"} @@ -467,49 +416,33 @@ {/if} - {#if scan_successful} -
  • -
    - -
    -
    - {@html $t("pages.wallet_info.scan_qr.scan_successful")} -
    -
  • - {:else if scanned_qr} + {#if !scanner_state} + + {:else if scanner_state === "scanned"}
  • {@html $t("pages.wallet_info.scan_qr.syncing")}...

    - {scanned_qr} + {scanned_qr_code}
  • - {:else if !scanner_open} - - {:else} - - -
    - {$t("pages.wallet_info.scan_qr.scanner.loading")}... + {:else if scanner_state === "success"} +
  • +
    + +
    +
    + {@html $t("pages.wallet_info.scan_qr.scan_successful")}
    - +
  • {/if} @@ -540,7 +473,7 @@
  • {@html $t("pages.wallet_info.gen_qr.notes")}
    - {@html $t("wallet_sync.transfer_notice")} + {@html $t("wallet_sync.server_transfer_notice")}
  • @@ -554,7 +487,7 @@ {#if !generated_qr || generation_state === "loading"} {:else} -
    - {#if generated_qr === "dummy"} -
    - -
    - {:else} - {@html generated_qr} - - - {/if} +
    + {@html generated_qr}
    {/if} {:else if sub_menu === "text_code"} - TODO: Export with text code + +
  • +

    + {$t("pages.wallet_info.gen_text_code.title")} +

    +
  • + + + + + +
    + + {@html $t("wallet_sync.textcode.usage_warning")} + +
    + + + {#if !$online} +
  • + + {@html $t("wallet_sync.offline_warning")} + +
  • + {/if} + + {#if generation_state !== "generated"} + + {:else} + +
    +