feat: add create profile to onboarding
This commit is contained in:
Jamie Caprani 2023-03-22 13:51:38 +00:00 committed by GitHub
parent f9255100a1
commit a502da6ea4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 473 additions and 54 deletions

View File

@ -323,6 +323,20 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
callback.invoke(finalConfig);
}
@ReactMethod
public void createAccountAndLogin(final String createAccountRequest) {
Log.d(TAG, "createAccountAndLogin");
String result = Statusgo.createAccountAndLogin(createAccountRequest);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "createAccountAndLogin success: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "createAccountAndLogin failed: " + result);
}
}
@ReactMethod
public void saveAccountAndLogin(final String multiaccountData, final String password, final String settings, final String config, final String accountsData) {
try {
@ -520,6 +534,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
return;
}
Log.d(TAG, "[Opening accounts" + rootDir);
Runnable r = new Runnable() {
@Override
public void run() {
@ -1129,6 +1145,23 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
executeRunnableStatusGoMethod(() -> Statusgo.deleteImportedKey(address, password, keyStoreDir), callback);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String keystoreDir() {
final String absRootDirPath = this.getNoBackupDirectory();
return pathCombine(absRootDirPath, "keystore");
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String backupDisabledDataDir() {
return this.getNoBackupDirectory();
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String logFilePath() {
return getLogsFile().getAbsolutePath();
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String generateAlias(final String seed) {
return Statusgo.generateAlias(seed);

View File

@ -857,6 +857,34 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(generateAlias:(NSString *)publicKey) {
return StatusgoGenerateAlias(publicKey);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(keystoreDir) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
lastObject];
NSURL *commonKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
return commonKeystoreDir.path;
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(backupDisabledDataDir) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
lastObject];
return rootUrl.path;
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(logFilePath) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
lastObject];
return rootUrl.path;
}
RCT_EXPORT_METHOD(generateAliasAsync:(NSString *)publicKey
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@ -934,6 +962,13 @@ RCT_EXPORT_METHOD(identiconAsync:(NSString *)publicKey
callback(@[result]);
}
RCT_EXPORT_METHOD(createAccountAndLogin:(NSString *)request) {
#if DEBUG
NSLog(@"createAccountAndLogin() method called");
#endif
StatusgoCreateAccountAndLogin(request);
}
RCT_EXPORT_METHOD(generateAliasAndIdenticonAsync:(NSString *)publicKey
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG

View File

@ -58,6 +58,18 @@
(h/test "Size :small"
(h/render (user-avatar-component :small))
(h/is-truthy (h/get-by-text "NU")))
(h/test "Two letters with excess whitespace"
(h/render [user-avatar/user-avatar
{:full-name "New User"
:size :big}])
(h/is-truthy (h/get-by-text "NU")))
(h/test "Two letters with leading whitespace"
(h/render [user-avatar/user-avatar
{:full-name " New User"
:size :big}])
(h/is-truthy (h/get-by-text "NU"))))
(h/describe "One letter"

View File

@ -5,14 +5,18 @@
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(defn trim-whitespace [s] (string/join " " (string/split (string/trim s) #"\s+")))
(defn- extract-initials
[full-name amount-initials]
(let [upper-case-first-letter (comp string/upper-case first)
names-list (string/split full-name " ")]
(->> names-list
(map upper-case-first-letter)
(take amount-initials)
(string/join))))
names-list (string/split (trim-whitespace full-name) " ")]
(if (= (first names-list) "")
""
(->> names-list
(map upper-case-first-letter)
(take amount-initials)
(string/join)))))
(defn initials-avatar
[{:keys [full-name size draw-ring? customization-color]}]

View File

@ -25,13 +25,13 @@
:height 24
:borderRadius 12}]}
[user-avatar/user-avatar
(merge image-picker-props
{:customization-color customization-color
:full-name (if (seq full-name)
full-name
placeholder)
:status-indicator? false
:size :medium})]]
(assoc image-picker-props
:customization-color customization-color
:full-name (if (seq full-name)
full-name
placeholder)
:status-indicator? false
:size :medium)]]
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
@ -47,5 +47,6 @@
[rn/view {:style style/input-container}
[title-input/title-input
(merge title-input-props
{:placeholder placeholder
{:override-theme :dark
:placeholder placeholder
:customization-color customization-color})]]]))

View File

@ -34,9 +34,11 @@
(def text-input-container {:flex 1})
(defn title-text
[disabled? blur?]
[disabled? blur? override-theme]
{:text-align-vertical :bottom
:color (when disabled? (get-disabled-color blur?))})
:color (if disabled?
(get-disabled-color blur?)
(colors/theme-colors colors/neutral-100 colors/white override-theme))})
(defn char-count
[blur?]

View File

@ -16,7 +16,8 @@
on-change-text
placeholder
max-length
default-value]
default-value
override-theme]
:or {max-length 0
default-value ""}}]
(let [focused? (reagent/atom false)
@ -34,7 +35,7 @@
(text/text-style
{:size :heading-2
:weight :semi-bold
:style (style/title-text disabled? blur?)})
:style (style/title-text disabled? blur? override-theme)})
:default-value default-value
:accessibility-label :profile-title-input
:on-focus #(swap! focused? (fn [] true))

View File

@ -237,7 +237,11 @@
([color suffix]
(custom-color color suffix nil))
([color suffix opacity]
(let [base-color (get-in colors-map [(keyword color) suffix])]
(let [color-keyword (keyword color)
base-color (get-in colors-map
[(if (= color-keyword :yinyang)
(if (theme/dark?) :yang :yin)
(keyword color)) suffix])]
(if opacity (alpha base-color (/ opacity 100)) base-color))))))
(defn custom-color-by-theme

View File

@ -479,8 +479,14 @@
(defn redirect-to-root
"Decides which root should be initialised depending on user and app state"
[db]
(if (get db :tos/accepted?)
(cond
(get db :onboarding-2/new-account?)
(re-frame/dispatch [:navigate-to :enable-notifications])
(get db :tos/accepted?)
(re-frame/dispatch [:init-root :shell-stack])
:else
(re-frame/dispatch [:init-root :tos])))
(rf/defn login-only-events

View File

@ -91,6 +91,10 @@
key-uid
#(.loginWithConfig ^js (status) account-data hashed-password config))))
(defn create-account-and-login
[request]
(.createAccountAndLogin ^js (status) (types/clj->json request)))
(defn export-db
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password callback]
@ -611,3 +615,15 @@
current-password#
new-password
callback))
(defn backup-disabled-data-dir
[]
(.backupDisabledDataDir ^js (status)))
(defn keystore-dir
[]
(.keystoreDir ^js (status)))
(defn log-file-path
[]
(.logFilePath ^js (status)))

View File

@ -12,7 +12,7 @@
[]
[quo/list-item
{:theme :accent
:on-press #(hide-sheet-and-dispatch [:generate-and-derive-addresses])
:on-press #(hide-sheet-and-dispatch [:navigate-to :intro])
:icon :main-icons/add
:accessibility-label :generate-a-new-key
:title (i18n/label :t/generate-a-new-key)}])

View File

@ -90,6 +90,9 @@
(def ^:const command-state-transaction-pending 6)
(def ^:const command-state-transaction-sent 7)
(def ^:const profile-default-color :blue)
(def ^:const profile-name-max-length 24)
(def ^:const profile-pictures-show-to-contacts-only 1)
(def ^:const profile-pictures-show-to-everyone 2)
(def ^:const profile-pictures-show-to-none 3)

View File

@ -4,6 +4,7 @@
[react-native.core :as rn]
[status-im2.contexts.onboarding.create-password.style :as style]
[utils.i18n :as i18n]
[utils.security.core :as security]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.re-frame :as rf]))
@ -32,7 +33,9 @@
:weight :semi-bold
:style {:color colors/white}} "Create profile password"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :enable-biometrics])
{:on-press #(rf/dispatch
[:onboarding-2/password-set
(security/mask-data "test123")])
:style {}} (i18n/label :t/continue)]]])
(defn create-password

View File

@ -2,6 +2,14 @@
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def continue-button
{:width "100%"
:margin-top :auto
:margin-bottom 72
:margin-left :auto
:margin-right :auto
:align-self :flex-end})
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
@ -13,3 +21,5 @@
(def navigation-bar {:height 56})
(def info-message
{:margin-top 8})

View File

@ -1,11 +1,15 @@
(ns status-im2.contexts.onboarding.create-profile.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.onboarding.create-profile.style :as style]
(:require [clojure.string :as string]
[utils.i18n :as i18n]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[status-im2.contexts.onboarding.create-profile.style :as style]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.re-frame :as rf]))
[status-im2.contexts.onboarding.select-photo.method-menu.view :as method-menu]
[utils.re-frame :as rf]
[status-im2.constants :as c]))
(defn navigation-bar
[]
@ -18,21 +22,105 @@
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}}]])
(def emoji-regex
(new
js/RegExp
#"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])"
"i"))
(defn has-emojis [s] (re-find emoji-regex s))
(def common-names ["Ethereum" "Bitcoin"])
(defn has-common-names [s] (pos? (count (filter #(string/includes? s %) common-names))))
(def special-characters-regex (new js/RegExp #"[^a-zA-Z\d\s-]" "i"))
(defn has-special-characters [s] (re-find special-characters-regex s))
(defn validation-message
[s]
(cond
(or (= s nil) (= s "")) nil
(has-emojis s) (i18n/label :t/are-not-allowed {:check (i18n/label :t/emojis)})
(has-special-characters s) (i18n/label :t/are-not-allowed
{:check (i18n/label :t/special-characters)})
(string/ends-with? s "-eth") (i18n/label :t/ending-not-allowed {:ending "-eth"})
(has-common-names s) (i18n/label :t/are-not-allowed {:check (i18n/label :t/common-names)})
:else nil))
(defn page
[]
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} "Create Profile"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :create-profile-password])
:style {}} (i18n/label :t/continue)]]])
[{:keys [image-path display-name color]}]
(let [full-name (reagent/atom display-name)
validation-msg (reagent/atom (validation-message @full-name))
on-change-text (fn [s]
(reset! validation-msg (validation-message s))
(reset! full-name s))
custom-color (reagent/atom (or color c/profile-default-color))
profile-pic (reagent/atom image-path)
on-change-profile-pic #(reset! profile-pic %)
on-change #(reset! custom-color %)]
(fn []
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view
{:style {:flex 1
:padding-horizontal 20}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white
:margin-top 12
:margin-bottom 20}} (i18n/label :t/create-profile)]
[rn/view
{:flex 1
:align-items :flex-start}
[rn/view
{:flex-direction :row
:justify-content :center}
[quo/profile-input
{:customization-color @custom-color
:placeholder (i18n/label :t/your-name)
:on-press #(rf/dispatch
[:bottom-sheet/show-sheet
{:override-theme :dark
:content
(fn []
[method-menu/view on-change-profile-pic])}])
:image-picker-props {:profile-picture @profile-pic
:full-name @full-name}
:title-input-props {:max-length c/profile-name-max-length
:on-change-text on-change-text}}]]
(when @validation-msg
[quo/info-message
{:type :error
:size :default
:icon :i/info
:style style/info-message}
@validation-msg])
[quo/text
{:size :paragraph-2
:style {:color colors/white-70-blur
:margin-top 20
:margin-bottom 16}} (i18n/label :t/accent-colour)]
[quo/color-picker
{:blur? true
:default-selected? :blue
:selected @custom-color
:on-change on-change}]]
[quo/button
{:accessibility-label :submit-create-profile-button
:type :primary
:override-theme :dark
:override-background-color (colors/custom-color @custom-color 50)
:on-press #(rf/dispatch [:onboarding-2/profile-data-set
{:image-path @profile-pic
:display-name @full-name
:color @custom-color}])
:style style/continue-button
:disabled (and (not (seq @full-name)) (not @validation-msg))}
(i18n/label :t/continue)]]])))
(defn create-profile
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
(let [onboarding-profile-data (rf/sub [:onboarding-2/profile])]
[background/view true]
[page onboarding-profile-data])])

View File

@ -25,7 +25,7 @@
:weight :semi-bold
:style {:color colors/white}} "Enable-biometrics"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :enable-notifications])
{:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
:type :grey
:override-theme :dark
:style {}} (i18n/label :t/continue)]]])

View File

@ -25,7 +25,7 @@
:weight :semi-bold
:style {:color colors/white}} "Enable-notifications"]
[quo/button
{:on-press #(rf/dispatch [:navigate-to :shell-stack])
{:on-press #(rf/dispatch [:init-root :shell-stack])
:type :grey
:override-theme :dark
:style {}} (i18n/label :t/continue)]]])

View File

@ -1,7 +1,67 @@
(ns status-im2.contexts.onboarding.events
(:require [utils.re-frame :as rf]))
(:require
[utils.re-frame :as rf]
[re-frame.core :as re-frame]
[status-im2.config :as config]
[clojure.string :as string]
[utils.security.core :as security]
[status-im.native-module.core :as status]
[status-im.ethereum.core :as ethereum]))
(re-frame/reg-fx
::create-account-and-login
(fn [request]
(status/create-account-and-login request)))
(rf/defn on-delete-profile-success
{:events [:onboarding/on-delete-profile-success]}
{:events [:onboarding-2/on-delete-profile-success]}
[{:keys [db]} key-uid]
{:db (update-in db [:multiaccounts/multiaccounts] dissoc key-uid)})
(rf/defn profile-data-set
{:events [:onboarding-2/profile-data-set]}
[{:keys [db]} onboarding-data]
{:db (assoc db :onboarding-2/profile onboarding-data)
:dispatch [:navigate-to :create-profile-password]})
(rf/defn password-set
{:events [:onboarding-2/password-set]}
[{:keys [db]} password]
{:db (assoc-in db [:onboarding-2/profile :password] password)
:dispatch [:navigate-to :enable-biometrics]})
(defn strip-file-prefix
[path]
(when path
(string/replace-first path "file://" "")))
(rf/defn create-account-and-login
{:events [:onboarding-2/create-account-and-login]}
[{:keys [db]}]
(let [{:keys [display-name
password
image-path
color]} (:onboarding-2/profile db)
log-enabled? (boolean (not-empty config/log-level))
request {:displayName display-name
:password (ethereum/sha3 (security/safe-unmask-data password))
:imagePath (strip-file-prefix image-path)
:color color
:backupDisabledDataDir (status/backup-disabled-data-dir)
:rootKeystoreDir (status/keystore-dir)
;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
;; resolved
:wakuV2Nameserver "1.1.1.1"
:logLevel (when log-enabled? config/log-level)
:logEnabled log-enabled?
:logFilePath (status/log-file-path)
:openseaAPIKey config/opensea-api-key
:verifyTransactionURL config/verify-transaction-url
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id}]
{::create-account-and-login request
:dispatch [:navigate-to :generating-keys]
:db (-> db
(dissoc :onboarding-2/profile)
(assoc :onboarding-2/new-account? true))}))

View File

@ -0,0 +1,14 @@
(ns status-im2.contexts.onboarding.generating-keys.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
(def navigation-bar {:height 56})

View File

@ -0,0 +1,30 @@
(ns status-im2.contexts.onboarding.generating-keys.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.onboarding.generating-keys.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.i18n :as i18n]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}}]])
(defn page
[]
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} (i18n/label :t/generating-keys)]]])
(defn generating-keys
[]
[rn/view {:style {:flex 1}}
[background/view true]
[page]])

View File

@ -54,7 +54,7 @@
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(rf/dispatch [:onboarding/on-delete-profile-success key-uid])
(rf/dispatch [:onboarding-2/on-delete-profile-success key-uid])
(log/info "profile deleted: error" error)))))}))
(defn show-confirmation

View File

@ -0,0 +1,71 @@
(ns status-im2.contexts.onboarding.select-photo.method-menu.view
(:require
[quo2.core :as quo]
[utils.i18n :as i18n]
["react-native-image-crop-picker" :default image-picker]
[status-im.multiaccounts.core]
[utils.re-frame :as rf]))
(def crop-size 1000)
(def crop-opts
{:cropping true
:cropperCircleOverlay true
:width crop-size
:height crop-size})
(defn show-access-error
[o]
(when (= "E_PERMISSION_MISSING" (.-code ^js o))
(js/console.log (i18n/label :t/error))))
(defn show-image-picker
([images-fn]
(show-image-picker images-fn nil))
([images-fn
{:keys [media-type]
:or {media-type "any"}
:as props}]
(-> ^js image-picker
(.openPicker (clj->js (merge {:mediaType media-type}
props)))
(.then images-fn)
(.catch show-access-error))))
(defn show-image-picker-camera
([images-fn]
(show-image-picker-camera images-fn nil))
([images-fn props]
(-> ^js image-picker
(.openCamera (clj->js props))
(.then images-fn)
(.catch show-access-error))))
(defn pick-pic
[update-profile-pic-callback]
(rf/dispatch [:bottom-sheet/hide])
(show-image-picker
#(update-profile-pic-callback (.-path ^js %))
crop-opts))
(defn take-pic
[update-profile-pic-callback]
(rf/dispatch [:bottom-sheet/hide])
(show-image-picker-camera
#(update-profile-pic-callback (.-path ^js %))
crop-opts))
(defn view
[update-profile-pic-callback]
[quo/action-drawer
[[{:icon :i/camera
:accessibility-label :take-photo-button
:label (i18n/label :t/profile-pic-take)
:override-theme :dark
:on-press #(take-pic update-profile-pic-callback)}
{:icon :i/image
:override-theme :dark
:accessibility-label :select-from-gallery-button
:label (i18n/label :t/profile-pic-pick)
:on-press #(pick-pic update-profile-pic-callback)}]]])

View File

@ -10,6 +10,7 @@
[status-im2.common.theme.core :as theme]
[status-im2.common.toasts.events]
[status-im2.contexts.add-new-contact.events]
status-im2.contexts.onboarding.events
[status-im2.common.bottom-sheet.events]
[status-im2.navigation.events :as navigation]
[status-im2.db :as db]

View File

@ -21,6 +21,7 @@
[status-im2.contexts.onboarding.new-to-status.view :as new-to-status]
[status-im2.contexts.onboarding.sign-in.view :as sign-in]
[status-im2.contexts.onboarding.syncing.syncing-devices.view :as syncing-devices]
[status-im2.contexts.onboarding.generating-keys.view :as generating-keys]
[status-im2.contexts.onboarding.profiles.view :as profiles]
[status-im2.contexts.quo-preview.main :as quo.preview]
[status-im2.contexts.shell.view :as shell]
@ -37,10 +38,9 @@
:orientation :portrait
:backgroundColor :transparent}}
(if platform/android?
{:navigationBar {:backgroundColor colors/neutral-100}
:statusBar {:backgroundColor :transparent
:style :light
:drawBehind true}}
{:statusBar {:backgroundColor :transparent
:style :light
:drawBehind true}}
{:statusBar {:style :light}})))
(def bottom-sheet-options
@ -129,9 +129,14 @@
;; Onboarding - new to Status
{:name :new-to-status
:options {:statusBar {:style :light}
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:options {:statusBar {:style :light}
:topBar {:visible false}}
:insets {:top false}
:component new-to-status/new-to-status}
{:name :create-profile
:options {:statusBar {:style :light}
:topBar {:visible false}}
:insets {:top false}
:component new-to-status/new-to-status}
@ -156,6 +161,14 @@
:insets {:top false}
:component enable-biometrics/enable-biometrics}
{:name :generating-keys
:options {:statusBar {:style :light}
:topBar {:visible false}
:navigationBar {:backgroundColor colors/black}}
:insets {:top false}
:component generating-keys/generating-keys}
{:name :enable-notifications
:options {:statusBar {:style :light}
:topBar {:visible false}

View File

@ -268,6 +268,10 @@
; media-server
(reg-root-key-sub :mediaserver/port :mediaserver/port)
; onboarding
(reg-root-key-sub :onboarding-2/profile :onboarding-2/profile)
; Testing
(reg-root-key-sub :messenger/started? :messenger/started?)

View File

@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.139.0",
"commit-sha1": "9c1c01c66f652ad6ce6fd4bbfbc613cc7a292878",
"src-sha256": "15cbbzir3bddgdbrrc9pnwdrsahn7a2ihaab7mfz93r0dg3q110i"
"version": "v0.139.1",
"commit-sha1": "48eb7052848a17ab7f972112a3653f0b4cc8537a",
"src-sha256": "0ipmjs6kmdpzyqrxw3nmrzpcmw478mnn1kv97i8khsvfvldlsjga"
}

View File

@ -4,6 +4,7 @@
"about-key-storage-title": "About key storage",
"about-names-content": "No one can pretend to be you! Youre anonymous by default and never have to reveal your real name. You can register a custom name for a small fee.",
"about-names-title": "Names cant be changed",
"accent-colour": "Accent colour",
"access-key": "Access key",
"access-existing-keys": "Access existing keys",
"accept-and-share-address": "Accept and share address",
@ -49,6 +50,7 @@
"allowing-authorizes-this-dapp": "Allowing authorizes this DApp to retrieve your wallet address and enable Web3",
"already-have-asset": "You already have this asset",
"amount": "Amount",
"are-not-allowed": "{{check} are not allowed",
"are-you-sure-description": "You will not be able to see the whole seed phrase again",
"are-you-sure?": "Are you sure?",
"ask-in-status": "Ask a question or report a bug",
@ -170,6 +172,7 @@
"close-app-content": "The app will stop and close. When you reopen it, the selected network will be used",
"close-app-title": "Warning!",
"command-button-send": "Send",
"common-names": "Common names",
"communities": "Communities",
"community-members": {
"one": "{{count}} member",
@ -286,6 +289,7 @@
"counter-9-plus": "9+",
"counter-99-plus": "99+",
"create": "Create",
"create-profile": "Create profile",
"create-a-pin": "Create a 6-digit passcode",
"create-a-puk": "Create a 12-digit PUK",
"create-group-chat": "Create group chat",
@ -473,6 +477,7 @@
"edit": "Edit",
"edit-group": "Edit group",
"edit-profile": "Edit profile",
"emojis": "Emojis",
"empty-chat-description": "There are no messages \nin this chat yet",
"empty-chat-description-one-to-one": "Any messages you send here are encrypted and can only be read by you and ",
"empty-chat-description-public": "It's been quiet here for the last {{quiet-hours}}. Start the conversation or ",
@ -481,6 +486,7 @@
"empty-chat-description-public-share-this": "share this chat.",
"enable": "Enable",
"encrypt-with-password": "Encrypt with password",
"ending-not-allowed": "{{ending}} ending is not allowed",
"ens-10-SNT": "10 SNT",
"ens-add-username": "Add username",
"ens-agree-to": "Agree to ",
@ -1242,6 +1248,7 @@
"signing-phrase": "Signing phrase",
"something-went-wrong": "Something went wrong",
"soon": "Soon",
"special-characters": "Special characters",
"specify-address": "Specify address",
"specify-name": "Specify a name",
"specify-symbol": "Specify a symbol",
@ -1473,6 +1480,7 @@
"your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",
"your-data-belongs-to-you": "If you lose your seed phrase you lose your data and funds",
"your-data-belongs-to-you-description": "If you lose access, for example by losing your phone, you can only access your keys with your seed phrase. No one, but you has your seed phrase. Write it down. Keep it safe",
"your-name": "Your Name",
"your-recovery-phrase": "Your seed phrase",
"your-recovery-phrase-description": "This is your seed phrase. You use it to prove that this is your wallet. You only get to see it once! Write it on paper and keep it in a secure place. You will need it if you lose or reinstall your wallet.",
"custom-seed-phrase": "Invalid seed phrase",