add navigation buttons for wallet login

pull/18/head
Laurin Weger 3 months ago
parent 0c7c4baa9b
commit b6c2b40f14
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 647
      ng-app/src/lib/Login.svelte

@ -9,12 +9,22 @@
// according to those terms. // according to those terms.
--> -->
<!--
The Login Procedure.
Has multiple states (steps) through the user flow.
-->
<script lang="ts"> <script lang="ts">
import { Alert, Toggle } from "flowbite-svelte"; import { Alert, Toggle } from "flowbite-svelte";
import { onMount, createEventDispatcher, tick } from "svelte"; import { onMount, createEventDispatcher, tick } from "svelte";
import ng from "../api"; import ng from "../api";
import { emoji_cat, emojis, load_svg } from "../wallet_emojis"; import { emoji_cat, emojis, load_svg } from "../wallet_emojis";
import { PuzzlePiece } from "svelte-heros-v2"; import {
PuzzlePiece,
XCircle,
ArrowLeftCircle,
ArrowPath,
} from "svelte-heros-v2";
//import Worker from "../worker.js?worker&inline"; //import Worker from "../worker.js?worker&inline";
export let wallet; export let wallet;
export let for_import = false; export let for_import = false;
@ -46,7 +56,7 @@
} }
emojis2 = emojis2; emojis2 = emojis2;
display = 0; pazzlePage = 0;
selection = []; selection = [];
error = undefined; error = undefined;
@ -68,9 +78,9 @@
let pazzle_length = 9; let pazzle_length = 9;
let display = 0; let pazzlePage = 0;
let selection = []; let selection = [].fill(null, 0, pazzle_length);
let pin_code = []; let pin_code = [];
@ -88,6 +98,10 @@
step = "order"; step = "order";
ordered = []; ordered = [];
last_one = {}; last_one = {};
// In case, this is called by the cancel button, we need to reset the selection.
selection.forEach((emoji) => (emoji.sel = undefined));
selection = selection;
for (let i = 0; i < pazzle_length; i++) { for (let i = 0; i < pazzle_length; i++) {
last_one[i] = true; last_one[i] = true;
} }
@ -101,20 +115,21 @@
//console.log(shuffle_pin); //console.log(shuffle_pin);
} }
/** Called on selecting emoji in a category. */
function select(val) { function select(val) {
//console.log(emojis2[display][val]); //console.log(emojis2[display][val]);
let cat_idx = shuffle.category_indices[display]; let cat_idx = shuffle.category_indices[pazzlePage];
let cat = emojis[emoji_cat[cat_idx]]; let cat = emojis[emoji_cat[cat_idx]];
let idx = shuffle.emoji_indices[display][val]; let idx = shuffle.emoji_indices[pazzlePage][val];
//console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); //console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code);
selection.push({ cat: cat_idx, index: idx }); selection[pazzlePage] = { cat: cat_idx, index: idx };
//console.log(selection); console.debug(selection, cat, cat_idx, idx, val);
if (display == pazzle_length - 1) { if (pazzlePage == pazzle_length - 1) {
order(); order();
} else { } else {
display = display + 1; pazzlePage = pazzlePage + 1;
} }
} }
@ -214,7 +229,11 @@
dispatch("cancel"); dispatch("cancel");
} }
async function pin(val) { function to_previous_pazzle() {
pazzlePage = pazzlePage - 1;
}
async function on_pin_key(val) {
//console.log(val); //console.log(val);
pin_code.push(val); pin_code.push(val);
if (pin_code.length == 4) { if (pin_code.length == 4) {
@ -224,8 +243,8 @@
async function select_order(val, pos) { async function select_order(val, pos) {
delete last_one[pos]; delete last_one[pos];
//console.log(last_one); console.debug(last_one, val);
//console.log(val);
ordered.push(val); ordered.push(val);
val.sel = ordered.length; val.sel = ordered.length;
selection = selection; selection = selection;
@ -240,50 +259,297 @@
} }
</script> </script>
{#if step == "load"} <div>
<div class=" max-w-xl lg:px-8 mx-auto px-4 mt-10"> {#if step == "load"}
<h2 class="pb-5 text-xl">How to open your wallet, step by step :</h2> <div class=" max-w-xl lg:px-8 mx-auto px-4 mt-10">
<ul class="mb-8 ml-3 space-y-4 text-left list-decimal"> <h2 class="pb-5 text-xl">How to open your wallet, step by step :</h2>
<li> <ul class="mb-8 ml-3 space-y-4 text-left list-decimal">
For each one of the 9 categories of images, you will be presented with <li>
the 15 possible image choices. The categories are shuffled at every For each one of the 9 categories of images, you will be presented with
login. They will not always appear in the same order. the 15 possible image choices. The categories are shuffled at every
</li> login. They will not always appear in the same order.
<li> </li>
At each category, only one of the 15 displayed choices is the correct <li>
image that belongs to your pazzle. Find it and tap or click on that one. At each category, only one of the 15 displayed choices is the correct
The 15 images are shuffled too, they will not appear at the same image that belongs to your pazzle. Find it and tap or click on that
position at each login. On a computer, you can also use the tab key on one. The 15 images are shuffled too, they will not appear at the same
your keyboard to move to the desired item on the screen, then press the position at each login. On a computer, you can also use the tab key on
space bar to select each one. your keyboard to move to the desired item on the screen, then press
</li> the space bar to select each one.
<li> </li>
Once you completed the last category, you will be presented with all the <li>
images you have previously selected. Their order is displayed as it was Once you completed the last category, you will be presented with all
when you picked them. But this is not the correct order of the images in the images you have previously selected. Their order is displayed as
your pazzle. You now have to order them correctly. it was when you picked them. But this is not the correct order of the
</li> images in your pazzle. You now have to order them correctly.
<li> </li>
You must remember which image should be the first one in your pazzle. <li>
Find it on the screen and click or tap on it. It will be greyed out and You must remember which image should be the first one in your pazzle.
the number 1 will appear on top of it. Find it on the screen and click or tap on it. It will be greyed out
</li> and the number 1 will appear on top of it.
<li> </li>
Move on to the second image of your pazzle (that you memorized). Find it <li>
on the screen and tap on it. Repeat this step until you reached the last Move on to the second image of your pazzle (that you memorized). Find
image. it on the screen and tap on it. Repeat this step until you reached the
</li> last image.
<li> </li>
Finally, your PIN code will be asked. enter it by clicking or tapping on <li>
the digits. Finally, your PIN code will be asked. enter it by clicking or tapping
</li> on the digits.
</ul> </li>
</div> </ul>
<div class=" max-w-xl lg:px-8 mx-auto px-4 text-primary-700"> </div>
{#if !loaded} <div class=" max-w-xl lg:px-8 mx-auto px-4 text-primary-700">
Loading pazzle... {#if !loaded}
Loading pazzle...
<svg
class="animate-spin my-4 h-14 w-14 mx-auto"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
/>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
{:else}
<div class="flex justify-center space-x-12 mt-4 mb-4">
<button
on:click={letsgo}
class="mt-1 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 mb-2"
>
<PuzzlePiece
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>
Open my wallet now!
</button>
<button
on:click={cancel}
class="mt-1 bg-red-100 hover:bg-red-100/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 mb-2"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Cancel</button
>
</div>
{/if}
</div>
{#if for_import}
<div class=" max-w-xl lg:px-8 mx-auto px-4 mb-8">
<span class="text-xl">Do you trust this device? </span> <br />
<div class="flex justify-center items-center my-4">
<Toggle class="" bind:checked={trusted}
>Yes, save my wallet on this device</Toggle
>
</div>
<p class="text-sm">
If you do, if this device is yours or is used by few trusted persons
of your family or workplace, and you would like to login again from
this device in the future, then you can save your wallet on this
device. To the contrary, if this device is public and shared by
strangers, do not save your wallet here. {#if !tauri_platform}By
selecting this option, you agree to save some cookies on your
browser.{/if}<br />
</p>
</div>
{/if}
{:else if step == "pazzle"}
<div
class="flex flex-col justify-center h-screen p-4 pazzleline"
class:min-w-[310px]={mobile}
class:min-w-[500px]={!mobile}
class:max-w-[360px]={mobile}
class:max-w-[600px]={!mobile}
>
<div class="mt-auto">
{#each [0, 1, 2, 3, 4] as row}
<div class="columns-3 gap-0">
{#each emojis2[pazzlePage]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i (pazzlePage + "-" + row + "-" + i)}
<div
role="button"
tabindex="0"
class="w-full aspect-square emoji focus:outline-none focus:bg-gray-300"
on:click={() => select(row * 3 + i)}
on:keypress={() => select(row * 3 + i)}
>
<svelte:component this={emoji.svg?.default} />
</div>
{/each}
</div>
{/each}
</div>
<div class="flex justify-between mt-auto">
<button
class="mt-1 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={pazzlePage === 0 ? init : to_previous_pazzle}
><ArrowLeftCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Go Back</button
>
<button
on:click={cancel}
class="mt-1 bg-red-100 hover:bg-red-100/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 mb-2"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Cancel</button
>
</div>
</div>
{:else if step == "order"}
<!-- console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); -->
<div
class="flex flex-col justify-center h-screen p-4"
class:min-w-[310px]={mobile}
class:min-w-[500px]={!mobile}
class:max-w-[360px]={mobile}
class:max-w-[600px]={!mobile}
>
<div class="mt-auto">
{#each [0, 1, 2] as row}
<div class="columns-3 gap-0">
{#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i}
{#if !emoji.sel}
<div
role="button"
tabindex="0"
class="w-full aspect-square emoji focus:outline-none focus:bg-gray-300"
on:click={() => select_order(emoji, row * 3 + i)}
on:keypress={() => select_order(emoji, row * 3 + i)}
>
<svelte:component
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg
?.default}
/>
</div>
{:else}
<div
class="w-full aspect-square opacity-25 select-none sel-emoji"
>
<svelte:component
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg
?.default}
/>
<span
class="sel drop-shadow-[2px_2px_2px_rgba(255,255,255,1)]"
>{emoji.sel}</span
>
</div>
{/if}
{/each}
</div>
{/each}
</div>
<div class="flex justify-between mt-auto">
<button
class="mt-1 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={() => (step = "pazzle")}
>
<ArrowLeftCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>
Go Back</button
>
<button
class="mt-1 bg-yellow-100 hover:bg-yellow-100/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={order}
><ArrowPath
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Clear</button
>
<button
on:click={cancel}
class="mt-1 bg-red-100 hover:bg-red-100/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 mb-2"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Cancel</button
>
</div>
</div>
{:else if step == "pin"}
<div
class="flex flex-col justify-center h-screen p-4"
class:min-w-[310px]={mobile}
class:min-w-[500px]={!mobile}
class:max-w-[360px]={mobile}
class:max-w-[600px]={!mobile}
>
<div class="max-w-6xl lg:px-8 mt-auto px-3">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-xl">Enter your PIN code</span>
</p>
<div class="w-[295px] mx-auto">
{#each [0, 1, 2] as row}
<div class="">
{#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await on_pin_key(num)}
>
<span>{num}</span>
</button>
{/each}
</div>
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await on_pin_key(shuffle_pin[9])}
>
<span>{shuffle_pin[9]}</span>
</button>
</div>
</div>
<div class="flex justify-between mt-auto">
<button
class="mt-1 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={order}
><ArrowLeftCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Go Back</button
>
<button
class="mt-1 bg-yellow-100 hover:bg-yellow-100/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={start_pin}
><ArrowPath
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Clear</button
>
<button
on:click={cancel}
class="mt-1 bg-red-100 hover:bg-red-100/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 mb-2"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Cancel</button
>
</div>
</div>
{:else if step == "opening"}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
Opening your wallet...<br />
Please wait
<svg <svg
class="animate-spin my-4 h-14 w-14 mx-auto" class="animate-spin mt-10 h-14 w-14 mx-auto"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -303,199 +569,66 @@
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/> />
</svg> </svg>
{:else}
<button
on:click={letsgo}
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/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"
>
<PuzzlePiece
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>
Open my wallet now!
</button>
{/if}
</div>
{#if for_import}
<div class=" max-w-xl lg:px-8 mx-auto px-4 mb-8">
<span class="text-xl">Do you trust this device? </span> <br />
<div class="flex justify-center items-center my-4">
<Toggle class="" bind:checked={trusted}
>Yes, save my wallet on this device</Toggle
>
</div>
<p class="text-sm">
If you do, if this device is yours or is used by few trusted persons of
your family or workplace, and you would like to login again from this
device in the future, then you can save your wallet on this device. To
the contrary, if this device is public and shared by strangers, do not
save your wallet here. {#if !tauri_platform}By selecting this option,
you agree to save some cookies on your browser.{/if}<br />
</p>
</div> </div>
{/if} {:else if step == "end"}
{:else if step == "pazzle"} {#if error}
<div <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
class="h-screen aspect-[3/5] pazzleline" An error occurred !
class:min-w-[310px]={mobile} <svg
class:min-w-[500px]={!mobile} fill="none"
class:max-w-[360px]={mobile} class="animate-bounce mt-10 h-10 w-10 mx-auto"
class:max-w-[600px]={!mobile} stroke="currentColor"
> stroke-width="1.5"
{#each [0, 1, 2, 3, 4] as row} viewBox="0 0 24 24"
<div class="columns-3 gap-0"> xmlns="http://www.w3.org/2000/svg"
{#each emojis2[display]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} aria-hidden="true"
<div >
role="button" <path
tabindex="0" stroke-linecap="round"
class="w-full aspect-square emoji focus:outline-none focus:bg-gray-300" stroke-linejoin="round"
on:click={() => select(row * 3 + i)} 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"
on:keypress={() => select(row * 3 + i)} />
> </svg>
<svelte:component this={emoji.svg?.default} /> <Alert color="red" class="mt-5">
</div> {error}
{/each} </Alert>
<button
class="mt-10 select-none 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"
on:click={init}
>
Try again
</button>
<button
on:click={cancel}
class="mt-1 bg-red-100 hover:bg-red-100/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 mb-2"
><XCircle
tabindex="-1"
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white"
/>Cancel</button
>
</div> </div>
{/each} {:else}
</div> <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-green-800">
{:else if step == "order"} Your wallet is opened! <br />Please wait while the app is loading...
<!-- console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); --> <svg
<div class="my-10 h-16 w-16 mx-auto"
class="h-screen aspect-[3/3] pazzleline" fill="none"
class:min-w-[320px]={mobile} stroke="currentColor"
class:min-w-[500px]={!mobile} stroke-width="1.5"
class:max-w-[360px]={mobile} viewBox="0 0 24 24"
class:max-w-[600px]={!mobile} xmlns="http://www.w3.org/2000/svg"
> aria-hidden="true"
{#each [0, 1, 2] as row} >
<div class="columns-3 gap-0"> <path
{#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} stroke-linecap="round"
{#if !emoji.sel} stroke-linejoin="round"
<div d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
role="button" />
tabindex="0" </svg>
class="w-full aspect-square emoji focus:outline-none focus:bg-gray-300"
on:click={() => select_order(emoji, row * 3 + i)}
on:keypress={() => select_order(emoji, row * 3 + i)}
>
<svelte:component
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg?.default}
/>
</div>
{:else}
<div class="w-full aspect-square opacity-25 select-none sel-emoji">
<svelte:component
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg?.default}
/>
<span class="sel drop-shadow-[2px_2px_2px_rgba(255,255,255,1)]"
>{emoji.sel}</span
>
</div>
{/if}
{/each}
</div> </div>
{/each} {/if}
</div>
{:else if step == "pin"}
<div class=" max-w-6xl lg:px-8 mx-auto px-3">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-xl">Enter your PIN code</span>
</p>
<div class="w-[295px] mx-auto">
{#each [0, 1, 2] as row}
<div class="">
{#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await pin(num)}
>
<span>{num}</span>
</button>
{/each}
</div>
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await pin(shuffle_pin[9])}
>
<span>{shuffle_pin[9]}</span>
</button>
</div>
</div>
{:else if step == "opening"}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
Opening your wallet...<br />
Please wait
<svg
class="animate-spin mt-10 h-14 w-14 mx-auto"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
/>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
</div>
{:else if step == "end"}
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
An error occurred !
<svg
fill="none"
class="animate-bounce mt-10 h-10 w-10 mx-auto"
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>
<Alert color="red" class="mt-5">
{error}
</Alert>
<button class="mt-10 select-none" on:click={init}> Try again </button>
<button class="mt-10 ml-5 select-none" on:click={cancel}> Cancel </button>
</div>
{:else}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-green-800">
Your wallet is opened! <br />Please wait while the app is loading...
<svg
class="my-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="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
/>
</svg>
</div>
{/if} {/if}
{/if} </div>
<style> <style>
.pazzleline { .pazzleline {
@ -524,4 +657,28 @@
border: 0; border: 0;
box-shadow: none; */ box-shadow: none; */
} }
.scale-to-fit {
/* Use the smaller of viewport width or height to maintain aspect ratio */
/* width: 100vw; */
/* height: 100vh; */
max-width: calc(100vh * (3 / 5)); /* Adjust the ratio to fit your needs */
max-height: calc(100vw * (5 / 3)); /* Inverse of the above ratio */
display: flex;
flex-direction: column;
justify-content: center;
}
/* Additional styles for responsiveness */
@media (orientation: landscape) {
.scale-to-fit {
max-width: calc(100vh * (3 / 5));
}
}
@media (orientation: portrait) {
.scale-to-fit {
max-height: calc(100vw * (5 / 3));
}
}
</style> </style>

Loading…
Cancel
Save