diff --git a/ng-app/src/lib/Login.svelte b/ng-app/src/lib/Login.svelte index caadefa..765df6b 100644 --- a/ng-app/src/lib/Login.svelte +++ b/ng-app/src/lib/Login.svelte @@ -32,6 +32,7 @@ ArrowLeft, } from "svelte-heros-v2"; import PasswordInput from "./components/PasswordInput.svelte"; + import Spinner from "./components/Spinner.svelte"; //import Worker from "../worker.js?worker&inline"; export let wallet; export let for_import = false; @@ -374,7 +375,9 @@ {#if for_import}
- {$t("pages.wallet_create.save_wallet_options.trust")}
+ {$t("pages.wallet_create.save_wallet_options.trust")} +

{$t("pages.wallet_create.save_wallet_options.trust_description")} {#if !tauri_platform} @@ -384,6 +387,7 @@ {$t("pages.login.trust_device_yes")} +

{/if} @@ -392,27 +396,7 @@
{#if !loaded} {$t("pages.login.loading_pazzle")}... - - - - + {:else}
{:else if step == "end"} {#if error} diff --git a/ng-app/src/lib/Test.svelte b/ng-app/src/lib/Test.svelte index 88780c0..c15b09c 100644 --- a/ng-app/src/lib/Test.svelte +++ b/ng-app/src/lib/Test.svelte @@ -21,17 +21,19 @@ active_session, cannot_load_offline, online, + get_blob, } from "../store"; import { link } from "svelte-spa-router"; import { onMount, onDestroy, tick } from "svelte"; - import { Button } from "flowbite-svelte"; + import { Button, Progressbar, Spinner } from "flowbite-svelte"; import DataClassIcon from "./DataClassIcon.svelte"; import { t } from "svelte-i18n"; let is_tauri = import.meta.env.TAURI_PLATFORM; - let files = $active_session && branch_subs($active_session.private_store_id); + let upload_progress: null | { total: number; current: number; error?: any } = + null; - let img_map = {}; + let files = $active_session && branch_subs($active_session.private_store_id); let gitgraph; @@ -526,76 +528,28 @@ // ]); }); - async function get_img(ref) { - if (!ref) return false; - let cache = img_map[ref.nuri]; - if (cache) { - return cache; - } - let prom = new Promise(async (resolve) => { - try { - let nuri = { - target: "PrivateStore", - entire_store: false, - access: [{ Key: ref.reference.key }], - locator: [], - object: ref.reference.id, - }; - - let file_request = { - V0: { - command: "FileGet", - nuri, - session_id: $active_session.session_id, - }, - }; - - let final_blob; - let content_type; - let unsub = await ng.app_request_stream(file_request, async (blob) => { - //console.log("GOT APP RESPONSE", blob); - if (blob.V0.FileMeta) { - content_type = blob.V0.FileMeta.content_type; - final_blob = new Blob([], { type: content_type }); - } else if (blob.V0.FileBinary) { - if (blob.V0.FileBinary.byteLength > 0) { - final_blob = new Blob([final_blob, blob.V0.FileBinary], { - type: content_type, - }); - } - } else if (blob.V0 == "EndOfStream") { - var imageUrl = URL.createObjectURL(final_blob); - resolve(imageUrl); - } - }); - } catch (e) { - console.error(e); - resolve(false); - } - }); - img_map[ref.nuri] = prom; - return prom; - } - let fileinput; function uploadFile(upload_id, nuri, file, success) { - let chunkSize = 1048564; + let chunkSize = 1_048_564; let fileSize = file.size; let offset = 0; let readBlock = null; + upload_progress = { total: fileSize, current: offset }; let onLoadHandler = async function (event) { let result = event.target.result; if (event.target.error == null) { - offset += event.target.result.byteLength; - //console.log("chunk", event.target.result); + offset += result.byteLength; + upload_progress = { total: fileSize, current: offset }; + + // console.log("chunk", result); let res = await ng.upload_chunk( $active_session.session_id, upload_id, - event.target.result, + result, nuri ); //console.log("chunk upload res", res); @@ -609,6 +563,7 @@ return; } + // If finished: if (offset >= fileSize) { //console.log("file uploaded"); let res = await ng.upload_chunk( @@ -619,8 +574,16 @@ ); //console.log("end upload res", res); if (success) { + upload_progress = { total: fileSize, current: fileSize }; success(res); + } else { + upload_progress = { total: fileSize, current: fileSize, error: true }; } + + // Make progress bar disappear + setTimeout(() => { + upload_progress = null; + }, 2_500); return; } @@ -696,7 +659,7 @@ {#if $cannot_load_offline}

- {$t("pages.text.cannot_load_offline")} + {@html $t("pages.test.cannot_load_offline")} {$t("pages.user_panel.title")}.

@@ -747,6 +710,17 @@ bind:this={fileinput} /> + {#if upload_progress !== null} +
+ +
+ {/if} {#if files} {#await files.load()}

{$t("connectivity.loading")}...

@@ -755,7 +729,11 @@

{file.name} - {#await get_img(file) then url} + {#await get_blob(file)} +

+ +
+ {:then url} {#if url} {file.name} {/if} diff --git a/ng-app/src/lib/components/CopyToClipboard.svelte b/ng-app/src/lib/components/CopyToClipboard.svelte index 6760bc8..586a158 100644 --- a/ng-app/src/lib/components/CopyToClipboard.svelte +++ b/ng-app/src/lib/components/CopyToClipboard.svelte @@ -1,3 +1,14 @@ + + + + + + + diff --git a/ng-app/src/locales/en.json b/ng-app/src/locales/en.json index 17ca308..5e60d09 100644 --- a/ng-app/src/locales/en.json +++ b/ng-app/src/locales/en.json @@ -63,7 +63,8 @@ }, "test": { "cannot_load_offline": "You are offline and using the web app. You need to connect to the broker at least once before you can start using the app locally because the web app does not keep a local copy of your documents.

Once connected, if you lose connectivity again, you will be able to have limited access to some functionalities. Sending binary files won't be possible, because the limit of local storage in your browser is around 5MB.

All those limitations will be lifted once the \"UserStorage for Web\" feature will be released. Stay tuned!

Check your connection status in the ", - "add_image": "Add Image" + "add_image": "Add Image", + "upload_progress": "Uploading..." }, "login": { "heading": "How to open your wallet? You have 2 options:", diff --git a/ng-app/src/routes/WalletCreate.svelte b/ng-app/src/routes/WalletCreate.svelte index 464077e..f2628d5 100644 --- a/ng-app/src/routes/WalletCreate.svelte +++ b/ng-app/src/routes/WalletCreate.svelte @@ -45,6 +45,7 @@ import { onMount, onDestroy, tick } from "svelte"; import { wallets, set_active_session, has_wallets } from "../store"; + import Spinner from "../lib/components/Spinner.svelte"; const param = new URLSearchParams($querystring); @@ -528,27 +529,7 @@ {:else} {wait} {/if} - - - - + {:else}
@@ -1325,7 +1306,9 @@ bind:this={phrase} class="mt-10 mr-0" id="security-phrase-input" - placeholder={$t("pages.wallet_create.type_security_phrase_placeholder")} + placeholder={$t( + "pages.wallet_create.type_security_phrase_placeholder" + )} bind:value={security_txt} on:keypress={security_phrase_ok} />
{:else}
diff --git a/ng-app/src/store.ts b/ng-app/src/store.ts index 2d59db0..fd477dc 100644 --- a/ng-app/src/store.ts +++ b/ng-app/src/store.ts @@ -24,23 +24,23 @@ let all_branches = {}; // Make sure that a file named `locales/.json` exists when adding it here. export const available_languages = { - en: "English", - de: "Deutsch", - fr: "Français", - ru: "Русский", - es: "Español", - it: "Italiano", - zh: "中文", - pt: "Português", + en: "English", + de: "Deutsch", + fr: "Français", + ru: "Русский", + es: "Español", + it: "Italiano", + zh: "中文", + pt: "Português", }; for (const lang of Object.keys(available_languages)) { - register(lang, () => import(`./locales/${lang}.json`)) + register(lang, () => import(`./locales/${lang}.json`)) } init({ - fallbackLocale: "en", - initialLocale: "en", + fallbackLocale: "en", + initialLocale: "en", }); export const select_default_lang = async () => { @@ -453,4 +453,56 @@ export const branch_subs = function(nuri) { } }; +let blob_cache = {}; +export async function get_blob(ref: { nuri: string | number; reference: { key: any; id: any; }; }) { + if (!ref) return false; + const cached = blob_cache[ref.nuri]; + if (cached) { + return cached; + } + let prom = new Promise(async (resolve) => { + try { + let nuri = { + target: "PrivateStore", + entire_store: false, + access: [{ Key: ref.reference.key }], + locator: [], + object: ref.reference.id, + }; + + let file_request = { + V0: { + command: "FileGet", + nuri, + session_id: get(active_session).session_id, + }, + }; + + let final_blob; + let content_type; + let unsub = await ng.app_request_stream(file_request, async (blob) => { + //console.log("GOT APP RESPONSE", blob); + if (blob.V0.FileMeta) { + content_type = blob.V0.FileMeta.content_type; + final_blob = new Blob([], { type: content_type }); + } else if (blob.V0.FileBinary) { + if (blob.V0.FileBinary.byteLength > 0) { + final_blob = new Blob([final_blob, blob.V0.FileBinary], { + type: content_type, + }); + } + } else if (blob.V0 == "EndOfStream") { + var imageUrl = URL.createObjectURL(final_blob); + resolve(imageUrl); + } + }); + } catch (e) { + console.error(e); + resolve(false); + } + }); + blob_cache[ref.nuri] = prom; + return prom; +} + //export default branch_commits; \ No newline at end of file