From b6c2b40f149d3723e8750c5b07797b5dfc03fe18 Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Thu, 27 Jun 2024 11:59:58 +0200 Subject: [PATCH 01/29] add navigation buttons for wallet login --- ng-app/src/lib/Login.svelte | 647 ++++++++++++++++++++++-------------- 1 file changed, 402 insertions(+), 245 deletions(-) diff --git a/ng-app/src/lib/Login.svelte b/ng-app/src/lib/Login.svelte index 6e743bb..e64df77 100644 --- a/ng-app/src/lib/Login.svelte +++ b/ng-app/src/lib/Login.svelte @@ -9,12 +9,22 @@ // according to those terms. --> + + -{#if step == "load"} -
-

How to open your wallet, step by step :

- -
-
- {#if !loaded} - Loading pazzle... +
+ {#if step == "load"} +
+

How to open your wallet, step by step :

+
    +
  • + For each one of the 9 categories of images, you will be presented with + the 15 possible image choices. The categories are shuffled at every + login. They will not always appear in the same order. +
  • +
  • + At each category, only one of the 15 displayed choices is the correct + image that belongs to your pazzle. Find it and tap or click on that + one. The 15 images are shuffled too, they will not appear at the same + position at each login. On a computer, you can also use the tab key on + your keyboard to move to the desired item on the screen, then press + the space bar to select each one. +
  • +
  • + Once you completed the last category, you will be presented with all + the images you have previously selected. Their order is displayed as + it was when you picked them. But this is not the correct order of the + images in your pazzle. You now have to order them correctly. +
  • +
  • + You must remember which image should be the first one in your pazzle. + Find it on the screen and click or tap on it. It will be greyed out + and the number 1 will appear on top of it. +
  • +
  • + Move on to the second image of your pazzle (that you memorized). Find + it on the screen and tap on it. Repeat this step until you reached the + last image. +
  • +
  • + Finally, your PIN code will be asked. enter it by clicking or tapping + on the digits. +
  • +
+
+
+ {#if !loaded} + Loading pazzle... + + + + + {:else} +
+ + +
+ {/if} +
+ {#if for_import} +
+ Do you trust this device?
+
+ Yes, save my wallet on this device +
+

+ 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}
+

+
+ {/if} + {:else if step == "pazzle"} +
+
+ {#each [0, 1, 2, 3, 4] as row} +
+ {#each emojis2[pazzlePage]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i (pazzlePage + "-" + row + "-" + i)} +
select(row * 3 + i)} + on:keypress={() => select(row * 3 + i)} + > + +
+ {/each} +
+ {/each} +
+
+ + +
+
+ {:else if step == "order"} + +
+
+ {#each [0, 1, 2] as row} +
+ {#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} + {#if !emoji.sel} +
select_order(emoji, row * 3 + i)} + on:keypress={() => select_order(emoji, row * 3 + i)} + > + +
+ {:else} +
+ + {emoji.sel} +
+ {/if} + {/each} +
+ {/each} +
+
+ + + +
+
+ {:else if step == "pin"} +
+
+

+ Enter your PIN code +

+
+ {#each [0, 1, 2] as row} +
+ {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} + + {/each} +
+ {/each} + +
+
+
+ + + +
+
+ {:else if step == "opening"} +
+ Opening your wallet...
+ Please wait - {:else} - - {/if} -
- {#if for_import} -
- Do you trust this device?
-
- Yes, save my wallet on this device -
-

- 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}
-

- {/if} -{:else if step == "pazzle"} -
- {#each [0, 1, 2, 3, 4] as row} -
- {#each emojis2[display]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} -
select(row * 3 + i)} - on:keypress={() => select(row * 3 + i)} - > - -
- {/each} + {:else if step == "end"} + {#if error} +
+ An error occurred ! + + + {error} + + +
- {/each} -
-{:else if step == "order"} - -
- {#each [0, 1, 2] as row} -
- {#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} - {#if !emoji.sel} -
select_order(emoji, row * 3 + i)} - on:keypress={() => select_order(emoji, row * 3 + i)} - > - -
- {:else} -
- - {emoji.sel} -
- {/if} - {/each} + {:else} +
+ Your wallet is opened!
Please wait while the app is loading... +
- {/each} -
-{:else if step == "pin"} -
-

- Enter your PIN code -

-
- {#each [0, 1, 2] as row} -
- {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} - - {/each} -
- {/each} - -
-
-{:else if step == "opening"} -
- Opening your wallet...
- Please wait - - - - -
-{:else if step == "end"} - {#if error} -
- An error occurred ! - - - {error} - - - -
- {:else} -
- Your wallet is opened!
Please wait while the app is loading... - -
+ {/if} {/if} -{/if} +
From a4a1e639771660a65f9365216a4f93a662acdc4c Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Thu, 27 Jun 2024 16:13:51 +0200 Subject: [PATCH 02/29] ng-app login: adjust pin pad to same size as emojis --- ng-app/src/lib/Login.svelte | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/ng-app/src/lib/Login.svelte b/ng-app/src/lib/Login.svelte index e64df77..87e4747 100644 --- a/ng-app/src/lib/Login.svelte +++ b/ng-app/src/lib/Login.svelte @@ -490,31 +490,33 @@ class:max-w-[360px]={mobile} class:max-w-[600px]={!mobile} > -
+

Enter your PIN code

-
- {#each [0, 1, 2] as row} -
- {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} - - {/each} -
- {/each} + {#each [0, 1, 2] as row} +
+ {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} + + {/each} +
+ {/each} +
+
+
From 1be5c5be50a6cd1e4f7e6a025bcae2d34574f0b9 Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Thu, 27 Jun 2024 16:25:31 +0200 Subject: [PATCH 03/29] fix misalignment of cancel button --- ng-app/src/lib/Login.svelte | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ng-app/src/lib/Login.svelte b/ng-app/src/lib/Login.svelte index 87e4747..14c28fe 100644 --- a/ng-app/src/lib/Login.svelte +++ b/ng-app/src/lib/Login.svelte @@ -337,7 +337,7 @@ - +
+ An error occurred ! + + + {error} + +
+
+ + +
{:else}
@@ -659,28 +678,4 @@ border: 0; 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)); - } - } From dfdce388a455d09f0ac0f01a98b7bc4b9b27ed44 Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Thu, 27 Jun 2024 17:06:25 +0200 Subject: [PATCH 05/29] component descriptions --- ng-app/src/lib/Install.svelte | 6 +++++- ng-app/src/lib/NoWallet.svelte | 5 +++++ ng-app/src/routes/Home.svelte | 7 +++++-- ng-app/src/routes/User.svelte | 6 ++++++ ng-app/src/routes/WalletCreate.svelte | 7 +++++++ ng-app/src/routes/WalletLogin.svelte | 6 ++++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/ng-app/src/lib/Install.svelte b/ng-app/src/lib/Install.svelte index 1b1af5a..14ef5bd 100644 --- a/ng-app/src/lib/Install.svelte +++ b/ng-app/src/lib/Install.svelte @@ -9,8 +9,12 @@ // according to those terms. --> + + + + + + + diff --git a/ng-app/src/store.ts b/ng-app/src/store.ts index 8771ef8..59abe3e 100644 --- a/ng-app/src/store.ts +++ b/ng-app/src/store.ts @@ -7,7 +7,7 @@ // notice may not be copied, modified, or distributed except // according to those terms. -import { writable, readable, readonly, derived, get } from "svelte/store"; +import { writable, readable, readonly, derived, get, type Writable } from "svelte/store"; import ng from "./api"; let all_branches = {}; @@ -19,31 +19,58 @@ export const active_wallet = writable(undefined); export const wallets = writable({}); -export const connections = writable({}); +export const connections: Writable> = writable({}); export const active_session = writable(undefined); -let next_reconnect = null; +export const connection_status: Writable<"disconnected" | "connected" | "connecting"> = writable("disconnected"); -export const online = derived(connections,($connections) => { - for (const cnx of Object.keys($connections)) { - if (!$connections[cnx].error) return true; - else if ($connections[cnx].error=="PeerAlreadyConnected") { - connections.update((c) => { +let next_reconnect: NodeJS.Timeout | null = null; + +const updateConnectionStatus = ($connections: Record ) => { + // Reset error state for PeerAlreadyConnected errors. + Object.entries($connections).forEach(([cnx, connection]) => { + if (connection.error === "PeerAlreadyConnected") { + connections.update(c => { c[cnx].error = undefined; return c; }); - return true; } - else if ($connections[cnx].error=="ConnectionError" && !$connections[cnx].connecting && next_reconnect==null) { - console.log("will try reconnect in 20 sec"); - next_reconnect = setTimeout(async ()=> { - await reconnect(); - },20000); } + }); + + // Check if any connection is active. + const is_connected = Object.values($connections).some(connection => !connection.error); + + // Check if any connection is connecting. + const is_connecting = Object.values($connections).some(connection => connection.connecting); + + // Check, if reconnect is needed. + const should_reconnect = !is_connecting && (next_reconnect === null) && Object.values($connections).some( + connection => connection.error === "ConnectionError" + ); + if (should_reconnect) { + console.log("will try reconnect in 20 sec"); + next_reconnect = setTimeout(async () => { + await reconnect(); + connection_status.set("connecting"); + next_reconnect = null; + }, 20000); } - return false; + + if (is_connected) { + connection_status.set("connected"); + } else if (!is_connected && is_connecting) { + connection_status.set("connecting"); + } else { + connection_status.set("disconnected"); + } +}; +connections.subscribe(($connections) => { + updateConnectionStatus($connections); }); +export const online = derived(connection_status,($connectionStatus) => $connectionStatus == "connected"); + export const cannot_load_offline = writable(false); if (!get(online) && !import.meta.env.TAURI_PLATFORM) { @@ -123,8 +150,6 @@ export const reconnect = async function() { get(active_session).user, location.href )); - - }catch (e) { console.error(e) } From b39613117cb4a10acfce0bd06abb5fbf7425f183 Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Tue, 2 Jul 2024 12:28:43 +0200 Subject: [PATCH 09/29] remove clear in favor of go back button --- ng-app/src/lib/Login.svelte | 364 ++++++++++++++++-------------------- 1 file changed, 166 insertions(+), 198 deletions(-) diff --git a/ng-app/src/lib/Login.svelte b/ng-app/src/lib/Login.svelte index 8bdf5ed..cee8837 100644 --- a/ng-app/src/lib/Login.svelte +++ b/ng-app/src/lib/Login.svelte @@ -22,7 +22,7 @@ import { PuzzlePiece, XCircle, - ArrowLeftCircle, + Backspace, ArrowPath, LockOpen, } from "svelte-heros-v2"; @@ -31,7 +31,6 @@ export let for_import = false; let tauri_platform = import.meta.env.TAURI_PLATFORM; - let mobile = tauri_platform == "android" || tauri_platform == "ios"; const dispatch = createEventDispatcher(); @@ -87,8 +86,6 @@ let ordered = []; - let last_one = {}; - let shuffle_pin; let error; @@ -98,14 +95,9 @@ function order() { step = "order"; ordered = []; - 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++) { - last_one[i] = true; - } } async function start_pin() { @@ -230,23 +222,16 @@ dispatch("cancel"); } - function to_previous_pazzle() { - pazzlePage = pazzlePage - 1; - } - async function on_pin_key(val) { pin_code = [...pin_code, val]; } - async function select_order(val, pos) { - delete last_one[pos]; - console.debug(last_one, val); - + async function select_order(val) { ordered.push(val); val.sel = ordered.length; selection = selection; if (ordered.length == pazzle_length - 1) { - let last = selection[Object.keys(last_one)[0]]; + let last = selection.find((emoji) => !emoji.sel); ordered.push(last); last.sel = ordered.length; selection = selection; @@ -254,9 +239,58 @@ await start_pin(); } } + + function go_back() { + if (step === "pazzle") { + // Go to previous pazzle or init page, if on first pazzle. + if (pazzlePage === 0) { + init(); + } else { + pazzlePage -= 1; + } + } else if (step === "order") { + if (ordered.length === 0) { + step = "pazzle"; + } else { + const last_selected = ordered.pop(); + last_selected.sel = null; + ordered = ordered; + selection = selection; + } + } else if (step === "pin") { + if (pin_code.length === 0) { + // Unselect the last two elements. + const to_unselect = ordered.slice(-2); + to_unselect.forEach((val) => { + val.sel = null; + }); + + ordered = ordered.slice(0, -2); + selection = selection; + step = "order"; + } else { + pin_code = pin_code.slice(0, pin_code.length - 1); + } + } + } + + let width: number; + let breakPoint: number = 361; + let mobile = false; + $: if (width >= breakPoint) { + mobile = false; + } else { + mobile = true; + } -
+
{#if step == "load"}

How to open your wallet, step by step:

@@ -322,6 +356,14 @@ {:else}
+ -
{/if}
@@ -362,60 +396,8 @@

{/if} - {:else if step == "pazzle"} -
-
-

- - - Select your emoji of category: {emoji_cat[ - shuffle.category_indices[pazzlePage] - ]} -

- {#each [0, 1, 2, 3, 4] as row} -
- {#each emojis2[pazzlePage]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i (pazzlePage + "-" + row + "-" + i)} -
select(row * 3 + i)} - on:keypress={() => select(row * 3 + i)} - > - -
- {/each} -
- {/each} -
-
- - -
-
- {:else if step == "order"} - + + {:else if step == "pazzle" || step == "order" || step == "pin" || step == "mnemonic"}
-
-

- Click your emojis in the correct order -

- {#each [0, 1, 2] as row} -
- {#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} - {#if !emoji.sel} +
+ {#if step == "pazzle"} +

+ + + Select your emoji of category: {emoji_cat[ + shuffle.category_indices[pazzlePage] + ]} +

+ {#each [0, 1, 2, 3, 4] as row} +
+ {#each emojis2[pazzlePage]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i (pazzlePage + "-" + row + "-" + i)}
select_order(emoji, row * 3 + i)} - on:keypress={() => select_order(emoji, row * 3 + i)} + on:click={() => select(row * 3 + i)} + on:keypress={() => select(row * 3 + i)} > - +
- {:else} -
- - {emoji.sel} + {/each} + {:else if step == "order"} +

+ Click your emojis in the correct order +

+ {#each [0, 1, 2] as row} +
+ {#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} + {#if !emoji.sel} +
select_order(emoji)} + on:keypress={() => select_order(emoji)} > -
- {/if} - {/each} + +
+ {:else} +
+ + {emoji.sel} +
+ {/if} + {/each} +
+ {/each} + {:else if step == "pin"} +

+ Enter your PIN code: + {#each pin_code as pin_key}*{/each} +

+ {#each [0, 1, 2] as row} +
+ {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} + + {/each} +
+ {/each} +
+
+ +
- {/each} + {/if}
+
- - -
-
- {:else if step == "pin"} -
-
-

- Enter your PIN code -

- {#each [0, 1, 2] as row} -
- {#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} - - {/each} -
- {/each} -
-
- - -
-
-
- -
{:else if step == "opening"} @@ -660,6 +626,8 @@ {/if}
+ + diff --git a/ng-app/src/lib/NoWallet.svelte b/ng-app/src/lib/NoWallet.svelte index 12aa7a1..60fb913 100644 --- a/ng-app/src/lib/NoWallet.svelte +++ b/ng-app/src/lib/NoWallet.svelte @@ -16,7 +16,7 @@ import CenteredLayout from "./CenteredLayout.svelte"; - +