- monocole > monocle

- i18n fixes
- current_lang > svelte-i18n.locale
pull/28/head
Laurin Weger 6 months ago
parent 08168a0a33
commit bf0efefd1f
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 5
      ng-app/src/lib/CenteredLayout.svelte
  2. 4
      ng-app/src/locales/de.json
  3. 65
      ng-app/src/locales/en.json
  4. 2
      ng-app/src/locales/es.json
  5. 2
      ng-app/src/locales/fr.json
  6. 24
      ng-app/src/locales/i18n-init.ts
  7. 2
      ng-app/src/locales/it.json
  8. 2
      ng-app/src/locales/pt.json
  9. 2
      ng-app/src/locales/ru.json
  10. 2
      ng-app/src/locales/zh.json
  11. 2
      ng-app/src/routes/NotFound.svelte
  12. 11
      ng-app/src/routes/WalletCreate.svelte
  13. 25
      ng-app/src/routes/WalletLogin.svelte
  14. 111
      ng-app/src/store.ts
  15. 2
      ng-app/src/wallet_emojis.ts
  16. 2
      ng-wallet/src/emojis.rs

@ -12,7 +12,8 @@
<script lang="ts"> <script lang="ts">
import ng from "../api"; import ng from "../api";
import { onMount, tick } from "svelte"; import { onMount, tick } from "svelte";
import { current_lang, available_languages } from "../store"; import { locale } from "svelte-i18n";
import { available_languages } from "../locales/i18n-init";
import { Language } from "svelte-heros-v2"; import { Language } from "svelte-heros-v2";
import { t } from "svelte-i18n"; import { t } from "svelte-i18n";
@ -31,7 +32,7 @@
} }
const selectLang = async (lang) => { const selectLang = async (lang) => {
current_lang.set(lang); locale.set(lang);
changingLang = false; changingLang = false;
await tick(); await tick();
scrollToTop(); scrollToTop();

@ -1,6 +1,6 @@
{ {
"emojis": { "emojis": {
"code": { "codes": {
"happy": "grinsendes Gesicht", "happy": "grinsendes Gesicht",
"happy_tears": "Gesicht mit Freudentränen", "happy_tears": "Gesicht mit Freudentränen",
"halo": "lächelndes Gesicht mit Heiligenschein", "halo": "lächelndes Gesicht mit Heiligenschein",
@ -14,7 +14,7 @@
"celebrating": "Partygesicht", "celebrating": "Partygesicht",
"sunglasses": "lächelndes Gesicht mit Sonnenbrille", "sunglasses": "lächelndes Gesicht mit Sonnenbrille",
"eyes_up": "Augen verdrehendes Gesicht", "eyes_up": "Augen verdrehendes Gesicht",
"monocole": "Gesicht mit Monokel", "monocle": "Gesicht mit Monokel",
"sleeping": "schlafendes Gesicht", "sleeping": "schlafendes Gesicht",
"mask": "Gesicht mit Atemschutzmaske", "mask": "Gesicht mit Atemschutzmaske",
"fever": "Gesicht mit Fieberthermometer", "fever": "Gesicht mit Fieberthermometer",

@ -74,9 +74,9 @@
"3": "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.", "3": "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.",
"4": "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.", "4": "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.",
"5": "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.", "5": "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.",
"6": "Finally, your PIN code will be asked. enter it by clicking or tapping on the digits." "6": "Finally, your are asked for your PIN code. Enter it by clicking or tapping on the digits."
}, },
"with_menmonic": "With your 12 words Mnemonic (passphrase)", "with_mnemonic": "With your 12 words Mnemonic (passphrase)",
"mnemonic_steps": { "mnemonic_steps": {
"1": "Enter your twelve words mnemonic in the input field. The words must be separated by spaces.", "1": "Enter your twelve words mnemonic in the input field. The words must be separated by spaces.",
"2": "Enter the PIN code that you chose when you created your wallet." "2": "Enter the PIN code that you chose when you created your wallet."
@ -154,9 +154,10 @@
"choose_pin": { "choose_pin": {
"title": "Let's start creating your wallet by choosing a PIN code", "title": "Let's start creating your wallet by choosing a PIN code",
"description": "We recommend you to choose a PIN code that you already know very well. <br /> Your credit card PIN, by example, is a good choice.<br />We at NextGraph will never see your PIN.", "description": "We recommend you to choose a PIN code that you already know very well. <br /> Your credit card PIN, by example, is a good choice.<br />We at NextGraph will never see your PIN.",
"rules": "Here are the rules for the PIN:",
"1": "It cannot be a series like 1234 or 8765.", "1": "It cannot be a series like 1234 or 8765.",
"2": "The same digit cannot repeat more than once. By example 4484 is invalid.", "2": "The same digit cannot repeat more than once. By example 4484 is invalid.",
"3": "Try to avoid birth date, last digits of phone number, or zip code" "3": "Try to avoid birth dates, last digits of phone numbers, or zip codes"
}, },
"chosen_pin": "You have chosen:", "chosen_pin": "You have chosen:",
"confirm_pin": "Please confirm your PIN code.", "confirm_pin": "Please confirm your PIN code.",
@ -166,7 +167,7 @@
"title": "Now let's enter a security phrase and a security image", "title": "Now let's enter a security phrase and a security image",
"description": "As a verification step, this phrase and image will be presented to you every time you are about to enter your pazzle and PIN in order to unlock your wallet.<br /> This security measure will prevent you from entering your pazzle and PIN on malicious sites and apps.", "description": "As a verification step, this phrase and image will be presented to you every time you are about to enter your pazzle and PIN in order to unlock your wallet.<br /> This security measure will prevent you from entering your pazzle and PIN on malicious sites and apps.",
"warning": "Every time you will use your wallet, if you do not see and recognize your own security phrase and image before entering your pazzle, please stop and DO NOT enter your pazzle, as you would be the victim of a phishing attempt.", "warning": "Every time you will use your wallet, if you do not see and recognize your own security phrase and image before entering your pazzle, please stop and DO NOT enter your pazzle, as you would be the victim of a phishing attempt.",
"rules_title": "Here aer the rules for the security phrase and image:", "rules_title": "Here are the rules for the security phrase and image:",
"1": "The phrase should be at least 10 characters long", "1": "The phrase should be at least 10 characters long",
"2": "It should be something you will remember, but not something too personal.", "2": "It should be something you will remember, but not something too personal.",
"3": "Do not enter your full name, nor address, nor phone number.", "3": "Do not enter your full name, nor address, nor phone number.",
@ -187,7 +188,7 @@
"save_wallet_options": { "save_wallet_options": {
"description": "There are 4 options to choose before we can create your wallet. Those options can help you to use and keep your wallet. But we also want to be careful with your security and privacy.<br /><br /> Remember that in any case, once your wallet will be created, you will download a file that you should keep privately somewhere on your device, USB key or hard-disk. This is the default way you can use and keep your wallet. Now let's look at some options that can make your life a bit easier.", "description": "There are 4 options to choose before we can create your wallet. Those options can help you to use and keep your wallet. But we also want to be careful with your security and privacy.<br /><br /> Remember that in any case, once your wallet will be created, you will download a file that you should keep privately somewhere on your device, USB key or hard-disk. This is the default way you can use and keep your wallet. Now let's look at some options that can make your life a bit easier.",
"trust": "Do you trust this device?", "trust": "Do you trust this device?",
"trust_description": "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.", "trust_description": "If you do, if this device is yours, or it is used by a 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.",
"trust_allow_cookies": "By selecting this option, you agree to saving some cookies on your browser.", "trust_allow_cookies": "By selecting this option, you agree to saving some cookies on your browser.",
"trust_toggle": "Save my wallet on this device?", "trust_toggle": "Save my wallet on this device?",
"cloud": "Keep a copy in the cloud?", "cloud": "Keep a copy in the cloud?",
@ -198,7 +199,7 @@
"pdf_description": "We can prepare for you a PDF file containing all the information of your wallet, unencrypted. You should print this file and then delete the PDF (and empty the trash). Keep this printed document in a safe place. It contains all the information to regenerate your wallet in case you lost access to it.", "pdf_description": "We can prepare for you a PDF file containing all the information of your wallet, unencrypted. You should print this file and then delete the PDF (and empty the trash). Keep this printed document in a safe place. It contains all the information to regenerate your wallet in case you lost access to it.",
"pdf_toggle": "Create a PDF of my wallet?", "pdf_toggle": "Create a PDF of my wallet?",
"link": "Create a link to access your wallet easily?", "link": "Create a link to access your wallet easily?",
"link_descriptions": "When you want to use your wallet on the web or from other devices, we can help you find your wallet by creating a simple link accessible from anywhere. Only you will have access to this link. In order to do so, we will keep your wallet ID and some information about your broker on our cloud servers. If you prefer to opt out, just uncheck this option. By selecting this option, you agree to the", "link_description": "When you want to use your wallet on the web or from other devices, we can help you find your wallet by creating a simple link accessible from anywhere. Only you will have access to this link. In order to do so, we will keep your wallet ID and some information about your broker on our cloud servers. If you prefer to opt out, just uncheck this option. By selecting this option, you agree to the",
"link_toggle": "Create a link to my wallet?" "link_toggle": "Create a link to my wallet?"
}, },
"lets_create": "Let's create this wallet", "lets_create": "Let's create this wallet",
@ -217,6 +218,16 @@
"continue_confirm_description": "The pazzle and the mnemonic <span class=\"font-bold\"> will not be shown to you again</span >. Please make sure, you have written them down.", "continue_confirm_description": "The pazzle and the mnemonic <span class=\"font-bold\"> will not be shown to you again</span >. Please make sure, you have written them down.",
"continue_confirm_go_back": "Take me back", "continue_confirm_go_back": "Take me back",
"continue_confirm_yes": "Yes, I did" "continue_confirm_yes": "Yes, I did"
},
"wallet_login": {
"select_wallet": "Select a wallet to login with",
"with_another_wallet": "Log in with another wallet",
"import_wallet": "Import your wallet",
"import_file": "Import a Wallet File",
"import_qr": "Import with QR-Code",
"import_link": "Enter a Wallet Link",
"new_wallet": "Create a New Wallet",
"logged_in": "You are logged in.<br /> please wait while the app is loading"
} }
}, },
"buttons": { "buttons": {
@ -335,48 +346,48 @@
}, },
"codes": { "codes": {
"COMMENT": "YOU CAN FIND I18N UNICODE DESCRIPTIONS AT https://github.com/unicode-org/cldr-json", "COMMENT": "YOU CAN FIND I18N UNICODE DESCRIPTIONS AT https://github.com/unicode-org/cldr-json",
"happy": "grinning face", "happy": "happy grinning face",
"happy_tears": "face with tears of joy", "happy_tears": "face with tears of joy",
"halo": "smiling face with halo", "halo": "smiling face with halo ring",
"three_hearts": "smiling face with hearts", "three_hearts": "face with 3 hearts",
"with_two_hearts": "smiling face with heart-eyes", "with_two_hearts": "face with 2 heart-eyes",
"one_heart": "face blowing a kiss", "one_heart": "face blowing one heart kiss",
"with_tongue": "squinting face with tongue", "with_tongue": "squinting face with tongue",
"with_two_hands": "smiling face with open hands", "with_two_hands": "face with two hands",
"one_hand": "face with hand over mouth", "one_hand": "face with hand over mouth",
"silenced": "zipper-mouth face", "silenced": "silenced zipper-mouth face",
"celebrating": "partying face", "celebrating": "partying face",
"sunglasses": "smiling face with sunglasses", "sunglasses": "face with sunglasses",
"eyes_up": "face with rolling eyes", "eyes_up": "face with rolling eyes up",
"monocole": "face with monocle", "monocle": "face with monocle",
"sleeping": "sleeping face", "sleeping": "sleeping face",
"mask": "face with medical mask", "mask": "face with medical mask",
"fever": "face with thermometer", "fever": "fever face with thermometer",
"bandage": "face with head-bandage", "bandage": "face with head-bandage",
"vomit": "face vomiting", "vomit": "face vomiting",
"tissue": "sneezing face", "tissue": "tissue sneezing face",
"hot": "face with head-bandage", "hot": "hot face with head-bandage",
"cold": "cold face", "cold": "cold face",
"crossed_eyes": "face with crossed-out eyes", "crossed_eyes": "face with crossed-out eyes",
"exploding": "exploding head", "exploding": "exploding head",
"sad": "frowning face", "sad": "frowning sad face",
"long_nose": "lying face", "long_nose": "long nose lying face",
"many_tears": "loudly crying face", "many_tears": "loudly crying face",
"fear": "face screaming in fear", "fear": "face screaming in fear",
"tired": "yawning face", "tired": "yawning face",
"annoyed": "face with steam from nose", "annoyed": "annoyed face with steam from nose",
"clown": "clown face", "clown": "clown face",
"ghost": "ghost", "ghost": "ghost",
"dog": "dog face", "dog": "dog face",
"happy_cat": "grinning cat with smiling eyes", "happy_cat": "grinning cat with smiling eyes",
"scared_cat": "weary cat", "scared_cat": "weary scared cat",
"sad_cat": "crying cat", "sad_cat": "crying cat",
"monkey_no_see": "see-no-evil monkey", "monkey_no_see": "see-no-evil monkey",
"monkey_no_hear": "hear-no-evil monkey", "monkey_no_hear": "hear-no-evil monkey",
"monkey_no_talk": "speak-no-evil monkey", "monkey_no_talk": "speak-no-evil monkey",
"builder": "construction worker", "builder": "construction worker",
"princess": "princess", "princess": "princess",
"firefighter": "person", "firefighter": "firefighter",
"mage": "mage", "mage": "mage",
"mermaid": "merperson", "mermaid": "merperson",
"fairy": "fairy", "fairy": "fairy",
@ -431,7 +442,7 @@
"zebra": "zebra", "zebra": "zebra",
"pig": "pig", "pig": "pig",
"goat": "goat", "goat": "goat",
"sheep": "ewe", "sheep": "sheep",
"camel": "camel", "camel": "camel",
"giraffe": "giraffe", "giraffe": "giraffe",
"elephant": "elephant", "elephant": "elephant",
@ -522,7 +533,7 @@
"night_sky": "milky way", "night_sky": "milky way",
"cloud": "cloud with rain", "cloud": "cloud with rain",
"umbrella": "umbrella with rain drops", "umbrella": "umbrella with rain drops",
"lightning": "high voltage", "lightning": "lightning",
"snowflake": "snowflake", "snowflake": "snowflake",
"snowman": "snowman without snow", "snowman": "snowman without snow",
"thermometer": "thermometer", "thermometer": "thermometer",
@ -548,7 +559,7 @@
"broom": "broom", "broom": "broom",
"magnifying_glass": "magnifying glass tilted left", "magnifying_glass": "magnifying glass tilted left",
"bulb": "light bulb", "bulb": "light bulb",
"three_books": "books", "three_books": "three books",
"package": "package", "package": "package",
"pencil": "pencil", "pencil": "pencil",
"pin": "pushpin", "pin": "pushpin",

@ -14,7 +14,7 @@
"celebrating": "cara de fiesta", "celebrating": "cara de fiesta",
"sunglasses": "cara sonriendo con gafas de sol", "sunglasses": "cara sonriendo con gafas de sol",
"eyes_up": "cara con ojos en blanco", "eyes_up": "cara con ojos en blanco",
"monocole": "cara con monóculo", "monocle": "cara con monóculo",
"sleeping": "cara durmiendo", "sleeping": "cara durmiendo",
"mask": "cara con mascarilla médica", "mask": "cara con mascarilla médica",
"fever": "cara con termómetro", "fever": "cara con termómetro",

@ -14,7 +14,7 @@
"celebrating": "visage festif", "celebrating": "visage festif",
"sunglasses": "visage avec lunettes de soleil", "sunglasses": "visage avec lunettes de soleil",
"eyes_up": "visage roulant des yeux", "eyes_up": "visage roulant des yeux",
"monocole": "visage avec un monocle", "monocle": "visage avec un monocle",
"sleeping": "visage somnolent", "sleeping": "visage somnolent",
"mask": "visage avec masque", "mask": "visage avec masque",
"fever": "visage avec thermomètre", "fever": "visage avec thermomètre",

@ -1,13 +1,21 @@
import { register, init, getLocaleFromNavigator } from "svelte-i18n"; import { register, init, getLocaleFromNavigator } from "svelte-i18n";
register("en", () => import("./en.json")); // Make sure that a file with `<lang>.json` exists
register("de", () => import("./de.json")); // in the same directory, when adding it here.
register("fr", () => import("./fr.json")); export const available_languages = {
register("ru", () => import("./ru.json")); en: "English",
register("es", () => import("./es.json")); de: "Deutsch",
register("it", () => import("./it.json")); fr: "Français",
register("zh", () => import("./zh.json")); ru: "Русский",
register("pt", () => import("./pt.json")); es: "Español",
it: "Italiano",
zh: "中文",
pt: "Português",
};
for (const lang of Object.keys(available_languages)) {
register(lang, () => import(`./${lang}.json`))
}
init({ init({
fallbackLocale: "en", fallbackLocale: "en",

@ -14,7 +14,7 @@
"celebrating": "faccina che festeggia", "celebrating": "faccina che festeggia",
"sunglasses": "faccina con sorriso e occhiali da sole", "sunglasses": "faccina con sorriso e occhiali da sole",
"eyes_up": "faccina con occhi al cielo", "eyes_up": "faccina con occhi al cielo",
"monocole": "faccina con monocolo", "monocle": "faccina con monocolo",
"sleeping": "faccina che dorme", "sleeping": "faccina che dorme",
"mask": "faccina con mascherina", "mask": "faccina con mascherina",
"fever": "faccina con termometro", "fever": "faccina con termometro",

@ -14,7 +14,7 @@
"celebrating": "rosto festivo", "celebrating": "rosto festivo",
"sunglasses": "rosto sorridente com óculos escuros", "sunglasses": "rosto sorridente com óculos escuros",
"eyes_up": "rosto com olhos revirados", "eyes_up": "rosto com olhos revirados",
"monocole": "rosto com monóculo", "monocle": "rosto com monóculo",
"sleeping": "rosto dormindo", "sleeping": "rosto dormindo",
"mask": "rosto com máscara médica", "mask": "rosto com máscara médica",
"fever": "rosto com termômetro", "fever": "rosto com termômetro",

@ -14,7 +14,7 @@
"celebrating": "на вечеринке", "celebrating": "на вечеринке",
"sunglasses": "лицо в темных очках", "sunglasses": "лицо в темных очках",
"eyes_up": "закатывает глаза", "eyes_up": "закатывает глаза",
"monocole": "с моноклем", "monocle": "с моноклем",
"sleeping": "спит", "sleeping": "спит",
"mask": "в медицинской маске", "mask": "в медицинской маске",
"fever": "с градусником во рту", "fever": "с градусником во рту",

@ -14,7 +14,7 @@
"celebrating": "聚会笑脸", "celebrating": "聚会笑脸",
"sunglasses": "墨镜笑脸", "sunglasses": "墨镜笑脸",
"eyes_up": "翻白眼", "eyes_up": "翻白眼",
"monocole": "带单片眼镜的脸", "monocle": "带单片眼镜的脸",
"sleeping": "睡着了", "sleeping": "睡着了",
"mask": "感冒", "mask": "感冒",
"fever": "发烧", "fever": "发烧",

@ -18,7 +18,7 @@
<CenteredLayout displayFooter={true}> <CenteredLayout displayFooter={true}>
<div class="p-8"> <div class="p-8">
<Alert color="red"> <Alert color="red">
<span class="font-medium">404</span>{$t("pages.not_found.title")} <span class="font-medium">404</span> {$t("pages.not_found.title")}
<br /> <br />
<span class="text-sm">{$t("pages.not_found.message")}</span> <span class="text-sm">{$t("pages.not_found.message")}</span>
</Alert> </Alert>

@ -620,7 +620,8 @@
<h2 class="pb-5 text-xl"> <h2 class="pb-5 text-xl">
{$t("pages.wallet_create.wallet_about.title")}<span {$t("pages.wallet_create.wallet_about.title")}<span
class="text-sm" class="text-sm"
>{$t("pages.wallet_create.wallet_about.please_read")}</span >&nbsp
{$t("pages.wallet_create.wallet_about.please_read")}</span
> >
</h2> </h2>
<ul <ul
@ -818,7 +819,7 @@
<h2 class="pb-5 text-xl"> <h2 class="pb-5 text-xl">
{$t("pages.wallet_create.broker_about.title")}<span {$t("pages.wallet_create.broker_about.title")}<span
class="text-sm" class="text-sm"
>{@html $t( >&nbsp{@html $t(
"pages.wallet_create.broker_about.please_read" "pages.wallet_create.broker_about.please_read"
)}</span )}</span
> >
@ -1158,7 +1159,7 @@
</Alert> </Alert>
</p> </p>
<p class="text-left mt-5 px-3"> <p class="text-left mt-5 px-3">
{$t("pages.wallet_create.chose_pin.rules")} {$t("pages.wallet_create.choose_pin.rules")}
</p> </p>
<ul class="text-left list-disc list-inside px-3"> <ul class="text-left list-disc list-inside px-3">
<li>{@html $t("pages.wallet_create.choose_pin.1")}</li> <li>{@html $t("pages.wallet_create.choose_pin.1")}</li>
@ -1427,7 +1428,7 @@
>{@html $t( >{@html $t(
"pages.wallet_create.save_wallet_options.trust" "pages.wallet_create.save_wallet_options.trust"
)}</span )}</span
> <br /> ><br />
{@html $t( {@html $t(
"pages.wallet_create.save_wallet_options.trust_description" "pages.wallet_create.save_wallet_options.trust_description"
)} )}
@ -1701,7 +1702,7 @@
autoclose autoclose
outsideclose outsideclose
bind:open={confirm_modal_open} bind:open={confirm_modal_open}
title={$t("pages.wallet_create.confirm")} title={$t("pages.wallet_create.continue_confirm")}
> >
<span class="text-lg text-neutral-950"> <span class="text-lg text-neutral-950">
{@html $t("pages.wallet_create.continue_confirm_description")} {@html $t("pages.wallet_create.continue_confirm_description")}

@ -18,6 +18,7 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy, tick } from "svelte"; import { onMount, onDestroy, tick } from "svelte";
import { link, push } from "svelte-spa-router"; import { link, push } from "svelte-spa-router";
import { t, locale } from "svelte-i18n";
import Login from "../lib/Login.svelte"; import Login from "../lib/Login.svelte";
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
import ng from "../api"; import ng from "../api";
@ -212,7 +213,9 @@
</svg> </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">
An error occurred:<br />{error} {@html $t("errors.error_occurred", {
values: { message: $t("errors." + error) },
})}
</p> </p>
<button <button
on:click={() => { on:click={() => {
@ -222,7 +225,7 @@
}} }}
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" 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"
> >
Start over {$t("buttons.start_over")}
</button> </button>
</div> </div>
{:else if wallet} {:else if wallet}
@ -237,7 +240,7 @@
<div class="row"> <div class="row">
<Logo class="logo block h-40" alt="NextGraph Logo" /> <Logo class="logo block h-40" alt="NextGraph Logo" />
</div> </div>
<h2 class="pb-5 text-xl">Select a wallet to login with</h2> <h2 class="pb-5 text-xl">{$t("pages.wallet_login.select_wallet")}</h2>
<div class="flex flex-wrap justify-center gap-5 mb-10"> <div class="flex flex-wrap justify-center gap-5 mb-10">
{#each Object.entries($wallets) as wallet_entry} {#each Object.entries($wallets) as wallet_entry}
<div <div
@ -265,8 +268,10 @@
</div> </div>
{/each} {/each}
<div class="wallet-box"> <div class="wallet-box">
{#if $has_wallets}<p class="mt-1">Log in with another wallet</p> {#if $has_wallets}<p class="mt-1">
{:else}<p class="mt-1">Import your wallet</p> {$t("pages.wallet_login.with_another_wallet")}
</p>
{:else}<p class="mt-1">{$t("pages.wallet_login.import_wallet")}</p>
{/if} {/if}
<Fileupload <Fileupload
style="display:none;" style="display:none;"
@ -295,7 +300,7 @@
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25"
/> />
</svg> </svg>
Import a Wallet File {$t("pages.wallet_login.import_file")}
</button> </button>
<Button <Button
style="min-width: 250px;justify-content: left;" style="min-width: 250px;justify-content: left;"
@ -322,7 +327,7 @@
d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z" d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z"
/> />
</svg> </svg>
Import with QRcode {$t("pages.wallet_login.import_qr")}
</Button> </Button>
<Button <Button
style="min-width: 250px;justify-content: left;" style="min-width: 250px;justify-content: left;"
@ -345,7 +350,7 @@
/> />
</svg> </svg>
Enter a Wallet Link {$t("pages.wallet_login.import_link")}
</Button> </Button>
<a href="/wallet/create" use:link> <a href="/wallet/create" use:link>
<button <button
@ -367,14 +372,14 @@
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z" d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/> />
</svg> </svg>
Create a new wallet {$t("pages.wallet_login.new_wallet")}
</button> </button>
</a> </a>
</div> </div>
</div> </div>
<!-- {:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"} --> <!-- {:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"} -->
{:else if step == "loggedin"} {:else if step == "loggedin"}
You are logged in.<br /> please wait while the app is loading...{/if} {@html $t("pages.wallet_login.logged_in")}...{/if}
</CenteredLayout> </CenteredLayout>
</div> </div>

@ -7,37 +7,34 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
import { writable, readable, readonly, derived, get, type Writable } from "svelte/store"; import {
writable,
readable,
readonly,
derived,
get,
type Writable,
} from "svelte/store";
import { locale } from "svelte-i18n";
import ng from "./api"; import ng from "./api";
import { official_classes } from "./classes"; import { official_classes } from "./classes";
import { official_apps, official_services } from "./zeras"; import { official_apps, official_services } from "./zeras";
import { available_languages } from "./locales/i18n-init";
let all_branches = {}; let all_branches = {};
export const available_languages = {
"en": "English",
"de": "Deutsch",
"fr": "Français",
"ru": "Русский",
"es": "Español",
"it": "Italiano",
"zh": "中文",
"pt": "Português",
};
export const current_lang = writable("en");
export const select_default_lang = async() => { export const select_default_lang = async () => {
let locales = await ng.locales(); let locales = await ng.locales();
for (let lo of locales) { for (let lo of locales) {
if (available_languages[lo]) { if (available_languages[lo]) {
// exact match (if locales is a 2 chars lang code, or if we support regionalized translations) // exact match (if locales is a 2 chars lang code, or if we support regionalized translations)
current_lang.set(lo); locale.set(lo);
return; return;
} }
lo = lo.substr(0,2); lo = lo.substr(0, 2);
if (available_languages[lo]) { if (available_languages[lo]) {
current_lang.set(lo); locale.set(lo);
return; return;
} }
} }
@ -58,7 +55,7 @@ export const load_app = async (appName: string) => {
}; };
export const invoke_service = async (serviceName: string, nuri:string, args: object) => { export const invoke_service = async (serviceName: string, nuri: string, args: object) => {
if (serviceName.startsWith("n:g:z")) { if (serviceName.startsWith("n:g:z")) {
let service = official_services[serviceName]; let service = official_services[serviceName];
@ -77,7 +74,7 @@ export const invoke_service = async (serviceName: string, nuri:string, args: obj
export const cur_tab = writable({ export const cur_tab = writable({
cur_store: { cur_store: {
has_outer : { has_outer: {
nuri_trail: ":v:l" nuri_trail: ":v:l"
}, },
type: "public", // "protected", "private", "group", "dialog", type: "public", // "protected", "private", "group", "dialog",
@ -117,7 +114,7 @@ export const cur_tab = writable({
authors: "", authors: "",
icon: "", icon: "",
description: "", description: "",
stream : { stream: {
notif: 1, notif: 1,
last: "", last: "",
}, },
@ -147,7 +144,7 @@ export const connection_status: Writable<"disconnected" | "connected" | "connect
let next_reconnect: NodeJS.Timeout | null = null; let next_reconnect: NodeJS.Timeout | null = null;
const updateConnectionStatus = ($connections: Record<string, any> ) => { const updateConnectionStatus = ($connections: Record<string, any>) => {
// Reset error state for PeerAlreadyConnected errors. // Reset error state for PeerAlreadyConnected errors.
Object.entries($connections).forEach(([cnx, connection]) => { Object.entries($connections).forEach(([cnx, connection]) => {
if (connection.error === "PeerAlreadyConnected") { if (connection.error === "PeerAlreadyConnected") {
@ -172,7 +169,7 @@ const updateConnectionStatus = ($connections: Record<string, any> ) => {
console.log("will try reconnect in 20 sec"); console.log("will try reconnect in 20 sec");
next_reconnect = setTimeout(async () => { next_reconnect = setTimeout(async () => {
await reconnect(); await reconnect();
next_reconnect = null; next_reconnect = null;
}, 20000); }, 20000);
} }
@ -189,7 +186,7 @@ connections.subscribe(($connections) => {
updateConnectionStatus($connections); updateConnectionStatus($connections);
}); });
export const online = derived(connection_status,($connectionStatus) => $connectionStatus == "connected"); export const online = derived(connection_status, ($connectionStatus) => $connectionStatus == "connected");
export const cannot_load_offline = writable(false); export const cannot_load_offline = writable(false);
@ -208,7 +205,7 @@ if (get(connection_status) == "disconnected" && !import.meta.env.TAURI_PLATFORM)
}); });
} }
export const has_wallets = derived(wallets,($wallets) => Object.keys($wallets).length); export const has_wallets = derived(wallets, ($wallets) => Object.keys($wallets).length);
@ -219,7 +216,7 @@ export const set_active_session = function(session) {
export { writable, readonly, derived }; export { writable, readonly, derived };
export const close_active_wallet = async function() { export const close_active_wallet = async function() {
if (next_reconnect) { if (next_reconnect) {
clearTimeout(next_reconnect); clearTimeout(next_reconnect);
next_reconnect = null; next_reconnect = null;
} }
@ -240,7 +237,7 @@ export const close_active_session = async function() {
await ng.session_stop(session.user); await ng.session_stop(session.user);
connections.set({}); connections.set({});
active_session.set(undefined); active_session.set(undefined);
//console.log("setting active_session to undefined",get(active_session)); //console.log("setting active_session to undefined",get(active_session));
@ -254,11 +251,10 @@ export const close_active_session = async function() {
const can_connect = derived([active_wallet, active_session], ([$s1, $s2]) => [ const can_connect = derived([active_wallet, active_session], ([$s1, $s2]) => [
$s1, $s1,
$s2, $s2,
] ]);
);
export const reconnect = async function() { export const reconnect = async function() {
if (next_reconnect) { if (next_reconnect) {
clearTimeout(next_reconnect); clearTimeout(next_reconnect);
next_reconnect = null; next_reconnect = null;
} }
@ -270,12 +266,12 @@ export const reconnect = async function() {
try { try {
let info = await ng.client_info() let info = await ng.client_info()
//console.log("Connecting with",get(active_session).user); //console.log("Connecting with",get(active_session).user);
connections.set(await ng.user_connect( connections.set(await ng.user_connect(
info, info,
get(active_session).user, get(active_session).user,
location.href location.href
)); ));
}catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
} }
@ -309,19 +305,18 @@ export const disconnections_subscribe = async function() {
readable(false, function start(set) { readable(false, function start(set) {
return function stop() { return function stop() {
disconnections_unsub(); disconnections_unsub();
}; };
}); });
can_connect.subscribe(async (value) => { can_connect.subscribe(async (value) => {
if (value[0] && value[0].wallet && value[1]) { if (value[0] && value[0].wallet && value[1]) {
await reconnect(); await reconnect();
} }
}); });
export const branch_subs = function(nuri) { export const branch_subs = function(nuri) {
// console.log("branch_commits") // console.log("branch_commits")
@ -352,9 +347,9 @@ export const branch_subs = function(nuri) {
// // update, // // update,
// }; // };
return { return {
load: async () => { load: async () => {
//console.log("load upper"); //console.log("load upper");
let already_subscribed = all_branches[nuri]; let already_subscribed = all_branches[nuri];
if (!already_subscribed) return; if (!already_subscribed) return;
@ -367,12 +362,11 @@ export const branch_subs = function(nuri) {
} }
}, },
subscribe: (run, invalid) => { subscribe: (run, invalid) => {
let already_subscribed = all_branches[nuri]; let already_subscribed = all_branches[nuri];
if (!already_subscribed) { if (!already_subscribed) {
const { subscribe, set, update } = writable([]); // create the underlying writable store const { subscribe, set, update } = writable([]); // create the underlying writable store
let count = 0; let count = 0;
let unsub = () => {}; let unsub = () => { };
already_subscribed = { already_subscribed = {
load: async () => { load: async () => {
try { try {
@ -383,33 +377,32 @@ export const branch_subs = function(nuri) {
return; return;
} }
unsub(); unsub();
unsub = () => {}; unsub = () => { };
set([]); set([]);
let req= await ng.doc_fetch_repo_subscribe(nuri); let req = await ng.doc_fetch_repo_subscribe(nuri);
req.V0.session_id = session.session_id; req.V0.session_id = session.session_id;
unsub = await ng.app_request_stream(req, unsub = await ng.app_request_stream(req,
async (commit) => { async (commit) => {
//console.log("GOT APP RESPONSE", commit); //console.log("GOT APP RESPONSE", commit);
if (commit.V0.State) { if (commit.V0.State) {
for (const file of commit.V0.State.files) { for (const file of commit.V0.State.files) {
update( (old) => {old.unshift(file); return old;} ) update((old) => { old.unshift(file); return old; })
}
} else if (commit.V0.Patch.other?.FileAdd) {
update((old) => { old.unshift(commit.V0.Patch.other.FileAdd); return old; })
} }
} else if (commit.V0.Patch.other?.FileAdd) { });
update( (old) => {old.unshift(commit.V0.Patch.other.FileAdd); return old;} )
}
});
} }
catch (e) { catch (e) {
console.error(e); console.error(e);
} }
// this is in case decrease has been called before the load function returned. // this is in case decrease has been called before the load function returned.
if (count == 0) {unsub();} if (count == 0) { unsub(); }
}, },
increase: () => { increase: () => {
count += 1; count += 1;
//console.log("increase sub to",count); //console.log("increase sub to",count);
return readonly({subscribe}); return readonly({ subscribe });
}, },
decrease: () => { decrease: () => {
count -= 1; count -= 1;
@ -422,13 +415,13 @@ export const branch_subs = function(nuri) {
}, },
unsubscribe: () => { unsubscribe: () => {
unsub(); unsub();
console.log("unsubscribed ",nuri); console.log("unsubscribed ", nuri);
delete all_branches[nuri]; delete all_branches[nuri];
} }
} }
all_branches[nuri] = already_subscribed; all_branches[nuri] = already_subscribed;
} }
let new_store = already_subscribed.increase(); let new_store = already_subscribed.increase();
let read_unsub = new_store.subscribe(run, invalid); let read_unsub = new_store.subscribe(run, invalid);
return () => { return () => {
@ -436,7 +429,7 @@ export const branch_subs = function(nuri) {
//console.log("callback unsub"); //console.log("callback unsub");
already_subscribed.decrease(); already_subscribed.decrease();
} }
} }
} }
}; };

@ -88,7 +88,7 @@ let face = [
{ {
hexcode: "1f9d0", hexcode: "1f9d0",
shortcode: "face_with_monocle", shortcode: "face_with_monocle",
code: "monocole", code: "monocle",
}, },
{ {
hexcode: "1f634", hexcode: "1f634",

@ -86,7 +86,7 @@ const face: [EmojiDef<'static>; 15] = [
EmojiDef { EmojiDef {
hexcode: "1f9d0", hexcode: "1f9d0",
shortcode: "face_with_monocle", shortcode: "face_with_monocle",
code: "monocole", code: "monocle",
}, },
EmojiDef { EmojiDef {
hexcode: "1f634", hexcode: "1f634",

Loading…
Cancel
Save