Compare commits

..
Author SHA1 Message Date
marko 983a911b60 ci: enable sentry for releases
referenced issue: https://github.com/status-im/status-mobile/issues/21706

Signed-off-by: markoburcul <marko@status.im>
2025-01-13 13:18:47 +01:00
Sean HagstromandAlexander 394648b377 fix: use image clock when updating profile images to cause re-render (#21795) (#21830)
Co-authored-by: Alexander <alwxndr@gmail.com>
2025-01-10 15:01:57 +01:00
Yevheniia Berdnyk 22a606cbab e2e: additional fix for requirements 2025-01-10 14:03:23 +02:00
Sean HagstromandAlexander 1b30b3be80 chore: update legal-docs submodule and resources with updated terms-of-use (#21821) (#21832)
Co-authored-by: Alexander <alwxndr@gmail.com>
2025-01-10 12:27:10 +01:00
Yevheniia Berdnyk 10434b53e0 e2e: fix for requirements and getting username 2025-01-10 03:14:31 +02:00
flexsurfer 0472523a7f [#21652] The main part of a backup flow is missing at Keycard migrati… (#21893) 2025-01-09 19:20:45 +01:00
Volodymyr Kozieiev 770963447a Simplified pull request template (#21900) 2025-01-09 13:48:10 +00:00
Parvesh Monu 874aa9866d On-boarding: re add bio-metric screen to syncing flow (#21890) 2025-01-09 18:22:37 +05:30
Ulises Manuel 32a3f85694 fix(avatars) - Blinking all over the app and improvement in UX (#21782)
* Change multiple uses of `merge` to `assoc` in flat-list wrapper

* Fix fast-image wrapper to avoid blinking

* merge -> assoc usage in chat-item component

* Fix avatar not being updated when the user changes their username

* Fix scalable avatar issues

- On Android, the border was inconsistent depending on the theme.
- Fix animation, simplify the calculation, and now it matches designs

* Avoid blinking by using rn/memo
2025-01-08 18:16:19 -06:00
Volodymyr Kozieiev b88bbda3c5 Reverted some code after cleanup (#21892) 2025-01-08 11:32:44 +00:00
flexsurfer fad5119ceb [#21825] [Android] Java error at the and of faild Migration to a Keycard flow (#21889) 2025-01-08 11:47:53 +01:00
Parvesh Monu 3697f63ab0 Fix syncing flow navigation and designs (#21884) 2025-01-08 11:22:19 +05:30
52 changed files with 419 additions and 514 deletions
+16 -34
View File
@@ -1,39 +1,26 @@
[comment]: # (Please replace ... with your information. Remove < and >)
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
*otherwise*
fixes #...
### Summary
## Summary
[comment]: # (Summarise the problem and how the pull request solves it)
...
<!-- (Optional, remove if no changes to documentation) -->
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
## Review notes
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
### Review notes
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
## Testing notes
[comment]: # (Optional)
### Testing notes
<!-- (Optional) -->
#### Platforms
<!-- (Optional. Specify which platforms should be tested) -->
### Platforms
[comment]: # (Optional. Specify which platforms should be tested)
- Android
- iOS
- macOS
- Linux
- Windows
#### Areas that maybe impacted
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
### Areas that may be impacted
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
##### Functional
#### Functional
- 1-1 chats
- public chats
@@ -48,32 +35,27 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
- fleet
- bootnodes
##### Non-functional
#### Non-functional
- battery performance
- CPU performance / speed of the app
- network consumption
### Steps to test
<!-- (Specify exact steps to test if there are such) -->
## Steps to test
[comment]: # (Specify exact steps to test if there are such)
- Open Status
- ...
- Step 3, etc.
<!-- (PRs will only be accepted if squashed into single commit.) -->
### Before and after screenshots comparison
[comment]: # (Can be ready or wip)
status: ready
| Figma (if available) | iOS (if available) | Android (if available)
| --- | --- | --- |
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
status: ready <!-- Can be ready or wip -->
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
- Specify potentially impacted user flows in _Areas that maybe impacted*.
- Specify potentially impacted user flows in _Areas that may be impacted*.
- Ensure that _Steps to test_ is filled in.
### Risk
+2 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.15'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -41,6 +41,7 @@ pipeline {
BUILD_ENV = 'prod'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
FASTLANE_DISABLE_COLORS = 1
SENTRY_PRODUCTION = "${utils.isReleaseBuild() ? 'true' : 'false'}"
}
stages {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.15'
import groovy.json.JsonBuilder
+2 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.15'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -41,6 +41,7 @@ pipeline {
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
FASTLANE_DISABLE_COLORS = 1
BUNDLE_PATH = "${HOME}/.bundle"
SENTRY_PRODUCTION = "${utils.isReleaseBuild() ? 'true' : 'false'}"
}
stages {
+5 -1
View File
@@ -11,7 +11,7 @@
, outputFileName ? "status-go-${source.shortRev}-${platform}.aar" }:
let
inherit (lib) concatStringsSep optionalString optional splitString;
inherit (lib) concatStringsSep optionalString optional splitString fileContents;
isIOS = platform == "ios";
isAndroid = platform == "android";
enforceXCodeAvailable = callPackage ./enforceXCodeAvailable.nix { };
@@ -46,6 +46,10 @@ in buildGoPackage rec {
# TODO: try removing when go is upgraded to 1.22
GODEBUG = "netdns=cgo+2";
# Sentry for status-go
SENTRY_CONTEXT_NAME = "status-mobile";
SENTRY_CONTEXT_VERSION = version;
preBuild = ''
echo 'Generate static files'
pushd go/src/$goPackagePath
+1 -1
View File
@@ -66,7 +66,7 @@
"react-native-shake": "^3.3.1",
"react-native-share": "10.0.2",
"react-native-static-safe-area-insets": "^2.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.4",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.5",
"react-native-svg": "13.10.0",
"react-native-webview": "13.6.3",
"react-syntax-highlighter": "^15.5.0"
+52 -41
View File
@@ -1,9 +1,10 @@
Status Terms of Use
Last updated: 14 August 2024
Last updated: 10 December 2024
1. Introduction
1.1 Who we are
Status is developing a set of open source projects that use peer-to-peer technologies to help people transact securely, communicate freely, and organise with confidence. Anyone participating in these projects helps to build technology and tools that empowers people to advance their own sovereign communities.
@@ -14,7 +15,7 @@ Status does not provide any services, such as financial services, to users of St
1.2 About these terms
These terms are a contract between you and Status and apply to your use of Status Software. The term “Status Software” as used herein means a software developed by Status and is composed of a secure messaging tool, a crypto wallet, and a Web 3 browser integrated together.
These terms are a contract between you and Status and apply to your use of Status Software. The term “Status Software” as used herein means a software developed by Status and is composed of a secure messaging tool and a crypto wallet integrated together.
Please read these terms carefully before using Status Software. By installing or using Status Software on any device, you agree to these terms. If you do not agree, you should not install or use Status Software.
@@ -48,57 +49,56 @@ If a dispute arises between you and Status, we will seek to first solve it amica
At Status, we strive to develop open source software that can serve as a secure communication tool that helps to uphold human rights. Status Software is specifically designed to facilitate the free flow of information, protect the right to private, secure communications and promote the sovereignty of individuals.
Status Software is composed of a secure messaging tool, a crypto wallet, and a Web 3 browser integrated together. The software developed by Status in this regard is simply called “Status Software” and you can find more details about its development on Status GitHub page.
Status Software is composed of a secure messaging tool and a crypto wallet integrated together. The software developed by Status in this regard is simply called “Status Software” and you can find more details about its development on Status GitHub page.
Status Software is open source client software that is designed to be user-friendly and can be installed or run in a web browser on your local desktop or mobile device. You can use Status Software to interact with and participate in Web 3 protocols, applications and peer to peer networks (referred to in these terms collectively, as “Web 3”). Please note that Status Software is not a blockchain protocol, or a blockchain network, a platform or a web-based platform.
Status develops Status Software and makes it available for you to run in a web browser or for your local use on your desktop or mobile device. This means that you are solely responsible for your activity and any potential risk or loss you may incur through using the Status Software as further detailed below in these terms.
Status develops Status Software and makes it available for you to run in a web browser or for your local use on your desktop or mobile device. This means that you are solely responsible for your activity and any potential risk or loss you may incur through using the Status Software as further detailed below in these terms.
As a result of the privacy-first design of Status Software:
1. Status does not store nor have access to user data, messages, or content;
2. Status cannot associate content or actions with individual users. However, users may choose to disclose certain limited information to Status voluntarily, such as when opting in to share usage analytics. This data, shared only through explicit consent of the user, is processed in accordance with our Privacy Policy;
3. Status cannot block or ban users from using Status Software features;
4. Status has no means of monitoring, moderating, removing, modifying or regulating users content or activity, except in Community Spaces created and directly managed by Status.
2.1.1 Wallet
Status Software includes a crypto wallet. We will refer to such wallet functionality in these terms as “Wallet”.
The Wallet is your own personal crypto wallet. This type of wallet is sometimes also called “non-custodial”, “self-custodial” or “self-hosted”, which means you are in complete control of the crypto tokens (the “Digital Assets”) in the Wallet. Status will never have access to or control over your seed phrase, private keys or Digital Assets in your Wallet given its design.
The Wallet is your own personal crypto wallet. This type of wallet is sometimes also called “non-custodial”, “self-custodial” or “self-hosted”, which means you are in complete control of the crypto tokens (the “Digital Assets”) in the Wallet. Status will never have access to or control over your seed phrase, private keys or Digital Assets in your Wallet given its design.
Using the Wallet, you are able to send, receive and store Digital Assets and connect to and interact with third-party services that enable the exchange of Digital Assets for fiat currency and Web 3, including certain blockchain bridges and decentralised exchanges.
Using the Wallet, you are able to send, receive and store Digital Assets and connect to and interact with third-party services that enable the exchange of Digital Assets for fiat currency and Web 3, including certain blockchain bridges and decentralised exchanges.
The Wallet contains the latest security standards, anti-phishing mechanisms and locally generated and stored public and private keys to ensure that your Digital Assets are secured to the highest standards.
The Wallet contains the latest security standards, anti-phishing mechanisms and locally generated and stored public and private keys to ensure that your Digital Assets are secured to the highest standards.
When generating an account, a randomisation process is started on your own device that generates a key pair. Status does not have visibility of or access to your private keys. You are solely responsible for storing and securing your seed phrase and private keys, and creating, storing and securing their backups. If you fail to maintain the appropriate security measures of your private keys, it may result in you losing access to your Wallet and control of any Digital Assets in your Wallet. If you lose or forget your seed phrase or private keys, Status will not be able to help you recover or replace them and further, Status will not be able to assist you with the recovery of your Digital Assets.
When generating an account, a randomisation process is started on your own device that generates a key pair. Status does not have visibility of or access to your private keys. You are solely responsible for storing and securing your seed phrase and private keys, and creating, storing and securing their backups. If you fail to maintain the appropriate security measures of your private keys, it may result in you losing access to your Wallet and control of any Digital Assets in your Wallet. If you lose or forget your seed phrase or private keys, Status will not be able to help you recover or replace them and further, Status will not be able to assist you with the recovery of your Digital Assets.
In order to further enhance the security of storing your private keys, you may also choose to store your keys on a keycard, such as the Status Keycard.
In order to further enhance the security of storing your private keys, you may also choose to store your keys on a keycard, such as the Status Keycard.
2.1.2 Messaging
Status Software includes messaging functionality that enables secure communication between users. We will refer to the messaging functionality of Status Software and the Status Community Spaces collectively in these terms, as “Messaging”.
Status Software includes messaging functionality that enables secure communication between users. We will refer to the messaging functionality of Status Software and the Community Spaces collectively in these terms, as “Messaging”.
Messaging uses an open source, peer-to-peer protocol with end-to-end encryption and metadata suppression to protect your messages from third parties (including Status). End-to-end encryption means that only the sender and recipient of a message can read its contents, and no one else. Peer-to-peer communication is accomplished using the Waku peer-to-peer messaging protocol, which relies on a distributed network of nodes instead of a centralised server. This means that there is no central party or server from which messages can be intercepted, modified or blocked. Learn more about Waku and how it works on Wakus relevant website.
Messaging uses an open source, peer-to-peer protocol with end-to-end encryption and metadata suppression to protect your messages from third parties (including Status). End-to-end encryption means that only the sender and recipient of a message can read its contents, and no one else. Peer-to-peer communication is accomplished using the Waku peer-to-peer messaging protocol, which relies on a distributed network of nodes instead of a centralised server. This means that there is no central party or server from which messages can be intercepted, modified or blocked. Learn more about Waku and how it works on Wakus relevant website.
Within Messaging, you will also be able to participate in Status Community Spaces. This feature allows users to create their own token-gated communities where you can create group chats and engage with your communities, while leveraging the possibilities, functionality and benefits of blockchain technology. You will also be able to create (and join) open and public communities on Status Software that are accessible to other users. We note that content in these open and public communities will be accessible to all other users of Status Software. Nonetheless, all content will still be protected by the same end-to-end encryption utilised in Status Software.
Within Messaging, you will also be able to participate in Community Spaces. This feature allows users to create and join communities with varying access and discoverability options, which may include token-gated communities, private communities and open and public communities, where you can create group chats and engage with your communities. We note that content in all Community Spaces will be accessible to the members of those spaces. For open and public communities, content will be accessible to all other users of Status Software. Nonetheless, all content, regardless of the type of community, will still be protected by the same end-to-end encryption utilised in Status Software.
2.1.2 Web 3 browser
Status Software also includes a Web 3 browser through which you may access and interact with Web 3, exchanges, marketplaces, games and more. We will refer to the Web 3 browser in these terms as the “Web 3 Browser”.
3. Privacy
Status uses an open source, peer-to-peer protocol with end-to-end encryption and metadata suppression, which by design, means that Status (and any third party) is unable to and does not collect, store, own, control or have any visibility or means of access to your identity, Wallet, browsing information, any user private keys, Digital Assets, messages, content, history of interactions, user accounts or any other user information.
Therefore, Status does not (and cannot) monetise any users data or content, such as messages or browser information and Status does not have any interest in doing so.
Status however processes a limited amount of user data to ensure the technical operation of the Status Software, enhance its functionality, and improve the user experience. For more details on this limited process of user data, please refer to our Privacy Policy.
Status processes a limited amount of user data to ensure the technical operation of the Status Software, enhance its functionality, and improve the user experience. For more details on this limited process of user data, please refer to our Privacy Policy.
If you use third party services offered through Status Software, your privacy may not be protected and you will be subject to the privacy terms and conditions of such third parties. Please refer to our full terms regarding third party services below.
4. Using third party services and interacting with Web 3
When using Status Software, you may access or use third party products, services or tools (“Third Party Services”) and interact with Web 3. Status Software is only one means of interacting with these Third Party Services and Web 3 and you can independently utilise other means and tools to do so as well.
Your interactions with Web 3 could include many aspects, such as interacting with smart contracts that reside on blockchain networks, for example to swap Digital Assets or use (crypto) bridges, or deploying your own smart contracts through Status Community Spaces. You may also interact with and participate in peer-to-peer networks which could vary in their level of decentralisation, ranging from more centralised networks controlled by a single party to networks governed by decentralised communities.
Your interactions with Web 3 could include many aspects, such as interacting with smart contracts that reside on blockchain networks, for example to swap Digital Assets or use (crypto) bridges, or deploying your own smart contracts through Community Spaces. You may also interact with and participate in peer-to-peer networks which could vary in their level of decentralisation, ranging from more centralised networks controlled by a single party to networks governed by decentralised communities.
When you use Third Party Services or interact with Web 3, you acknowledge that Status does not control or operate any Third Party Service or Web 3. These products, services, or tools are either controlled, operated, owned, or licensed by the third party providing them, or they may operate autonomously, independently of Status or any other party.
@@ -127,7 +127,7 @@ Although security is a top priority for us and many functions of Status Software
7. Content
At Status, we believe in the sovereignty of individuals and we stand for the cause of personal liberty. We aim to promote social, political, and economic freedoms through Status Software, which is built on the principles of the free flow of information and censorship resistance. Through Status Software, particularly when using Messenger and Status Community Spaces, you will be able to create and interact with various content. We consider content to include anything you (or any other user) create, post, distribute or exchange through Status Software (as well as any future functions that may be added to Status Software), whether its text, links, GIFs, emoji, photos or any other media formats.
At Status, we believe in the sovereignty of individuals and we stand for the cause of personal liberty. We aim to promote social, political, and economic freedoms through Status Software, which is built on the principles of the free flow of information and censorship resistance. Through Status Software, particularly when using Messenger and Community Spaces, you will be able to create and interact with various content. We consider content to include anything you (or any other user) create, post, distribute or exchange through Status Software (as well as any future functions that may be added to Status Software), whether its text, links, GIFs, emoji, photos or any other media formats.
You are solely responsible for any content that you create, post, distribute or submit, messages you exchange or any other activity you may engage in related to your content on or through Status Software and any harm or liability that may result from such content.
@@ -145,25 +145,35 @@ You acknowledge that Status has no means of monitoring, moderating, removing, mo
8.1 Adherence to Status Principles
One of Status goals is the widespread adoption of the decentralised web while also staying true to our Principles. These terms are designed to reflect our Principles, while providing important legal protections for Status and setting out guidelines and terms for the Status Software community of users. We ask that you use Status Software in a way that promotes and aligns with the Status Principles.
One of Status goals is the widespread adoption of the decentralised web while also staying true to our Principles. These terms are designed to reflect our Principles, while providing important legal protections for Status and setting out guidelines and terms for the Status Software community of users. We ask that you use Status Software in a way that promotes and aligns with the Status Principles, and avoid actions that may harm or disrupt the community of users.
8.2 Limitation on certain uses of and acts in Status Software
We strongly encourage users to act responsibly and ethically in their interactions and refrain from (i) inciting harm, violence or illegal activity, (ii) engaging in harassment, abuse or discrimination, and (iii) spreading false or misleading information.
You shall not, nor try to, encourage or assist others using Status Software to:
1. gain or try to gain unauthorised access to Status Software;
2. interfere with or disrupt the integrity, safety, security, availability or performance of Status Software;
3. generate accounts on Status Software through unauthorised means;
4. install or transmit on or through Status Software, any viruses, worms, malware, Trojan horses, or other harmful or destructive code or content;
5. use spam, data mining, or other unsolicited promotional methods, machine generated content, or unethical or unwanted commercial content;
6. engage in phishing, spoofing, or similar fraudulent acts;
7. knowingly spread misinformation or impersonate another person or legal entity;
8. incite, commit or threaten, harm or engage in illegal or inappropriate conduct including stalking, bullying, harassment, intimidation or abuse another individual or group;
9. engage in or organise child sexual exploitation of any kind;
10. use Status Software, if you are subject to sanctions, or otherwise designated on a list of prohibited or restricted parties as maintained by, the United Nations, the European Union or any of its member states or the Singaporean, Swiss or US government, or intend to interact or transact with such parties;
11. violate, misappropriate or infringe the rights of Status, other users of Status Software, or any other third parties in any way, including but not limited to privacy, publicity, intellectual property, confidentiality, property or other rights;
12. engage in any activity through Status Software that may be in violation of applicable law, rules or regulations in your jurisdiction;
13. interfere, disrupt, negatively affect, or inhibit other users from their use of Status Software; or
14. engage in any attack, hack, denial-of-service attack, interference, or exploit of any smart contract in connection with use of Status Software.
If you are a Community Space creator or admin, we encourage you to establish your own guidelines to foster healthy and respectful community environments for your members.
8.2 Community Governance
Community Spaces are self-sovereign environments managed independently by their creators and appointed admins. These users are solely responsible for:
1. establishing and enforcing their own community guidelines;
2. configuring access controls and permissions;
3. managing community membership, including accepting or rejecting requests;
4. moderating content and interactions within their community; and
5. taking actions against community members who violate their community guidelines or behave disruptively, including the ability to exclude or ban members.
By participating in Community Spaces, you acknowledge that community governance lies solely with community creators and their appointed admins. Status cannot monitor, moderate or intervene in community interactions or governance decisions within any Community Space, except in cases where a Community Space is created and directly managed by Status.
8.3 Limitation on certain uses of and acts in Status Software
You agree not to use Status Software, or attempt or assist others to use it, in a manner that:
1. uses unauthorised methods to create or gain access to an account on Status Software;
2. interferes with or disrupts the integrity, safety, security, availability or performance of Status Software;
3. installs or transmits on or through Status Software, any viruses, worms, malware, Trojan horses, or other harmful or destructive code or content;
4. use Status Software, if you are subject to sanctions, or otherwise designated on a list of prohibited or restricted parties as maintained by, the United Nations, the European Union or any of its member states or the Singaporean, Swiss or US government, or intend to interact or transact with such parties;
5. violate, misappropriate or infringe the rights of Status, other users of Status Software, or any other third parties in any way, including but not limited to privacy, publicity, intellectual property, confidentiality, property or other rights;
6. engage in any activity through Status Software that may be in violation of applicable law, rules or regulations in your jurisdiction;
7. interfere, disrupt, negatively affect, or inhibit other users from their use of Status Software; or
8. engage in any attack, hack, denial-of-service attack, interference, or exploit of any smart contract in connection with use of Status Software.
9. Fees
@@ -252,6 +262,7 @@ You release Status from all liability related to any claim, cause of action, con
14. Limitation of liability
Status will not be held liable to you under any contract, negligence, strict liability, or other legal or equitable theory for any lost profits, cost of procurement for substitute services, or any special, incidental, or consequential damages related to, arising from, or in any way connected with these terms, Status, your use of Status Software, particularly where Status has indicated that it is not responsible. This includes without limitation, your use of SNT or other Digital Assets (creating, distributing, transacting in or otherwise) even if Status has been advised of the possibility of such damages.
In any event, Status aggregate liability for any claims is limited to EUR 100 (one hundred Euros). This limitation of liability will apply to the extent permitted by applicable law.
+1
View File
@@ -7,6 +7,7 @@
legacy.status-im.chat.models.loading
legacy.status-im.data-store.chats
legacy.status-im.data-store.visibility-status-updates
legacy.status-im.ens.core
legacy.status-im.fleet.core
legacy.status-im.group-chats.core
legacy.status-im.log-level.core
+70 -31
View File
@@ -1,40 +1,79 @@
(ns react-native.fast-image
(:require
["react-native-fast-image" :as FastImage]
[clojure.string :as string]
[react-native.core :as rn]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[utils.transforms :as transforms]))
(def fast-image-class (reagent/adapt-react-class ^js FastImage))
(defn- build-source
[source]
(if (string? source)
{:uri source
:priority :high}
source))
(defn placeholder
[style child]
[rn/view {:style (merge style {:flex 1 :justify-content :center :align-items :center})}
child])
(defn- remove-port
[source]
(cond
(string? source) (string/replace-first source #":\d+" "")
(:uri source) (some-> source
:uri
(string/replace-first #":\d+" ""))
:else source))
(defn fast-image
(defn- placeholder
[{:keys [style fallback-content error? loaded?]}]
[rn/view
{:style (assoc style
:flex 1
:justify-content :center
:align-items :center)}
(cond
(and error? fallback-content) fallback-content
error? [rn/text "X"]
(not loaded?) [rn/activity-indicator {:animating true}])])
;; We cannot use hooks since `reactify-component` seems to ignore the functional compiler
(defn- internal-fast-image
[_]
(let [loaded? (reagent/atom false)
error? (reagent/atom false)]
(fn [{:keys [source fallback-content] :as props}]
[fast-image-class
(merge
props
{:source (if (string? source)
{:uri source
:priority :high}
source)
:on-error (fn [e]
(when-let [on-error (:on-error props)]
(on-error e))
(reset! error? true))
:on-load (fn [e]
(when-let [on-load (:on-load props)]
(on-load e))
(reset! loaded? true)
(reset! error? false))})
(let [loaded? (reagent/atom false)
error? (reagent/atom false)
on-image-error (fn [event on-error]
(when (fn? on-error) (on-error event))
(reset! error? true))
on-image-loaded (fn [event on-load]
(when (fn? on-load) (on-load event))
(reset! loaded? true)
(reset! error? false))]
(fn [{:keys [source fallback-content on-error on-load] :as props}]
[:> FastImage
(assoc props
:source (build-source source)
:on-error #(on-image-error % on-error)
:on-load #(on-image-loaded % on-load))
(when (or @error? (not @loaded?))
[placeholder (:style props)
(if @error?
(or fallback-content [rn/text "X"])
(when-not @loaded?
[rn/activity-indicator {:animating true}]))])])))
[placeholder
{:style (js->clj (:style props))
:fallback-content fallback-content
:error? @error?
:loaded? @loaded?}])])))
(defn- compare-props
[old-props new-props]
(let [old-props-clj (transforms/js->clj old-props)
new-props-clj (transforms/js->clj new-props)
old-source (some-> old-props-clj
:source
remove-port)
new-source (some-> new-props-clj
:source
remove-port)]
(and (= old-source new-source)
(= (dissoc old-props-clj :source) (dissoc new-props-clj :source)))))
(def fast-image
(-> internal-fast-image
(reagent/reactify-component)
(rn/memo compare-props)
(reagent/adapt-react-class)))
+14 -11
View File
@@ -23,19 +23,22 @@
(when f
(f data index))))
(defn dissoc-custom-props
[props]
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn))
(defn base-list-props
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn]
[{:keys [key-fn data render-fn empty-component header footer separator render-data on-drag-end-fn]
:as props}]
(merge
{:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
(cond-> {:data (to-array data)}
key-fn (assoc :keyExtractor (wrap-key-fn key-fn))
render-fn (assoc :renderItem (wrap-render-fn render-fn render-data))
separator (assoc :ItemSeparatorComponent (fn [] (reagent/as-element separator)))
empty-component (assoc :ListEmptyComponent (fn [] (reagent/as-element empty-component)))
header (assoc :ListHeaderComponent (reagent/as-element header))
footer (assoc :ListFooterComponent (reagent/as-element footer))
on-drag-end-fn (assoc :onDragEnd (wrap-on-drag-end-fn on-drag-end-fn))
:always (merge (dissoc-custom-props props))))
(defn flat-list
[props]
@@ -1,11 +1,10 @@
(ns status-im.common.scalable-avatar.style)
(defn wrapper
[{:keys [scale margin-top margin border-color]}]
[{:transform [{:scale scale}]
:margin-top margin-top
:margin-left margin
:margin-bottom margin}
{:border-width 4
:border-color border-color
:border-radius 100}])
[border-color scale]
[{:transform-origin "bottom left"
:border-width 4
:border-color border-color
:border-radius 100
:transform [{:scale 1} {:translate-y 4}]}
{:transform [{:scale scale} {:translate-y 4}]}])
+6 -26
View File
@@ -2,30 +2,14 @@
(:require [quo.core :as quo]
[react-native.reanimated :as reanimated]
[status-im.common.scalable-avatar.style :as style]))
(def scroll-animation-input-range [0 50])
(def header-extrapolation-option
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
(defn f-avatar
(def scroll-range #js [0 48])
(def scale-range #js [1 0.4])
(defn view
[{:keys [scroll-y full-name online? profile-picture customization-color border-color]}]
(let [image-scale-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[1 0.4]
header-extrapolation-option)
image-top-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 20]
header-extrapolation-option)
image-side-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[-4 -20]
header-extrapolation-option)]
[reanimated/view
{:style (style/wrapper {:scale image-scale-animation
:margin-top image-top-margin-animation
:margin image-side-margin-animation
:border-color border-color})}
(let [image-scale (reanimated/interpolate scroll-y scroll-range scale-range :clamp)]
[reanimated/view {:style (style/wrapper border-color image-scale)}
[quo/user-avatar
{:full-name full-name
:online? online?
@@ -34,7 +18,3 @@
:ring? true
:customization-color customization-color
:size :big}]]))
(defn view
[props]
[:f> f-avatar props])
@@ -10,14 +10,12 @@
[quo/documentation-drawers
{:title (i18n/label :t/forgot-your-password-info-title)
:shell? shell?}
[rn/view
{:style style/container}
[rn/view {:style style/container}
[quo/text {:size :paragraph-2} (i18n/label :t/forgot-your-password-info-description)]
[rn/view {:style style/step-container}
[quo/step {:in-blur-view? shell?} 1]
[rn/view
{:style style/step-content}
[rn/view {:style style/step-content}
[quo/text {:size :paragraph-2 :weight :semi-bold}
(i18n/label :t/forgot-your-password-info-remove-app)]
[quo/text {:size :paragraph-2} (i18n/label :t/forgot-your-password-info-remove-app-description)]]]
@@ -33,10 +31,8 @@
[rn/view {:style style/step-container}
[quo/step {:in-blur-view? shell?} 3]
[rn/view
{:style style/step-content}
[rn/view
{:style style/step-title}
[rn/view {:style style/step-content}
[rn/view {:style style/step-title}
[quo/text {:size :paragraph-2} (str (i18n/label :t/sign-up) " ")]
[quo/text {:size :paragraph-2 :weight :semi-bold}
(i18n/label :t/forgot-your-password-info-signup-with-key)]]
@@ -45,8 +41,7 @@
[rn/view {:style style/step-container}
[quo/step {:in-blur-view? shell?} 4]
[rn/view
{:style style/step-content}
[rn/view {:style style/step-content}
[quo/text {:size :paragraph-2 :weight :semi-bold}
(i18n/label :t/forgot-your-password-info-create-new-password)]
[quo/text {:size :paragraph-2}
@@ -52,7 +52,7 @@
(contains? view-ids-to-track view-id)
(conj (navigation-event (name view-id)))
(= :screen/onboarding.syncing-results view-id)
(#{:screen/onboarding.preparing-status :screen/onboarding.syncing-biometric} view-id)
(conj (key-value-event "onboarding-completed"))
(= :screen/keycard.migrate.success view-id)
@@ -276,8 +276,7 @@
(defn chat-user
[item]
[rn/view
{:style (merge style/container {:margin-horizontal 0})}
[rn/view {:style (assoc style/container :margin-horizontal 0)}
[chat-item item]])
(defn chat-list-item
+5 -6
View File
@@ -62,8 +62,8 @@
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
:keyboard-should-persist-taps :always
:data items
:render-fn (fn [item]
(chat-list-item/chat-list-item item theme))
:render-data {:theme theme}
:render-fn chat-list-item/chat-list-item
:scroll-event-throttle 8
:content-container-style {:padding-bottom
shell.constants/floating-shell-button-height
@@ -94,8 +94,7 @@
{:selected-tab :tab/contacts
:tab->content (empty-state-content theme)}]
[rn/section-list
{:ref (when (not-empty items)
set-scroll-ref)
{:ref (when (seq items) set-scroll-ref)
:key-fn :public-key
:get-item-layout get-item-layout
:content-inset-adjustment-behavior :never
@@ -108,8 +107,8 @@
:sticky-section-headers-enabled false
:render-section-header-fn contact-list/contacts-section-header
:render-section-footer-fn contact-list/contacts-section-footer
:render-fn (fn [data]
(contact-item-render data theme))
:render-data {:theme theme}
:render-fn contact-item-render
:scroll-event-throttle 8
:on-scroll #(common.banner/set-scroll-shared-value
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
@@ -15,13 +15,20 @@
(rf/dispatch [:open-modal :screen/keycard.empty-create]))
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
(defn- backup-recovery-phrase-success
[masked-seed-phrase]
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/confirm-backup
{:masked-seed-phrase masked-seed-phrase
:on-success #(rf/dispatch [:keycard/create.phrase-backed-up %])}]))
(rf/reg-event-fx :keycard/create.get-phrase
(fn [{:keys [db]}]
{:db (assoc-in db [:keycard :create] nil)
:fx [[:dispatch [:navigate-back]]
[:dispatch
[:open-modal :screen/backup-recovery-phrase-dark
{:on-success #(rf/dispatch [:keycard/create.phrase-backed-up %])}]]]}))
{:on-success backup-recovery-phrase-success}]]]}))
(rf/reg-event-fx :keycard/create.phrase-backed-up
(fn [{:keys [db]} [masked-phrase-vector]]
@@ -69,6 +69,13 @@
(rf/dispatch [:keycard/migration.continue])
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
(defn- backup-recovery-phrase-success
[masked-seed-phrase]
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/confirm-backup
{:masked-seed-phrase masked-seed-phrase
:on-success #(rf/dispatch [:keycard/migration.phrase-backed-up])}]))
(rf/reg-event-fx :keycard/migration.get-phrase
(fn [{:keys [db]}]
(let [mnemonic (get-in db [:profile/profile :mnemonic])]
@@ -80,7 +87,7 @@
{:on-success #(rf/dispatch [:keycard/migration.phrase-entered %])}]]
[:dispatch
[:open-modal :screen/backup-recovery-phrase-dark
{:on-success #(rf/dispatch [:keycard/migration.phrase-backed-up])
{:on-success backup-recovery-phrase-success
:masked-seed-phrase (security/mask-data mnemonic)}]])]})))
(rf/reg-event-fx :keycard/migration.phrase-entered
@@ -6,7 +6,6 @@
[status-im.common.biometric.utils :as biometric]
[status-im.common.resources :as resources]
[status-im.contexts.onboarding.enable-biometrics.style :as style]
[status-im.navigation.state :as state]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -25,7 +24,7 @@
bio-type-label (biometric/get-label-by-type supported-biometric-type)
profile-color (or (:color (rf/sub [:onboarding/profile]))
(rf/sub [:profile/customization-color]))
syncing-results? (= :screen/onboarding.syncing-results @state/root-id)
syncing? (= (rf/sub [:view-id]) :screen/onboarding.syncing-biometric)
biometric-type (rf/sub [:biometrics/supported-type])]
[rn/view {:style (style/buttons insets)}
[quo/button
@@ -39,10 +38,8 @@
{:accessibility-label :maybe-later-button
:background :blur
:type :grey
:on-press #(rf/dispatch (if syncing-results?
[:navigate-to-within-stack
[:screen/onboarding.enable-notifications
:screen/onboarding.enable-biometrics]]
:on-press #(rf/dispatch (if syncing?
[:onboarding/finish-onboarding false]
[:onboarding/create-account-and-login]))
:container-style {:margin-top 12}}
(i18n/label :t/maybe-later)]]))
+1 -15
View File
@@ -38,12 +38,6 @@
(fn [{:keys [db]}]
{:db (dissoc db :onboarding/navigated-to-enter-seed-phrase-from-screen)}))
(rf/reg-event-fx :onboarding/navigate-to-enable-notifications-from-syncing
(fn [{:keys [db]}]
{:db (dissoc db :onboarding/profile)
:dispatch [:navigate-to-within-stack
[:screen/onboarding.enable-notifications :screen/onboarding.enable-biometrics]]}))
(rf/reg-event-fx :onboarding/navigate-to-enable-notifications
(fn [{:keys [db]}]
{:dispatch [:navigate-to-within-stack
@@ -113,14 +107,6 @@
[:navigate-to-within-stack [:screen/onboarding.enable-biometrics from-screen]]
[:onboarding/create-account-and-login])]]})))
(rf/reg-event-fx
:onboarding/navigate-to-enable-biometrics
(fn [{:keys [db]}]
(let [supported-type (get-in db [:biometrics :supported-type])]
{:dispatch (if supported-type
[:open-modal :screen/onboarding.enable-biometrics]
[:open-modal :screen/onboarding.enable-notifications])})))
(rf/reg-event-fx
:onboarding/seed-phrase-validated
(fn [{:keys [db]} [seed-phrase key-uid]]
@@ -200,7 +186,7 @@
(rf/dispatch [:onboarding/set-auth-method auth-method])
(when syncing?
(rf/dispatch
[:onboarding/navigate-to-enable-notifications-from-syncing])))
[:onboarding/finish-onboarding false])))
:on-error #(log/error "failed to save biometrics"
{:key-uid key-uid
:error %})}])]})))
@@ -73,7 +73,6 @@
[quo/bottom-actions
(cond->
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
:actions :two-vertical-actions
:description :bottom
:description-text [terms]}
@@ -21,9 +21,10 @@
:background-color (when-not in-onboarding? colors/neutral-80-opa-80-blur)})
(defn page-illustration
[width]
[width pairing-progress?]
{:flex 1
:width width
:align-items :center
:margin-vertical (when pairing-progress? 24)
:align-self :center
:justify-content :center})
@@ -18,11 +18,10 @@
[quo/text-combinations
{:container-style {:margin-top 56 :margin-horizontal 20}
:title (i18n/label (if pairing-progress?
:t/sync-devices-title
:t/sync-profile-title
:t/sync-devices-error-title))
:description (i18n/label (if pairing-progress?
:t/sync-devices-sub-title
:t/sync-devices-error-sub-title))
:description (when-not pairing-progress?
(i18n/label :t/sync-devices-error-sub-title))
:title-accessibility-label :progress-screen-title
:description-accessibility-label :progress-screen-sub-title}])
@@ -42,31 +41,31 @@
(defn try-again-button
[profile-color logged-in?]
[quo/bottom-actions
{:actions (if logged-in? :one-action :two-actions)
:blur? true
:button-one-label (i18n/label :t/recovery-phrase)
:button-one-props {:type :primary
:accessibility-label :try-seed-phrase-button
:customization-color profile-color
:container-style {:flex 1}
:size 40
:on-press navigate-to-enter-seed-phrase}
(if logged-in? :button-one-label :button-two-label)
(i18n/label :t/try-again)
(if logged-in? :button-one-props :button-two-props)
{:type (if logged-in? :primary :grey)
:accessibility-label :try-again-later-button
:customization-color profile-color
:container-style {:flex 1}
:size 40
:on-press #(try-again logged-in?)}}])
(let [two-vertical-actions-height 116]
[quo/bottom-actions
{:actions (if logged-in? :one-action :two-vertical-actions)
:blur? true
:container-style {:height (when-not logged-in? two-vertical-actions-height)}
:button-two-label (i18n/label :t/use-recovery-phrase)
:button-two-props {:type :primary
:accessibility-label :try-seed-phrase-button
:customization-color profile-color
:size 40
:on-press navigate-to-enter-seed-phrase}
:button-one-label
(i18n/label :t/try-again)
:button-one-props
{:type (if logged-in? :primary :grey)
:accessibility-label :try-again-later-button
:customization-color profile-color
:size 40
:on-press #(try-again logged-in?)}}]))
(defn- illustration
[pairing-progress?]
[rn/image
{:resize-mode :contain
:style (style/page-illustration (:width (rn/get-window)))
:style (style/page-illustration (:width (rn/get-window)) pairing-progress?)
:source (resources/get-image (if pairing-progress? :syncing-devices :syncing-wrong))}])
(defn view
@@ -83,7 +82,12 @@
[quo/page-nav {:type :no-title :background :blur}]
[page-title pairing-progress?]
[illustration pairing-progress?]
(when-not (pairing-progress pairing-status)
(if pairing-progress?
[quo/information-box
{:type :default
:blur? true
:style {:margin-vertical 11 :margin-horizontal 12}}
(i18n/label :t/sync-devices-sub-title)]
[try-again-button profile-color logged-in?])]))
(defn view-onboarding
@@ -1,43 +0,0 @@
(ns status-im.contexts.onboarding.syncing.results.style
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
(def absolute-fill
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(defn page-container
[top]
{:flex 1
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:padding-top top
:padding-bottom 20
:background-color colors/neutral-80-opa-80-blur})
(defn content
[translate-x]
(reanimated/apply-animations-to-style
{:transform [{:translate-x translate-x}]}
{:margin-top 56
:margin-bottom 26
:flex 1}))
(def current-device
{:margin-bottom 19})
(def device-list
{:flex 1
:margin-top 12
:padding-horizontal 20})
(def continue-button
{:margin-top 20
:padding-horizontal 20})
@@ -1,84 +0,0 @@
(ns status-im.contexts.onboarding.syncing.results.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.constants :as constants]
[status-im.contexts.onboarding.common.background.view :as background]
[status-im.contexts.onboarding.syncing.results.style :as style]
[status-im.contexts.syncing.device.view :as device]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn page-title
[]
[quo/text-combinations
{:container-style {:margin-horizontal 20}
:title (i18n/label :t/sync-devices-complete-title)
:title-accessibility-label :sync-devices-title
:description (i18n/label :t/sync-devices-complete-sub-title)
:description-accessibility-label :sync-devices-complete-sub-title}])
(defn current-device
[installation]
[rn/view {:style style/current-device}
[device/view
(merge installation
{:this-device? true})]])
(defn devices-list
[]
(let [installations (rf/sub [:pairing/enabled-installations])
this-device (first installations)
other-devices (rest installations)]
[rn/view {:style style/device-list}
[current-device this-device]
[quo/text
{:accessibility-label :synced-with-sub-title
:weight :regular
:size :paragraph-2
:style {:color colors/white-opa-40}}
(i18n/label :t/synced-with)]
[rn/flat-list
{:data other-devices
:shows-vertical-scroll-indicator false
:key-fn :installation-id
:render-fn device/view}]]))
(defn continue-button
[on-press]
(let [profile-color (rf/sub [:profile/customization-color])]
[quo/button
{:on-press (fn []
(when on-press
(on-press))
(rf/dispatch [:onboarding/navigate-to-enable-biometrics]))
:accessibility-label :continue-button
:customization-color profile-color
:container-style style/continue-button}
(i18n/label :t/continue)]))
(defn- f-view
[]
(let [top (safe-area/get-top)
translate-x (reanimated/use-shared-value 0)
window-width (:width (rn/get-window))]
[rn/view {:style (style/page-container top)}
[rn/view {:style style/absolute-fill}
[background/view true]]
[reanimated/view
{:style (style/content translate-x)}
[page-title]
[devices-list]
[continue-button
#(reanimated/animate-shared-value-with-delay translate-x
(- window-width)
constants/onboarding-modal-animation-duration
:linear
200)]]]))
(defn view
[]
[:f> f-view])
@@ -5,9 +5,11 @@
[utils.re-frame :as rf]))
(rf/reg-event-fx :profile/update-local-picture
(fn [{:keys [db]} [images]]
(fn [{:keys [db now]} [images]]
{:db (if images
(assoc-in db [:profile/profile :images] images)
(assoc-in db
[:profile/profile :images]
(map #(assoc % :clock now) images))
(update db :profile/profile dissoc :images))}))
(rf/reg-event-fx :profile/edit-profile-picture-success
@@ -37,18 +37,19 @@
;; login phase 1: we want to load and show chats faster, so we split login into 2 phases
(rf/reg-event-fx :profile.login/login-existing-profile
(fn [{:keys [db]} [settings-data account]]
(let [settings (data-store.settings/rpc->settings settings-data)
profile-overview (profile.rpc/rpc->profiles-overview account)
log-level (or (:log-level settings) config/log-level)
pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)
new-db (-> db
(assoc :profile/profile
(merge profile-overview
settings
{:log-level log-level}))
(assoc-in [:activity-center :loading?] true)
(dissoc :centralized-metrics/onboarding-enabled?))
keycard? (get-in new-db [:profile/profile :keycard-pairing])]
(let [settings (data-store.settings/rpc->settings settings-data)
profile-overview (profile.rpc/rpc->profiles-overview account)
log-level (or (:log-level settings) config/log-level)
pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)
biometric-supported-type (get-in db [:biometrics :supported-type])
new-db (-> db
(assoc :profile/profile
(merge profile-overview
settings
{:log-level log-level}))
(assoc-in [:activity-center :loading?] true)
(dissoc :centralized-metrics/onboarding-enabled?))
keycard? (get-in new-db [:profile/profile :keycard-pairing])]
{:db (cond-> new-db
pairing-completed? (dissoc :syncing))
:fx (into [[:json-rpc/call
@@ -81,10 +82,10 @@
(when keycard?
[:dispatch [:centralized-metrics/track :metric/keycard-login]])]
(cond
pairing-completed?
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
(and pairing-completed? biometric-supported-type)
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-biometric]]]
(get db :onboarding/new-account?)
(or pairing-completed? (get db :onboarding/new-account?))
[[:dispatch [:onboarding/finalize-setup]]
[:dispatch [:onboarding/finish-onboarding false]]]
@@ -129,8 +129,10 @@
[:dispatch [:hide-bottom-sheet]]]})))
(rf/reg-event-fx :profile.settings/update-local-picture
(fn [{:keys [db]} [images]]
{:db (assoc-in db [:profile/profile :images] images)}))
(fn [{:keys [db now]} [images]]
{:db (assoc-in db
[:profile/profile :images]
(map #(assoc % :clock now) images))}))
(rf/reg-event-fx :profile.settings/mnemonic-was-shown
(fn [_]
@@ -19,7 +19,7 @@
{:d "M20 20V0H0C11 0 20 9 20 20Z"
:fill background-color}]])
(defn f-view
(defn view
[{:keys [scroll-y customization-color theme]}]
(let [background-color (colors/resolve-color customization-color theme 40)
opacity-animation (reanimated/interpolate scroll-y
@@ -30,7 +30,3 @@
[reanimated/view {:style (style/radius-container opacity-animation)}
[left-radius background-color]
[right-radius background-color]]]))
(defn view
[props]
[:f> f-view props])
@@ -1,11 +1,11 @@
(ns status-im.contexts.profile.settings.header.style)
(ns status-im.contexts.profile.settings.header.style
(:require [quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(def avatar-row-wrapper
{:display :flex
:padding-left 20
{:padding-left 20
:padding-right 12
:margin-top -60
:margin-bottom -4
:margin-top -65
:align-items :flex-end
:justify-content :space-between
:flex-direction :row})
@@ -21,3 +21,9 @@
{:opacity opacity-animation
:flex-direction :row
:justify-content :space-between})
(defn avatar-border-color
[theme]
(if platform/android?
colors/neutral-80-opa-80 ;; Fix is not needed because Android doesn't use blur
(colors/theme-colors colors/border-avatar-light colors/neutral-80-opa-80 theme)))
@@ -1,6 +1,5 @@
(ns status-im.contexts.profile.settings.header.view
(:require [quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[status-im.common.scalable-avatar.view :as avatar]
@@ -11,49 +10,46 @@
[status-im.contexts.profile.utils :as profile.utils]
[utils.re-frame :as rf]))
(defn- on-state-dropdown-press
[]
(rf/dispatch [:show-bottom-sheet
{:shell? true
:theme :dark
:content visibility-sheet/view}]))
(defn view
[{:keys [scroll-y]}]
(let [theme (quo.theme/use-theme)
app-theme (rf/sub [:theme])
{:keys [public-key emoji-hash bio] :as profile} (rf/sub [:profile/profile-with-image])
online? (rf/sub [:visibility-status-updates/online?
public-key])
status (rf/sub
[:visibility-status-updates/visibility-status-update
public-key])
customization-color (rf/sub [:profile/customization-color])
full-name (profile.utils/displayed-name profile)
profile-picture (profile.utils/photo profile)
{:keys [status-title status-icon]} (header.utils/visibility-status-type-data status)
border-theme app-theme]
(let [app-theme (rf/sub [:theme])
{:keys [public-key emoji-hash bio]
:as profile} (rf/sub [:profile/profile-with-image])
online? (rf/sub [:visibility-status-updates/online? public-key])
status (rf/sub [:visibility-status-updates/visibility-status-update public-key])
customization-color (rf/sub [:profile/customization-color])
full-name (profile.utils/displayed-name profile)
profile-picture (profile.utils/photo profile)
{:keys [status-title
status-icon]} (header.utils/visibility-status-type-data status)]
[:<>
[header.shape/view
{:scroll-y scroll-y
:customization-color customization-color
:theme theme}]
:customization-color customization-color}]
[rn/view {:style style/avatar-row-wrapper}
[avatar/view
{:scroll-y scroll-y
:display-name full-name
:full-name full-name
:online? online?
:border-color (colors/theme-colors colors/border-avatar-light
colors/neutral-80-opa-80
border-theme)
:border-color (style/avatar-border-color app-theme)
:customization-color customization-color
:profile-picture profile-picture}]
[rn/view {:style {:margin-bottom 4}}
[quo/dropdown
{:background :blur
:size :size-32
:type :outline
:icon? true
:no-icon-color? true
:icon-name status-icon
:on-press #(rf/dispatch [:show-bottom-sheet
{:shell? true
:theme :dark
:content (fn [] [visibility-sheet/view])}])}
status-title]]]
[quo/dropdown
{:background :blur
:size :size-32
:type :outline
:icon? true
:no-icon-color? true
:icon-name status-icon
:on-press on-state-dropdown-press}
status-title]]
[quo/page-top
{:title-accessibility-label :username
:emoji-dash emoji-hash
@@ -1,7 +1,7 @@
(ns status-im.contexts.profile.settings.view
(:require [oops.core :as oops]
[quo.core :as quo]
[quo.theme :as quo.theme]
[quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
@@ -44,19 +44,6 @@
(rf/reg-event-fx :wallet/confirm-account-origin confirm-account-origin)
(defn store-new-seed-phrase
[{:keys [db]} [{:keys [seed-phrase]}]]
{:db (update-in db
[:wallet :ui :create-account :new-keypair]
assoc
:seed-phrase
seed-phrase)
:fx [[:dispatch-later
[{:ms 20
:dispatch [:navigate-to :screen/wallet.confirm-backup]}]]]})
(rf/reg-event-fx :wallet/store-new-seed-phrase store-new-seed-phrase)
(defn seed-phrase-validated
[{:keys [db]} [seed-phrase key-uid on-error]]
(let [keypair-already-added? (-> db
@@ -14,15 +14,6 @@
result-db (:db effects)]
(is (match? result-db expected-db))))
(deftest store-seed-phrase-test
(let [db {}
props [{:seed-phrase "test-secret" :random-phrase "random-test"}]
expected-db {:wallet {:ui {:create-account {:new-keypair {:seed-phrase "test-secret"
:random-phrase "random-test"}}}}}
effects (events/store-new-seed-phrase {:db db} props)
result-db (:db effects)]
(is (match? result-db expected-db))))
(deftest store-account-generated-test
(let [db {:wallet {:ui {:create-account
{:new-keypair {:seed-phrase "test-secret"
@@ -61,15 +61,43 @@
:margin-right 12)]
[button (assoc params :word (second options))]])
(defn- complete-backup-sheet
[on-success]
(let [customization-color (rf/sub [:profile/customization-color])
[checked? set-checked] (rn/use-state false)]
[:<>
[quo/drawer-top {:title (i18n/label :t/complete-backup)}]
[quo/text
{:style style/cheat-description}
(i18n/label :t/ensure-written-recovery)]
[quo/disclaimer
{:checked? checked?
:container-style {:margin-horizontal 20}
:on-change #(set-checked (not checked?))}
(i18n/label :t/written-seed-ready)]
[quo/bottom-actions
{:actions :two-actions
:button-one-label (i18n/label :t/done)
:button-one-props {:disabled? (not checked?)
:customization-color customization-color
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(on-success))}
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet]))}}]]))
(defn view
[]
(let [random-indices (random-selection)
quiz-index (reagent/atom 0)
incorrect-count (reagent/atom 0)
show-error? (reagent/atom false)
{:keys [seed-phrase]} (rf/sub [:wallet/create-account-new-keypair])
unmasked-seed-phrase (security/safe-unmask-data seed-phrase)
random-phrase (reagent/atom [])]
(let [random-indices (random-selection)
quiz-index (reagent/atom 0)
incorrect-count (reagent/atom 0)
show-error? (reagent/atom false)
{:keys [on-success
masked-seed-phrase]} (rf/sub [:get-screen-params])
unmasked-seed-phrase (security/safe-unmask-data masked-seed-phrase)
random-phrase (reagent/atom [])]
(fn []
(rn/use-mount
(fn []
@@ -86,10 +114,10 @@
(reset! quiz-index (inc @quiz-index)))
(reset! incorrect-count 0)
(reset! show-error? false)
(when (= @quiz-index questions-count)
(rf/dispatch [:navigate-to
:screen/wallet.keypair-name
{:workflow :new-keypair}])))
(when (and on-success (= @quiz-index questions-count))
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [complete-backup-sheet
on-success])}])))
(do
(when (> @incorrect-count 0)
(rf/dispatch [:show-bottom-sheet
@@ -98,7 +126,7 @@
(reset! show-error? true))))]
[rn/view {:style {:flex 1}}
[quo/page-nav
{:icon-name :i/arrow-left
{:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :top-bar}]
[quo/page-top
@@ -10,6 +10,13 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- backup-recovery-phrase-success
[masked-seed-phrase]
(rf/dispatch [:navigate-to :screen/confirm-backup
{:masked-seed-phrase masked-seed-phrase
:on-success #(rf/dispatch [:navigate-to :screen/wallet.keypair-name
{:workflow :new-keypair}])}]))
(defn- keypair-options
[]
[quo/action-drawer
@@ -17,10 +24,7 @@
:accessibility-label :generate-new-keypair
:label (i18n/label :t/generate-new-keypair)
:on-press #(rf/dispatch [:navigate-to :screen/backup-recovery-phrase
{:on-success (fn [masked-seed-phrase]
(rf/dispatch [:wallet/store-new-seed-phrase
{:seed-phrase
masked-seed-phrase}]))}])}
{:on-success backup-recovery-phrase-success}])}
{:icon :i/seed
:accessibility-label :import-using-phrase
:label (i18n/label :t/import-using-phrase)
+4 -3
View File
@@ -26,9 +26,10 @@
:id :screen/profile.profiles
:options (options/dark-root-options)}}]}}}
:screen/onboarding.syncing-results
{:root {:stack {:children [{:component {:name :screen/onboarding.syncing-results
:id :screen/onboarding.syncing-results
:screen/onboarding.syncing-biometric
{:root {:stack {:id :screen/onboarding.enable-biometrics
:children [{:component {:name :screen/onboarding.enable-biometrics
:id :screen/onboarding.enable-biometrics
:options (options/dark-root-options)}}]}}}})
(defn old-roots
+2 -11
View File
@@ -53,7 +53,6 @@
[status-im.contexts.onboarding.share-usage.view :as onboarding.share-usage]
[status-im.contexts.onboarding.sign-in.view :as sign-in]
[status-im.contexts.onboarding.syncing.progress.view :as syncing-devices]
[status-im.contexts.onboarding.syncing.results.view :as syncing-results]
[status-im.contexts.preview.feature-flags.view :as feature-flags]
[status-im.contexts.preview.quo.component-preview.view :as component-preview]
[status-im.contexts.preview.quo.main :as quo.preview]
@@ -542,7 +541,7 @@
:alias-id :wallet.create-account-edit-derivation-path}
:component wallet-edit-derivation-path/view}
{:name :screen/wallet.confirm-backup
{:name :screen/confirm-backup
:metrics {:track? true
:alias-id :wallet.create-account-backup-new-keypair-confirm}
:options {:insets {:top? true :bottom? true}}
@@ -855,13 +854,6 @@
:popGesture false}
:component syncing-devices/view-onboarding})
(def onboarding-syncing-results
{:name :screen/onboarding.syncing-results
:metrics {:track? true
:alias-id :onboarding.syncing-completed}
:options {:theme :dark}
:component syncing-results/view})
(def onboarding-screens
[onboarding-intro
onboarding-create-profile
@@ -875,8 +867,7 @@
onboarding-sign-in-intro
onboarding-sign-in
onboarding-syncing-progress
onboarding-syncing-progress-intro
onboarding-syncing-results])
onboarding-syncing-progress-intro])
(def keycard-screens
[{:name :screen/keycard.check
+19 -1
View File
@@ -65,6 +65,7 @@
(fn [[profiles port font-file theme] [_ target-key-uid]]
(let [{:keys [images ens-name? customization-color] :as profile} (get profiles target-key-uid)
image-name (-> images first :type)
image-clock (-> images first :clock)
override-ring? (when ens-name? false)]
(when (and profile port)
{:config
@@ -75,6 +76,7 @@
:image-name image-name
:key-uid target-key-uid
:theme theme
:clock image-clock
:override-ring? override-ring?}}
{:type :initials
:options {:port port
@@ -100,12 +102,24 @@
(fn [{:keys [public-key]}]
public-key))
(re-frame/reg-sub
:profile/light-client-enabled?
:<- [:profile/profile]
(fn [profile]
(get-in profile [:wakuv2-config :LightClient])))
(re-frame/reg-sub
:profile/store-confirmations-enabled?
:<- [:profile/profile]
(fn [profile]
(get-in profile [:wakuv2-config :EnableStoreConfirmationForMessagesSent])))
(re-frame/reg-sub
:profile/peer-syncing-enabled?
:<- [:profile/profile]
(fn [profile]
(:peer-syncing-enabled? profile)))
(re-frame/reg-sub
:profile/telemetry-enabled?
:<- [:profile/profile]
@@ -224,7 +238,10 @@
customization-color]} profile
ens-name? (or ens-name? (seq ens-names))
avatar-opts (assoc avatar-opts :override-ring? (when ens-name? false))
images-with-uri (mapv (fn [{key-uid :keyUid image-name :type :as image}]
images-with-uri (mapv (fn [{key-uid :keyUid
image-name :type
image-clock :clock
:as image}]
(assoc image
:config
{:type :account
@@ -232,6 +249,7 @@
{:port port
:ratio pixel-ratio/ratio
:image-name image-name
:clock image-clock
:key-uid key-uid
:theme theme}
avatar-opts)}))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "58707e787513f883ce3d42826e9989a3e71b9d4b",
"commit-sha1": "58707e787513f883ce3d42826e9989a3e71b9d4b",
"src-sha256": "1a4kkazy3qkpkgh88j41jqmlx9gwrv2f66b1dzlxqljg5v2f1d10"
"version": "v8.1.0",
"commit-sha1": "df1c8788e42784ba3b8ed3e7c5bd3ea530028410",
"src-sha256": "1yxcswrj7p1m96lx795vbqlgjlmpkgzaw7l8f2k4ni3d7vmlklnw"
}
+4 -1
View File
@@ -8,4 +8,7 @@ filelock~=3.16.1
python-dateutil~=2.8.1
ImageHash~=4.3.1
Pillow~=10.0.0
pytz~=2020.4
pytest-xdist==3.2.0
pytz~=2020.4
PyGithub==1.55
typing-extensions==4.12.2
@@ -693,7 +693,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
chat.click()
else:
self.home_2.contacts_tab.click()
chat.click()
chat.find_element().click()
self.chat_2.profile_send_message_button.click()
lost_messages = list()
@@ -194,7 +194,8 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[0].just_fyi("Admin relogins")
self.chats[0].reopen_app(user_name=self.usernames[0])
self.homes[0].get_chat(self.chat_name).click()
if not self.chats[0].chat_message_input.is_element_displayed(15):
self.homes[0].get_chat(self.chat_name).click()
self.chats[0].just_fyi("Admin checks reactions count after relogin")
message_element = self.chats[0].chat_element_by_text(message)
@@ -484,7 +485,6 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[0], muted_message[:25])):
self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message)
chat.click()
chat.click()
if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30):
self.errors.append(
"Message '%s' is not shown in chat for %s (Member 1) after mute" % (muted_message, self.usernames[1]))
@@ -521,7 +521,6 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[2], unmuted_message)):
self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
chat.click()
chat.click()
if not self.chats[1].chat_element_by_text(unmuted_message).is_element_displayed(30):
self.errors.append(
"Message '%s' is not shown in chat for %s (Member 1) after unmute" % (
@@ -1,5 +1,6 @@
import datetime
import random
import time
import emoji
import pytest
@@ -321,10 +322,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.get_chat(self.username_2).wait_for_visibility_of_element()
self.chat_1 = self.home_1.get_chat(self.username_2).click()
self.chat_1.send_message('hey')
self.chat_2 = self.home_2.get_chat(self.username_1).click_until_presence_of_element(
ChatView(self.drivers[1]).chat_message_input)
# self.chat_2.send_message(self.text_message)
# [home.click_system_back_button_until_element_is_shown() for home in self.homes]
self.chat_2 = self.home_2.get_chat(self.username_1).click()
self.home_1.navigate_back_to_home_view()
self.home_1.just_fyi("Open community to message")
@@ -920,6 +918,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
expected_message = ""
try:
self.channel_2.element_by_translation_id("edit-message").double_click()
time.sleep(1)
for i in range(29, 32):
self.channel_2.driver.press_keycode(i)
input_text = self.channel_2.chat_message_input.text
@@ -1059,7 +1058,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.errors.append("Not all channels are shown in community before joining: %s" % not_shown)
chan = self.community_2.get_channel("general")
if chan.is_element_displayed():
chan.click()
chan.find_element().click()
if not self.channel_2.chat_element_by_text(control_message_general_chat).is_element_displayed(20):
self.errors.append("Message in community channel is not visible for user before join")
else:
@@ -1175,7 +1174,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.errors.append("Pending status is not displayed")
general_channel = self.community_2.get_channel("general")
if general_channel.is_element_displayed():
general_channel.click()
general_channel.find_element().click()
if not self.channel_2.chat_element_by_text(control_message_general_chat).is_element_displayed(30):
self.errors.append(
"Message in community channel is not visible for user before join, it was indicated as " \
+2 -2
View File
@@ -46,7 +46,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.sign_in_2.just_fyi("Device 2: try syncing profile")
self.sign_in_2.sync_profile(sync_code=self.sync_code)
self.sign_in_2.progress_screen_title.wait_for_element()
assert self.sign_in_2.progress_screen_title.text == "Oops, somethings wrong"
assert self.sign_in_2.progress_screen_title.text == "Oops, somethings wrong!"
self.home_3.chats_tab.is_element_displayed() # just pinging 3rd device to save the connection
@marks.testrail_id(740221)
@@ -258,7 +258,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.sign_in_2.explore_new_status_button.click_if_shown()
self.sign_in_2.sync_profile(sync_code=self.sync_code, first_user=False)
self.sign_in_2.progress_screen_title.wait_for_element()
assert self.sign_in_2.progress_screen_title.text == "Oops, somethings wrong"
assert self.sign_in_2.progress_screen_title.text == "Oops, somethings wrong!"
self.sign_in_2.just_fyi("Device 2: try invalid passphrase")
self.sign_in_2.try_seed_phrase_button.click()
+5 -13
View File
@@ -100,21 +100,13 @@ class BaseElement(object):
self.click()
def click_until_presence_of_element(self, desired_element, attempts=4):
counter = 0
self.driver.info("Click until `%s` by `%s`: `%s` will be presented" % (
desired_element.name, desired_element.by, desired_element.locator))
while not desired_element.is_element_displayed(1) and counter <= attempts:
try:
el = self.find_element()
try:
el.click()
except AttributeError:
raise Exception("Element: %s\n Element type: %s" % (el, type(el)))
return self.navigate()
except (NoSuchElementException, TimeoutException):
counter += 1
else:
self.driver.info("%s element not found" % desired_element.name)
for _ in range(attempts):
self.find_element().click()
if desired_element.is_element_displayed(2):
return
raise NoSuchElementException("%s element not found" % desired_element.name)
def double_click(self):
self.driver.info('Double tap on: %s' % self.name)
+4 -6
View File
@@ -54,7 +54,7 @@ class ChatElement(SilentButton):
def click(self):
if self.community:
from views.chat_view import CommunityView
desired_element = CommunityView(self.driver).community_description_text
desired_element = CommunityView(self.driver).community_title
else:
from views.chat_view import ChatView
desired_element = ChatView(self.driver).chat_message_input
@@ -400,7 +400,7 @@ class HomeView(BaseView):
self.close_activity_centre.wait_for_rendering_ended_and_click()
self.chats_tab.wait_for_visibility_of_element()
def add_contact(self, public_key, nickname='', remove_from_contacts=False):
def add_contact(self, public_key, nickname=''):
self.driver.info("Adding user to Contacts via chats > add new contact")
self.new_chat_button.click_until_presence_of_element(self.add_a_contact_chat_bottom_sheet_button)
self.add_a_contact_chat_bottom_sheet_button.click()
@@ -411,9 +411,7 @@ class HomeView(BaseView):
chat.element_by_translation_id("user-found").wait_for_visibility_of_element()
if not chat.view_profile_new_contact_button.is_element_displayed():
chat.click_system_back_button()
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_block_contact_button)
if remove_from_contacts and chat.profile_remove_from_contacts.is_element_displayed():
chat.profile_remove_from_contacts.click()
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_send_contact_request_button)
chat.profile_send_contact_request_button.click()
chat.contact_request_message_input.send_keys("hi")
chat.confirm_send_contact_request_button.click()
@@ -524,7 +522,7 @@ class HomeView(BaseView):
def get_username(self):
self.toast_content_element.wait_for_invisibility_of_element()
profile_view = self.get_profile_view()
profile_view = self.profile_button.click_until_presence_of_element(profile_view.default_username_text)
self.profile_button.click_until_presence_of_element(profile_view.default_username_text)
profile_view.default_username_text.wait_for_element(3)
username = profile_view.default_username_text.text
profile_view.click_system_back_button()
+4 -4
View File
@@ -73,14 +73,14 @@ class SignInView(BaseView):
def create_user(self, password=common_password, first_user=True, enable_notifications=False):
self.driver.info("## Creating new multiaccount with password:'%s'" % password, device=False)
if first_user:
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
self.create_profile_button.click()
self.maybe_later_button.wait_and_click()
else:
if self.show_profiles_button.is_element_displayed(20):
self.show_profiles_button.click()
self.plus_profiles_button.click()
self.create_new_profile_button.click()
self.start_fresh_lets_go_button.click_until_presence_of_element(self.profile_title_input)
self.start_fresh_lets_go_button.click()
self.set_password(password)
self.chats_tab.wait_for_visibility_of_element(30)
self.driver.info("## New multiaccount is created successfully!", device=False)
@@ -97,14 +97,14 @@ class SignInView(BaseView):
if not after_sync_code:
if not second_user:
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
self.create_profile_button.click()
self.maybe_later_button.wait_and_click()
else:
self.plus_profiles_button.click()
self.create_new_profile_button.click()
self.use_recovery_phrase_button.click()
self.passphrase_edit_box.send_keys(passphrase)
self.continue_button.click_until_presence_of_element(self.profile_title_input)
self.continue_button.click()
self.set_password(password)
self.chats_tab.wait_for_visibility_of_element(30)
self.driver.info("## Multiaccount is recovered successfully!", device=False)
+7 -3
View File
@@ -458,6 +458,7 @@
"community-thumbnail-image": "Thumbnail image",
"community-thumbnail-upload": "Upload",
"community-unmuted": "Community unmuted",
"complete-backup": "Complete backup",
"complete-hardwallet-setup": "This card is now linked. You need it to sign transactions and unlock your keys",
"completed": "Completed",
"confirm": "Confirm",
@@ -971,6 +972,7 @@
"ens-your-your-name": "Your ENS name",
"ensure-both-devices-are-on-the-same-network": "Ensure both devices are on the same network",
"ensure-qr-code-is-in-focus-to-scan": "Ensure that the QR code is in focus to scan",
"ensure-written-recovery": "Ensure you have written down your recovery phrase and have a safe place to keep it. Remember, anyone who has your recovery phrase has access to your funds.",
"enter-12-words": "Enter the 12 words of your seed phrase, separated by single spaces",
"enter-a-private-key": "Enter a private key",
"enter-a-seed-phrase": "Enter a seed phrase",
@@ -2517,14 +2519,15 @@
"sync-code-generated": "Sync code generated",
"sync-devices-complete-sub-title": "Your devices are now in sync",
"sync-devices-complete-title": "Device sync complete!",
"sync-devices-error-sub-title": "Make sure both devices are powered on and connected to the internet.",
"sync-devices-error-title": "Oops, somethings wrong",
"sync-devices-error-sub-title": "Try again and double-check the instructions",
"sync-devices-error-title": "Oops, somethings wrong!",
"sync-devices-result-sub-title": "Your devices are now in sync",
"sync-devices-sub-title": "Please keep both devices switched on and connected to the internet until sync is complete",
"sync-devices-sub-title": "Please keep both devices switched on and connected to the same network until sync is complete.",
"sync-devices-title": "Syncing devices...",
"sync-in-progress": "Syncing...",
"sync-new-device": "Sync new device",
"sync-or-recover-profile": "Sync or recover profile",
"sync-profile-title": "Syncing profile...",
"sync-settings": "Sync settings",
"sync-synced": "In sync",
"sync-your-profile": "Sync your profile",
@@ -2917,6 +2920,7 @@
"other": "{{count}} words"
},
"write-down-and-store-securely": "Write codes down\n & store them securely",
"written-seed-ready": "I have written down my recovery phrase and ready to complete backup and remove it from device",
"wrong-address": "Wrong address",
"wrong-card": "Wrong card",
"wrong-card-text": "Tapped card does not correspond to the keys you selected",
-1
View File
@@ -1913,7 +1913,6 @@
"sync-code-generated": "同期コードが生成されました",
"sync-devices-complete-sub-title": "お使いのデバイスが同期されました",
"sync-devices-complete-title": "デバイスの同期が完了しました!",
"sync-devices-error-sub-title": "両方のデバイスの電源がオンになっていて、インターネットに接続されていることを確認してください。",
"sync-devices-error-title": "おっと、何かが間違っています",
"sync-devices-result-sub-title": "お使いのデバイスが同期されました",
"sync-devices-sub-title": "同期が完了するまで、両方のデバイスの電源を入れ、インターネットに接続したままにしてください。",
+2 -2
View File
@@ -9479,9 +9479,9 @@ react-native-static-safe-area-insets@^2.2.0:
resolved "https://registry.yarnpkg.com/react-native-static-safe-area-insets/-/react-native-static-safe-area-insets-2.2.0.tgz#dd86b6a38f43964fac8df8c0e6bc8e062527786c"
integrity sha512-TLTW2e2kRK3COSK8gMZzwp4wHguFCtcO18itDLn5av/xQblXt9ylu84o+qD9aKJCBfvtNzGOvqqTKqC5GJRZ/g==
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.4":
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.5":
version "2.6.2"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#e78f46de10d65cfef2df2f62b6f41e64e0c332b9"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#5b456ea3654d1344d9ae26fe88a2051719394dfe"
react-native-svg@13.10.0:
version "13.10.0"