Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eae887e6b4 | ||
|
|
eff9003b68 | ||
|
|
6a2c13928e | ||
|
|
3191c70048 | ||
|
|
8e3c42796f | ||
|
|
141fbba9a4 | ||
|
|
aaca9c9388 | ||
|
|
1b9c3b577c | ||
|
|
c1daea3e99 | ||
|
|
9673eb40df | ||
|
|
b7cd92ce67 | ||
|
|
8878bf096c | ||
|
|
6774271d9a | ||
|
|
744ba2917e | ||
|
|
a5b001f237 | ||
|
|
6104ec05e3 | ||
|
|
b933d386b2 | ||
|
|
e2ec2e6171 | ||
|
|
a3bb6305b9 | ||
|
|
06be16d081 | ||
|
|
6a9e79f450 | ||
|
|
84f5a4378c | ||
|
|
2329b79f3d | ||
|
|
5b1f25d545 | ||
|
|
d35c2d2616 | ||
|
|
4226aa4d5e |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 542 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,9 +1,10 @@
|
|||||||
Status Terms of Use
|
Status Terms of Use
|
||||||
|
|
||||||
Last updated: 14 August 2024
|
Last updated: 10 December 2024
|
||||||
|
|
||||||
1. Introduction
|
1. Introduction
|
||||||
|
|
||||||
|
|
||||||
1.1 Who we are
|
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.
|
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
|
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.
|
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.
|
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 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
|
2.1.1 Wallet
|
||||||
|
|
||||||
Status Software includes a crypto wallet. We will refer to such wallet functionality in these terms as “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
|
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 Waku’s 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 Waku’s 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
|
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.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
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
|
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.
|
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.
|
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
|
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.
|
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
|
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:
|
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.
|
||||||
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;
|
8.2 Community Governance
|
||||||
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;
|
Community Spaces are self-sovereign environments managed independently by their creators and appointed admins. These users are solely responsible for:
|
||||||
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;
|
1. establishing and enforcing their own community guidelines;
|
||||||
7. knowingly spread misinformation or impersonate another person or legal entity;
|
2. configuring access controls and permissions;
|
||||||
8. incite, commit or threaten, harm or engage in illegal or inappropriate conduct including stalking, bullying, harassment, intimidation or abuse another individual or group;
|
3. managing community membership, including accepting or rejecting requests;
|
||||||
9. engage in or organise child sexual exploitation of any kind;
|
4. moderating content and interactions within their community; and
|
||||||
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;
|
5. taking actions against community members who violate their community guidelines or behave disruptively, including the ability to exclude or ban members.
|
||||||
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;
|
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.
|
||||||
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.
|
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
|
9. Fees
|
||||||
@@ -252,6 +262,7 @@ You release Status from all liability related to any claim, cause of action, con
|
|||||||
14. Limitation of liability
|
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.
|
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.
|
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,67 +0,0 @@
|
|||||||
(ns legacy.status-im.ui.screens.about-app.views
|
|
||||||
(:require
|
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
|
||||||
[legacy.status-im.ui.components.copyable-text :as copyable-text]
|
|
||||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
|
||||||
[legacy.status-im.ui.components.list.item :as list.item]
|
|
||||||
[legacy.status-im.ui.components.react :as react]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf])
|
|
||||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
|
||||||
|
|
||||||
(views/defview about-app
|
|
||||||
[]
|
|
||||||
(views/letsubs [app-version [:get-app-short-version]
|
|
||||||
commit-hash [:get-commit-hash]
|
|
||||||
node-version [:get-app-node-version]]
|
|
||||||
[:<>
|
|
||||||
[quo/page-nav
|
|
||||||
{:type :title
|
|
||||||
:title (i18n/label :t/about-app)
|
|
||||||
:background :blur
|
|
||||||
:icon-name :i/close
|
|
||||||
:on-press #(rf/dispatch [:navigate-back])}]
|
|
||||||
[react/scroll-view
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:copied-text app-version}
|
|
||||||
[list.item/list-item
|
|
||||||
{:size :small
|
|
||||||
:accessibility-label :app-version
|
|
||||||
:title (i18n/label :t/version)
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text app-version}]]
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:copied-text commit-hash}
|
|
||||||
[list.item/list-item
|
|
||||||
{:size :small
|
|
||||||
:accessibility-label :commit-hash
|
|
||||||
:title (i18n/label :t/app-commit)
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text commit-hash}]]
|
|
||||||
[copyable-text/copyable-text-view
|
|
||||||
{:copied-text node-version}
|
|
||||||
[list.item/list-item
|
|
||||||
{:size :small
|
|
||||||
:accessibility-label :node-version
|
|
||||||
:title (i18n/label :t/node-version)
|
|
||||||
:accessory :text
|
|
||||||
:accessory-text node-version}]]]]))
|
|
||||||
|
|
||||||
(views/defview learn-more-sheet
|
|
||||||
[]
|
|
||||||
(views/letsubs [{:keys [title content]} [:bottom-sheet/options]]
|
|
||||||
[react/view
|
|
||||||
{:style {:padding-left 16
|
|
||||||
:padding-top 16
|
|
||||||
:padding-right 34
|
|
||||||
:padding-bottom 0}}
|
|
||||||
[react/view {:style {:align-items :center :flex-direction :row :margin-bottom 16}}
|
|
||||||
[icons/icon :main-icons/info
|
|
||||||
{:color colors/blue
|
|
||||||
:container-style {:margin-right 13}}]
|
|
||||||
[react/text {:style {:typography :title-bold}} title]]
|
|
||||||
[react/text {:style {:color colors/gray}} content]]))
|
|
||||||
|
|
||||||
(def learn-more
|
|
||||||
{:content learn-more-sheet})
|
|
||||||
@@ -33,6 +33,9 @@
|
|||||||
name]]]]))
|
name]]]]))
|
||||||
|
|
||||||
(def log-levels
|
(def log-levels
|
||||||
|
"The status-go log library (zap) doesn't support the trace level, so we remove
|
||||||
|
the trace option from the UI. When trace is enabled an error will happen while
|
||||||
|
trying to login (user will see the error 'wrong password')."
|
||||||
[{:name "DISABLED"
|
[{:name "DISABLED"
|
||||||
:value ""}
|
:value ""}
|
||||||
{:name "ERROR"
|
{:name "ERROR"
|
||||||
@@ -42,9 +45,7 @@
|
|||||||
{:name "INFO"
|
{:name "INFO"
|
||||||
:value "INFO"}
|
:value "INFO"}
|
||||||
{:name "DEBUG"
|
{:name "DEBUG"
|
||||||
:value "DEBUG"}
|
:value "DEBUG"}])
|
||||||
{:name "TRACE"
|
|
||||||
:value "TRACE"}])
|
|
||||||
|
|
||||||
(views/defview log-level-settings
|
(views/defview log-level-settings
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
(ns legacy.status-im.ui.screens.screens
|
(ns legacy.status-im.ui.screens.screens
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.ui.components.colors :as colors]
|
[legacy.status-im.ui.components.colors :as colors]
|
||||||
[legacy.status-im.ui.screens.about-app.views :as about-app]
|
|
||||||
[legacy.status-im.ui.screens.advanced-settings.views :as advanced-settings]
|
[legacy.status-im.ui.screens.advanced-settings.views :as advanced-settings]
|
||||||
[legacy.status-im.ui.screens.appearance.views :as appearance]
|
[legacy.status-im.ui.screens.appearance.views :as appearance]
|
||||||
[legacy.status-im.ui.screens.backup-settings.view :as backup-settings]
|
[legacy.status-im.ui.screens.backup-settings.view :as backup-settings]
|
||||||
@@ -93,12 +92,6 @@
|
|||||||
:insets {:top? platform/android?}}
|
:insets {:top? platform/android?}}
|
||||||
:component sync-settings/sync-settings}
|
:component sync-settings/sync-settings}
|
||||||
|
|
||||||
;; ABOUT
|
|
||||||
{:name :about-app
|
|
||||||
:options {:topBar {:visible false}
|
|
||||||
:insets {:top? platform/android?}}
|
|
||||||
:component about-app/about-app}
|
|
||||||
|
|
||||||
;; STATUS HELP
|
;; STATUS HELP
|
||||||
{:name :help-center
|
{:name :help-center
|
||||||
:options {:topBar {:visible false}
|
:options {:topBar {:visible false}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
[rn/view {:style (style/loading-container size blur? theme)}]))
|
[rn/view {:style (style/loading-container size blur? theme)}]))
|
||||||
|
|
||||||
(defn- left-subtitle
|
(defn- left-subtitle
|
||||||
[{:keys [size subtitle-type subtitle-color icon icon-color blur? subtitle customization-color emoji
|
[{:keys [size subtitle-text-props subtitle-type subtitle-color icon icon-color blur? subtitle
|
||||||
|
customization-color emoji
|
||||||
network-image]
|
network-image]
|
||||||
:or {subtitle-type :default}}]
|
:or {subtitle-type :default}}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
@@ -39,9 +40,10 @@
|
|||||||
:style style/image}]
|
:style style/image}]
|
||||||
nil)])
|
nil)])
|
||||||
[text/text
|
[text/text
|
||||||
{:weight :medium
|
(merge {:weight :medium
|
||||||
:size :paragraph-2
|
:size :paragraph-2
|
||||||
:style (style/description subtitle-color blur? theme)}
|
:style (style/description subtitle-color blur? theme)}
|
||||||
|
subtitle-text-props)
|
||||||
subtitle]
|
subtitle]
|
||||||
(when (= subtitle-type :editable)
|
(when (= subtitle-type :editable)
|
||||||
[icons/icon :i/edit
|
[icons/icon :i/edit
|
||||||
@@ -75,7 +77,8 @@
|
|||||||
|
|
||||||
(defn- left-side
|
(defn- left-side
|
||||||
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
|
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
|
||||||
[{:keys [title status size blur? custom-subtitle icon subtitle subtitle-type subtitle-color icon-color
|
[{:keys [title subtitle-text-props status size blur? custom-subtitle icon subtitle subtitle-type
|
||||||
|
subtitle-color icon-color
|
||||||
customization-color network-image emoji title-icon]
|
customization-color network-image emoji title-icon]
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
@@ -94,6 +97,7 @@
|
|||||||
[custom-subtitle props]
|
[custom-subtitle props]
|
||||||
[left-subtitle
|
[left-subtitle
|
||||||
{:theme theme
|
{:theme theme
|
||||||
|
:subtitle-text-props subtitle-text-props
|
||||||
:size size
|
:size size
|
||||||
:subtitle-type subtitle-type
|
:subtitle-type subtitle-type
|
||||||
:subtitle-color subtitle-color
|
:subtitle-color subtitle-color
|
||||||
@@ -140,6 +144,7 @@
|
|||||||
[:size {:optional true} [:maybe [:enum :default :small :large]]]
|
[:size {:optional true} [:maybe [:enum :default :small :large]]]
|
||||||
[:title :string]
|
[:title :string]
|
||||||
[:subtitle {:optional true} [:maybe [:or :string :double]]]
|
[:subtitle {:optional true} [:maybe [:or :string :double]]]
|
||||||
|
[:subtitle-text-props {:optional true} [:maybe :map]]
|
||||||
[:custom-subtitle {:optional true} [:maybe fn?]]
|
[:custom-subtitle {:optional true} [:maybe fn?]]
|
||||||
[:icon {:optional true} [:maybe :keyword]]
|
[:icon {:optional true} [:maybe :keyword]]
|
||||||
[:title-icon {:optional true} [:maybe :keyword]]
|
[:title-icon {:optional true} [:maybe :keyword]]
|
||||||
|
|||||||
@@ -79,11 +79,11 @@
|
|||||||
[rn/view {:style style/community-logo-ring}]])
|
[rn/view {:style style/community-logo-ring}]])
|
||||||
|
|
||||||
(defn- description-container
|
(defn- description-container
|
||||||
[{:keys [description description-text collection-text community-text
|
[{:keys [description description-text collection-text community-text blur?
|
||||||
collection-image community-image blur?]
|
collection-image community-image description-accessibility-label]
|
||||||
context-tag-props :context-tag
|
context-tag-props :context-tag
|
||||||
summary-props :summary}]
|
summary-props :summary}]
|
||||||
[rn/view
|
[rn/view {:accessibility-label description-accessibility-label}
|
||||||
(cond
|
(cond
|
||||||
(and (= description :text) (not (string/blank? description-text)))
|
(and (= description :text) (not (string/blank? description-text)))
|
||||||
[text/text
|
[text/text
|
||||||
|
|||||||
@@ -61,14 +61,17 @@
|
|||||||
(defn view
|
(defn view
|
||||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
||||||
blur-options content-avoid-keyboard? automatically-adjust-keyboard-insets]
|
blur-options content-avoid-keyboard? automatically-adjust-keyboard-insets
|
||||||
|
;; Note: Provide `initial-header-height` to avoid a jump due to the on-layout 1-frame
|
||||||
|
;; delay. Revisit this on RN 0.76 since the on-layout delay has been fixed.
|
||||||
|
initial-header-height]
|
||||||
:or {footer-container-padding (safe-area/get-top)}}
|
:or {footer-container-padding (safe-area/get-top)}}
|
||||||
& children]
|
& children]
|
||||||
(reagent/with-let [scroll-view-ref (atom nil)
|
(reagent/with-let [scroll-view-ref (atom nil)
|
||||||
set-scroll-ref #(reset! scroll-view-ref %)
|
set-scroll-ref #(reset! scroll-view-ref %)
|
||||||
window-height (:height (rn/get-window))
|
window-height (:height (rn/get-window))
|
||||||
footer-container-height (reagent/atom 0)
|
footer-container-height (reagent/atom 0)
|
||||||
header-height (reagent/atom 0)
|
header-height (reagent/atom nil)
|
||||||
content-container-height (reagent/atom 0)
|
content-container-height (reagent/atom 0)
|
||||||
content-scroll-y (reagent/atom 0)
|
content-scroll-y (reagent/atom 0)
|
||||||
keyboard-height (reagent/atom 0)
|
keyboard-height (reagent/atom 0)
|
||||||
@@ -112,7 +115,7 @@
|
|||||||
{:style
|
{:style
|
||||||
(if content-avoid-keyboard?
|
(if content-avoid-keyboard?
|
||||||
(style/content-keyboard-avoiding-view
|
(style/content-keyboard-avoiding-view
|
||||||
{:top @header-height
|
{:top (or @header-height initial-header-height)
|
||||||
:bottom (if keyboard-shown?
|
:bottom (if keyboard-shown?
|
||||||
@footer-container-height
|
@footer-container-height
|
||||||
(+ bottom-safe-area @footer-container-height))})
|
(+ bottom-safe-area @footer-container-height))})
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
(ns status-im.common.privacy.view
|
(ns status-im.common.privacy.view
|
||||||
(:require-macros [legacy.status-im.utils.slurp :refer [slurp]])
|
(:require-macros [legacy.status-im.utils.slurp :refer [slurp]])
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[react-native.gesture :as gesture]))
|
[react-native.gesture :as gesture]
|
||||||
|
[status-im.contexts.settings.common.header :as header]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(def privacy-statement-text (slurp "resources/privacy.mdwn"))
|
(def privacy-statement-text (slurp "resources/privacy.mdwn"))
|
||||||
|
|
||||||
(defn privacy-statement
|
(defn privacy-statement
|
||||||
[]
|
[]
|
||||||
[gesture/scroll-view {:margin 20}
|
[gesture/scroll-view {:style {:margin 20}}
|
||||||
[quo/text privacy-statement-text]])
|
[quo/text privacy-statement-text]])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
[quo/overlay {:type :shell}
|
||||||
|
[header/view {:title (i18n/label :t/privacy-policy)}]
|
||||||
|
[gesture/scroll-view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text privacy-statement-text]]])
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
(def ui
|
(def ui
|
||||||
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
|
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
|
||||||
:biometrics (js/require "../resources/images/ui2/biometrics.png")
|
:biometrics (js/require "../resources/images/ui2/biometrics.png")
|
||||||
|
:usage-data (js/require "../resources/images/ui2/usage-data.png")
|
||||||
|
:login-syncing (js/require "../resources/images/ui2/login-syncing.png")
|
||||||
:chat-privately-with-friends (js/require "../resources/images/ui2/chat-privately-with-friends.png")
|
:chat-privately-with-friends (js/require "../resources/images/ui2/chat-privately-with-friends.png")
|
||||||
:desktop-how-to-pair-sign-in (js/require "../resources/images/ui2/desktop-how-to-pair-sign-in.png")
|
:desktop-how-to-pair-sign-in (js/require "../resources/images/ui2/desktop-how-to-pair-sign-in.png")
|
||||||
:desktop-how-to-pair-logged-in (js/require
|
:desktop-how-to-pair-logged-in (js/require
|
||||||
|
|||||||
@@ -10,24 +10,43 @@
|
|||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.security.core :as security]))
|
[utils.security.core :as security]))
|
||||||
|
|
||||||
(rf/reg-fx :effects.keycard/call-on-auth-success
|
(defn- handle-password-success
|
||||||
(fn [on-auth-success]
|
[has-partially-operable-accounts? on-auth-success masked-password]
|
||||||
(when on-auth-success (on-auth-success ""))))
|
(let [on-auth-success-callback #(on-auth-success masked-password)]
|
||||||
|
(rf/dispatch [:standard-auth/set-success true])
|
||||||
|
(rf/dispatch [:standard-auth/reset-login-password])
|
||||||
|
(if has-partially-operable-accounts?
|
||||||
|
(rf/dispatch [:wallet/make-partially-operable-accounts-fully-operable
|
||||||
|
{:password masked-password
|
||||||
|
:on-success on-auth-success-callback
|
||||||
|
:on-error on-auth-success-callback}])
|
||||||
|
(on-auth-success-callback))))
|
||||||
|
|
||||||
(defn authorize
|
(defn authorize
|
||||||
[{:keys [db]} [{:keys [on-auth-success keycard-supported?] :as args}]]
|
[{:keys [db]} [{:keys [on-auth-success] :as args}]]
|
||||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||||
keycard? (get-in db [:profile/profile :keycard-pairing])]
|
keycard-profile? (get-in db [:profile/profile :keycard-pairing])]
|
||||||
{:fx
|
{:fx
|
||||||
[(if keycard?
|
[(if keycard-profile?
|
||||||
(if keycard-supported?
|
[:dispatch
|
||||||
[:effects.keycard/call-on-auth-success on-auth-success]
|
[:standard-auth/authorize-with-keycard
|
||||||
[:effects.utils/show-popup
|
{:on-complete
|
||||||
{:title "This feature is not supported yet "
|
(fn [pin]
|
||||||
:content
|
(rf/dispatch
|
||||||
"Keycard support is limited to logging in
|
[:keycard/connect
|
||||||
and signing the sending transaction.
|
{:key-uid key-uid
|
||||||
Use Status Desktop to access all functions."}])
|
:on-success
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:keycard/get-keys
|
||||||
|
{:pin pin
|
||||||
|
:on-success (fn [{:keys [encryption-public-key]}]
|
||||||
|
(rf/dispatch [:keycard/disconnect])
|
||||||
|
(handle-password-success false
|
||||||
|
on-auth-success
|
||||||
|
(security/mask-data encryption-public-key)))
|
||||||
|
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error
|
||||||
|
%])}]))}]))}]]
|
||||||
[:effects.biometric/check-if-available
|
[:effects.biometric/check-if-available
|
||||||
{:key-uid key-uid
|
{:key-uid key-uid
|
||||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||||
@@ -89,21 +108,12 @@
|
|||||||
(defn- bottom-sheet-password-view
|
(defn- bottom-sheet-password-view
|
||||||
[{:keys [on-press-biometric on-auth-success auth-button-icon-left auth-button-label]}]
|
[{:keys [on-press-biometric on-auth-success auth-button-icon-left auth-button-label]}]
|
||||||
(fn []
|
(fn []
|
||||||
(let [has-partially-operable-accounts? (rf/sub [:wallet/has-partially-operable-accounts?])
|
(let [has-partially-operable-accounts? (rf/sub [:wallet/has-partially-operable-accounts?])]
|
||||||
handle-password-success
|
|
||||||
(fn [password]
|
|
||||||
(let [sha3-pwd (security/hash-masked-password password)
|
|
||||||
on-auth-success-callback #(on-auth-success sha3-pwd)]
|
|
||||||
(rf/dispatch [:standard-auth/set-success true])
|
|
||||||
(rf/dispatch [:standard-auth/reset-login-password])
|
|
||||||
(if has-partially-operable-accounts?
|
|
||||||
(rf/dispatch [:wallet/make-partially-operable-accounts-fully-operable
|
|
||||||
{:password sha3-pwd
|
|
||||||
:on-success on-auth-success-callback
|
|
||||||
:on-error on-auth-success-callback}])
|
|
||||||
(on-auth-success-callback))))]
|
|
||||||
[enter-password/view
|
[enter-password/view
|
||||||
{:on-enter-password handle-password-success
|
{:on-enter-password #(handle-password-success
|
||||||
|
has-partially-operable-accounts?
|
||||||
|
on-auth-success
|
||||||
|
(security/hash-masked-password %))
|
||||||
:on-press-biometrics on-press-biometric
|
:on-press-biometrics on-press-biometric
|
||||||
:button-icon-left auth-button-icon-left
|
:button-icon-left auth-button-icon-left
|
||||||
:button-label auth-button-label}])))
|
:button-label auth-button-label}])))
|
||||||
|
|||||||
@@ -9,26 +9,25 @@
|
|||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
||||||
auth-button-icon-left size blur? container-style disabled? dependencies keycard-supported?]
|
auth-button-icon-left size blur? container-style disabled? dependencies on-complete]
|
||||||
:or {container-style {:flex 1}}}]
|
:or {container-style {:flex 1}}}]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
auth-method (rf/sub [:auth-method])
|
auth-method (rf/sub [:auth-method])
|
||||||
biometric-auth? (= auth-method constants/auth-method-biometric)
|
biometric-auth? (= auth-method constants/auth-method-biometric)
|
||||||
on-complete (rn/use-callback
|
on-complete-callback (rn/use-callback
|
||||||
(fn [reset]
|
(fn [reset-slider-fn]
|
||||||
(rf/dispatch [:standard-auth/authorize
|
(js/setTimeout #(reset-slider-fn false) 500)
|
||||||
{:on-close (fn [success?]
|
(rf/dispatch [:standard-auth/authorize
|
||||||
(js/setTimeout #(reset success?) 200))
|
{:auth-button-icon-left auth-button-icon-left
|
||||||
:auth-button-icon-left auth-button-icon-left
|
:theme theme
|
||||||
:theme theme
|
:blur? blur?
|
||||||
:blur? blur?
|
:biometric-auth? biometric-auth?
|
||||||
:keycard-supported? keycard-supported?
|
:on-auth-success on-auth-success
|
||||||
:biometric-auth? biometric-auth?
|
:on-auth-fail on-auth-fail
|
||||||
:on-auth-success on-auth-success
|
:auth-button-label auth-button-label}]))
|
||||||
:on-auth-fail on-auth-fail
|
(vec (conj dependencies on-auth-success on-auth-fail)))
|
||||||
:auth-button-label auth-button-label}]))
|
on-complete (or on-complete on-complete-callback)
|
||||||
(vec (conj dependencies on-auth-success on-auth-fail)))
|
biometric-type (rf/sub [:biometrics/supported-type])]
|
||||||
biometric-type (rf/sub [:biometrics/supported-type])]
|
|
||||||
[quo/slide-button
|
[quo/slide-button
|
||||||
{:container-style container-style
|
{:container-style container-style
|
||||||
:size size
|
:size size
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
(ns status-im.common.terms.view
|
(ns status-im.common.terms.view
|
||||||
(:require-macros [legacy.status-im.utils.slurp :refer [slurp]])
|
(:require-macros [legacy.status-im.utils.slurp :refer [slurp]])
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[react-native.gesture :as gesture]))
|
[react-native.gesture :as gesture]
|
||||||
|
[status-im.contexts.settings.common.header :as header]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(def terms-of-use-text (slurp "resources/terms-of-use.mdwn"))
|
(def terms-of-use-text (slurp "resources/terms-of-use.mdwn"))
|
||||||
|
|
||||||
(defn terms-of-use
|
(defn terms-of-use
|
||||||
[]
|
[]
|
||||||
[gesture/scroll-view {:margin 20}
|
[gesture/scroll-view {:style {:margin 20}}
|
||||||
[quo/text terms-of-use-text]])
|
[quo/text terms-of-use-text]])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
[quo/overlay {:type :shell}
|
||||||
|
[header/view {:title (i18n/label :t/terms-of-service)}]
|
||||||
|
[gesture/scroll-view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text terms-of-use-text]]])
|
||||||
|
|||||||
@@ -28,9 +28,10 @@
|
|||||||
:long-enough?
|
:long-enough?
|
||||||
:short-enough?)))))
|
:short-enough?)))))
|
||||||
|
|
||||||
|
(def password-tip? (set constants/password-tips))
|
||||||
|
|
||||||
(defn strength
|
(defn strength
|
||||||
[validations]
|
[validations]
|
||||||
(->> (select-keys validations constants/password-tips)
|
(->> validations
|
||||||
(vals)
|
(filter #(and (password-tip? (key %)) (val %)))
|
||||||
(filter true?)
|
(count)))
|
||||||
count))
|
|
||||||
|
|||||||
@@ -334,6 +334,7 @@
|
|||||||
(def ^:const privacy-policy-link "https://status.im/privacy-policy/")
|
(def ^:const privacy-policy-link "https://status.im/privacy-policy/")
|
||||||
(def ^:const terms-of-service-link "https://status.im/terms-of-use")
|
(def ^:const terms-of-service-link "https://status.im/terms-of-use")
|
||||||
(def ^:const create-account-link "https://status.app/help/wallet/create-wallet-accounts")
|
(def ^:const create-account-link "https://status.app/help/wallet/create-wallet-accounts")
|
||||||
|
(def ^:const mobile-upvote-link "https://status-mobile.featureupvote.com")
|
||||||
|
|
||||||
(def ^:const visibility-status-unknown 0)
|
(def ^:const visibility-status-unknown 0)
|
||||||
(def ^:const visibility-status-automatic 1)
|
(def ^:const visibility-status-automatic 1)
|
||||||
@@ -641,3 +642,9 @@
|
|||||||
(def ^:const wallet-connect-transaction-refresh-interval-ms 10000)
|
(def ^:const wallet-connect-transaction-refresh-interval-ms 10000)
|
||||||
|
|
||||||
(def ^:const native-token-symbol "ETH")
|
(def ^:const native-token-symbol "ETH")
|
||||||
|
|
||||||
|
;; About app links
|
||||||
|
(def ^:const status-app-url "http://status.app")
|
||||||
|
(def ^:const go-waku-url "https://github.com/waku-org/go-waku")
|
||||||
|
(def ^:const status-go-url "https://github.com/status-im/status-go")
|
||||||
|
(def ^:const status-mobile-url "https://github.com/status-im/status-mobile")
|
||||||
|
|||||||
@@ -53,7 +53,13 @@
|
|||||||
(conj (navigation-event (name view-id)))
|
(conj (navigation-event (name view-id)))
|
||||||
|
|
||||||
(= :screen/onboarding.syncing-results view-id)
|
(= :screen/onboarding.syncing-results view-id)
|
||||||
(conj (key-value-event "onboarding-completed")))))
|
(conj (key-value-event "onboarding-completed"))
|
||||||
|
|
||||||
|
(= :screen/keycard.migrate.success view-id)
|
||||||
|
(conj (key-value-event "keycard-migration-succeeded"))
|
||||||
|
|
||||||
|
(= :screen/keycard.migrate.fail view-id)
|
||||||
|
(conj (key-value-event "keycard-migration-failed")))))
|
||||||
|
|
||||||
(defn navigated-to-collectibles-tab-event
|
(defn navigated-to-collectibles-tab-event
|
||||||
[location]
|
[location]
|
||||||
|
|||||||
@@ -52,8 +52,8 @@
|
|||||||
{:eventName "navigation"
|
{:eventName "navigation"
|
||||||
:platform platform-os
|
:platform platform-os
|
||||||
:appVersion app-version
|
:appVersion app-version
|
||||||
:eventValue {:viewId "onboarding.create-profile-info"}}}]
|
:eventValue {:viewId "onboarding.create-profile-password"}}}]
|
||||||
(tracking/track-view-id-event :screen/onboarding.create-profile)))
|
(tracking/track-view-id-event :screen/onboarding.create-profile-password)))
|
||||||
(is (= [] (tracking/track-view-id-event :unknown-stack)))))
|
(is (= [] (tracking/track-view-id-event :unknown-stack)))))
|
||||||
|
|
||||||
(deftest tracked-event-test
|
(deftest tracked-event-test
|
||||||
|
|||||||
@@ -11,30 +11,35 @@
|
|||||||
[{:keys [contact-id]}]
|
[{:keys [contact-id]}]
|
||||||
(let [{:keys [contact-request-state
|
(let [{:keys [contact-request-state
|
||||||
community-id
|
community-id
|
||||||
chat-name]} (rf/sub [:chats/current-chat-chat-view])
|
chat-name]} (rf/sub [:chats/current-chat-chat-view])
|
||||||
chat-type (rf/sub [:chats/chat-type])
|
chat-type (rf/sub [:chats/chat-type])
|
||||||
[primary-name _] (if (= chat-type :public-chat)
|
[primary-name _] (if (= chat-type :public-chat)
|
||||||
[(str "#" chat-name) ""]
|
[(str "#" chat-name) ""]
|
||||||
(rf/sub [:contacts/contact-two-names-by-identity contact-id]))
|
(rf/sub [:contacts/contact-two-names-by-identity contact-id]))
|
||||||
community-chat? (= chat-type :community-chat)
|
community-chat? (= chat-type :community-chat)
|
||||||
joined (when community-chat?
|
joined (when community-chat?
|
||||||
(rf/sub [:communities/community-joined community-id]))
|
(rf/sub [:communities/community-joined community-id]))
|
||||||
pending? (when community-chat?
|
pending? (when community-chat?
|
||||||
(rf/sub [:communities/my-pending-request-to-join community-id]))
|
(rf/sub [:communities/my-pending-request-to-join community-id]))
|
||||||
contact-request-send? (or (not contact-request-state)
|
contact-request-send? (or (not contact-request-state)
|
||||||
(= contact-request-state
|
(= contact-request-state
|
||||||
constants/contact-request-state-none))
|
constants/contact-request-state-none))
|
||||||
contact-request-received? (= contact-request-state
|
contact-request-received? (= contact-request-state
|
||||||
constants/contact-request-state-received)
|
constants/contact-request-state-received)
|
||||||
contact-request-pending? (= contact-request-state
|
contact-request-pending? (= contact-request-state
|
||||||
constants/contact-request-state-sent)]
|
constants/contact-request-state-sent)
|
||||||
|
keycard? (rf/sub [:keycard/keycard-profile?])
|
||||||
|
keycard-feature-unavailable (rn/use-callback
|
||||||
|
#(rf/dispatch [:keycard/feature-unavailable-show]))]
|
||||||
[rn/view {:style style/container}
|
[rn/view {:style style/container}
|
||||||
[quo/permission-context
|
[quo/permission-context
|
||||||
{:blur? true
|
{:blur? true
|
||||||
:on-press (cond
|
:on-press (cond
|
||||||
(and community-chat? (not pending?) (not joined))
|
(and community-chat? (not pending?) (not joined))
|
||||||
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
(if keycard?
|
||||||
{:community-id community-id}])
|
keycard-feature-unavailable
|
||||||
|
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
|
{:community-id community-id}]))
|
||||||
|
|
||||||
(not community-chat?)
|
(not community-chat?)
|
||||||
#(rf/dispatch [:chat.ui/show-profile contact-id]))
|
#(rf/dispatch [:chat.ui/show-profile contact-id]))
|
||||||
|
|||||||
@@ -10,72 +10,73 @@
|
|||||||
[status-im.contexts.communities.actions.community-rules.view :as community-rules]
|
[status-im.contexts.communities.actions.community-rules.view :as community-rules]
|
||||||
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
|
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
|
||||||
[status-im.contexts.communities.utils :as communities.utils]
|
[status-im.contexts.communities.utils :as communities.utils]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
{id :community-id} (rf/sub [:get-screen-params])
|
{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name color images joined]} (rf/sub [:communities/community id])
|
{:keys [name color images joined]} (rf/sub [:communities/community id])
|
||||||
has-permissions? (rf/sub [:communities/has-permissions? id])
|
has-permissions? (rf/sub [:communities/has-permissions? id])
|
||||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||||
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||||
revealed-accounts-count (count revealed-accounts)
|
revealed-accounts-count (count revealed-accounts)
|
||||||
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts]))
|
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts]))
|
||||||
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
|
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
|
||||||
(i18n/label :t/all-addresses)
|
(i18n/label :t/all-addresses)
|
||||||
(i18n/label-pluralize
|
(i18n/label-pluralize
|
||||||
revealed-accounts-count
|
revealed-accounts-count
|
||||||
:t/address-count))
|
:t/address-count))
|
||||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||||
highest-permission-role
|
highest-permission-role
|
||||||
:t/member))
|
:t/member))
|
||||||
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||||
navigate-back (rn/use-callback #(rf/dispatch [:navigate-back]))
|
navigate-back (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||||
|
show-addresses-for-permissions (rn/use-callback
|
||||||
show-addresses-for-permissions
|
(fn []
|
||||||
(rn/use-callback
|
(if can-edit-addresses?
|
||||||
(fn []
|
(rf/dispatch [:open-modal :addresses-for-permissions
|
||||||
(if can-edit-addresses?
|
{:community-id id}])
|
||||||
(rf/dispatch [:open-modal :addresses-for-permissions {:community-id id}])
|
(rf/dispatch [:show-bottom-sheet
|
||||||
(rf/dispatch [:show-bottom-sheet
|
{:community-id id
|
||||||
{:community-id id
|
:content
|
||||||
:content (fn [] [addresses-for-permissions/view])}])))
|
addresses-for-permissions/view}])))
|
||||||
[can-edit-addresses?])
|
[can-edit-addresses?])
|
||||||
|
show-airdrop-addresses (rn/use-callback
|
||||||
show-airdrop-addresses
|
(fn []
|
||||||
(rn/use-callback
|
(if can-edit-addresses?
|
||||||
(fn []
|
(rf/dispatch [:open-modal :address-for-airdrop
|
||||||
(if can-edit-addresses?
|
{:community-id id}])
|
||||||
(rf/dispatch [:open-modal :address-for-airdrop {:community-id id}])
|
(rf/dispatch [:show-bottom-sheet
|
||||||
(rf/dispatch [:show-bottom-sheet
|
{:community-id id
|
||||||
{:community-id id
|
:content airdrop-addresses/view}])))
|
||||||
:content (fn [] [airdrop-addresses/view])}])))
|
[can-edit-addresses?])
|
||||||
[can-edit-addresses?])
|
confirm-choices (rn/use-callback
|
||||||
|
(fn []
|
||||||
confirm-choices
|
(rf/dispatch
|
||||||
(rn/use-callback
|
[:standard-auth/authorize
|
||||||
(fn []
|
{:auth-button-label (if can-edit-addresses?
|
||||||
(rf/dispatch
|
(i18n/label
|
||||||
[:standard-auth/authorize
|
:t/edit-shared-addresses)
|
||||||
{:auth-button-label (if can-edit-addresses?
|
(i18n/label :t/request-to-join))
|
||||||
(i18n/label :t/edit-shared-addresses)
|
:on-auth-success
|
||||||
(i18n/label :t/request-to-join))
|
(fn [password]
|
||||||
:on-auth-success (fn [password]
|
(rf/dispatch
|
||||||
(rf/dispatch
|
[:communities/request-to-join-with-addresses
|
||||||
[:communities/request-to-join-with-addresses
|
{:community-id id
|
||||||
{:community-id id
|
:password password}]))}])
|
||||||
:password password}]))}])
|
(navigate-back))
|
||||||
(navigate-back))
|
[can-edit-addresses?])
|
||||||
[can-edit-addresses?])
|
open-permission-sheet (rn/use-callback
|
||||||
|
(fn []
|
||||||
open-permission-sheet
|
(rf/dispatch
|
||||||
(rn/use-callback (fn []
|
[:show-bottom-sheet
|
||||||
(rf/dispatch [:show-bottom-sheet
|
{:content (fn []
|
||||||
{:content (fn [] [permissions-sheet/view id])}]))
|
[permissions-sheet/view id])}]))
|
||||||
[id])]
|
[id])]
|
||||||
(rn/use-mount
|
(rn/use-mount
|
||||||
(fn []
|
(fn []
|
||||||
(rf/dispatch [:communities/initialize-permission-addresses id])))
|
(rf/dispatch [:communities/initialize-permission-addresses id])))
|
||||||
@@ -86,7 +87,7 @@
|
|||||||
:icon-name :i/close
|
:icon-name :i/close
|
||||||
:on-press navigate-back
|
:on-press navigate-back
|
||||||
:accessibility-label :back-button}
|
:accessibility-label :back-button}
|
||||||
has-permissions?
|
(and has-permissions? (ff/enabled? ::ff/community.view-token-requirements))
|
||||||
(assoc :right-side
|
(assoc :right-side
|
||||||
[{:icon-left :i/unlocked
|
[{:icon-left :i/unlocked
|
||||||
:on-press open-permission-sheet
|
:on-press open-permission-sheet
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
||||||
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
|
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
@@ -122,23 +123,23 @@
|
|||||||
(defn- page-top
|
(defn- page-top
|
||||||
[{:keys [community-id identical-choices? can-edit-addresses?]}]
|
[{:keys [community-id identical-choices? can-edit-addresses?]}]
|
||||||
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])
|
(let [{:keys [name logo color]} (rf/sub [:communities/for-context-tag community-id])
|
||||||
has-permissions? (rf/sub [:communities/has-permissions? community-id])
|
has-permissions? (rf/sub [:communities/has-permissions? community-id])
|
||||||
confirm-discard-changes
|
confirm-discard-changes (rn/use-callback
|
||||||
(rn/use-callback
|
(fn []
|
||||||
(fn []
|
(if identical-choices?
|
||||||
(if identical-choices?
|
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
|
||||||
(rf/dispatch [:dismiss-modal :addresses-for-permissions])
|
(rf/dispatch [:show-bottom-sheet
|
||||||
(rf/dispatch [:show-bottom-sheet
|
{:content (fn []
|
||||||
{:content (fn [] [confirm-discard-drawer
|
[confirm-discard-drawer
|
||||||
community-id])}])))
|
community-id])}])))
|
||||||
[identical-choices? community-id])
|
[identical-choices? community-id])
|
||||||
|
open-permission-sheet (rn/use-callback
|
||||||
open-permission-sheet
|
(fn []
|
||||||
(rn/use-callback (fn []
|
(rf/dispatch [:show-bottom-sheet
|
||||||
(rf/dispatch [:show-bottom-sheet
|
{:content (fn []
|
||||||
{:content (fn [] [permissions-sheet/view
|
[permissions-sheet/view
|
||||||
community-id])}]))
|
community-id])}]))
|
||||||
[community-id])]
|
[community-id])]
|
||||||
[:<>
|
[:<>
|
||||||
(when can-edit-addresses?
|
(when can-edit-addresses?
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
@@ -161,7 +162,7 @@
|
|||||||
:community-name name
|
:community-name name
|
||||||
:community-logo logo
|
:community-logo logo
|
||||||
:customization-color color}
|
:customization-color color}
|
||||||
has-permissions?
|
(and has-permissions? (ff/enabled? ::ff/community.view-token-requirements))
|
||||||
(assoc :button-icon :i/info
|
(assoc :button-icon :i/info
|
||||||
:button-type :grey
|
:button-type :grey
|
||||||
:on-button-press open-permission-sheet))])]))
|
:on-button-press open-permission-sheet))])]))
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
:right-icon :i/chevron-right
|
:right-icon :i/chevron-right
|
||||||
:accessibility-label :view-token-gating
|
:accessibility-label :view-token-gating
|
||||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||||
{:content (fn [] [permissions-sheet/view id])
|
{:content (fn []
|
||||||
|
[permissions-sheet/view id])
|
||||||
:padding-bottom-override 16}])
|
:padding-bottom-override 16}])
|
||||||
:label (i18n/label :t/view-token-gating)})
|
:label (i18n/label :t/view-token-gating)})
|
||||||
|
|
||||||
@@ -138,7 +139,9 @@
|
|||||||
[id token-gated? intro-message test-networks-enabled?]
|
[id token-gated? intro-message test-networks-enabled?]
|
||||||
(let [common [(show-qr id) (share-community id)]
|
(let [common [(show-qr id) (share-community id)]
|
||||||
specific (cond
|
specific (cond
|
||||||
(and token-gated? (not test-networks-enabled?))
|
(and token-gated?
|
||||||
|
(not test-networks-enabled?)
|
||||||
|
(ff/enabled? ::ff/community.view-token-requirements))
|
||||||
[(invite-contacts id) (view-token-gating id)]
|
[(invite-contacts id) (view-token-gating id)]
|
||||||
|
|
||||||
token-gated?
|
token-gated?
|
||||||
@@ -161,7 +164,8 @@
|
|||||||
[id token-gated? muted? muted-till color intro-message]
|
[id token-gated? muted? muted-till color intro-message]
|
||||||
[[(view-members id)
|
[[(view-members id)
|
||||||
(view-rules id intro-message)
|
(view-rules id intro-message)
|
||||||
(when token-gated? (view-token-gating id))
|
(when (and token-gated? (ff/enabled? ::ff/community.view-token-requirements))
|
||||||
|
(view-token-gating id))
|
||||||
(when (ff/enabled? ::ff/community.edit-account-selection)
|
(when (ff/enabled? ::ff/community.edit-account-selection)
|
||||||
(edit-shared-addresses id))
|
(edit-shared-addresses id))
|
||||||
(mark-as-read id)
|
(mark-as-read id)
|
||||||
|
|||||||
@@ -27,7 +27,11 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [theme (quo.theme/use-theme)
|
||||||
{:keys [id]} (rf/sub [:get-screen-params])
|
{:keys [id]} (rf/sub [:get-screen-params])
|
||||||
{:keys [color name images]} (rf/sub [:communities/community id])]
|
{:keys [color name images]} (rf/sub [:communities/community id])
|
||||||
|
keycard? (rf/sub [:keycard/keycard-profile?])
|
||||||
|
keycard-feature-unavailable (rn/use-callback
|
||||||
|
#(rf/dispatch [:keycard/feature-unavailable-show
|
||||||
|
{:feature-name :community.request-to-join}]))]
|
||||||
[rn/safe-area-view {:flex 1}
|
[rn/safe-area-view {:flex 1}
|
||||||
[gesture/scroll-view {:style style/container}
|
[gesture/scroll-view {:style style/container}
|
||||||
[rn/view style/page-container
|
[rn/view style/page-container
|
||||||
@@ -59,7 +63,9 @@
|
|||||||
(i18n/label :t/cancel)]
|
(i18n/label :t/cancel)]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:accessibility-label :join-community-button
|
{:accessibility-label :join-community-button
|
||||||
:on-press #(join-community-and-navigate-back id)
|
:on-press (if keycard?
|
||||||
|
keycard-feature-unavailable
|
||||||
|
#(join-community-and-navigate-back id))
|
||||||
:container-style {:flex 1}
|
:container-style {:flex 1}
|
||||||
:inner-style {:background-color (colors/resolve-color color theme)}}
|
:inner-style {:background-color (colors/resolve-color color theme)}}
|
||||||
(i18n/label :t/request-to-join)]]
|
(i18n/label :t/request-to-join)]]
|
||||||
|
|||||||
@@ -106,12 +106,14 @@
|
|||||||
[quo/text (i18n/label :t/network-not-supported)])
|
[quo/text (i18n/label :t/network-not-supported)])
|
||||||
|
|
||||||
(defn- request-access-button
|
(defn- request-access-button
|
||||||
[id color]
|
[id color keycard? keycard-feature-unavailable]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:on-press (if config/community-accounts-selection-enabled?
|
{:on-press (if keycard?
|
||||||
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
keycard-feature-unavailable
|
||||||
{:community-id id}])
|
(if config/community-accounts-selection-enabled?
|
||||||
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}]))
|
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
|
{:community-id id}])
|
||||||
|
#(rf/dispatch [:open-modal :community-requests-to-join {:id id}])))
|
||||||
:accessibility-label :show-request-to-join-screen-button
|
:accessibility-label :show-request-to-join-screen-button
|
||||||
:customization-color color
|
:customization-color color
|
||||||
:container-style {:margin-bottom 12}
|
:container-style {:margin-bottom 12}
|
||||||
@@ -126,27 +128,34 @@
|
|||||||
|
|
||||||
(defn- token-requirements
|
(defn- token-requirements
|
||||||
[{:keys [id color role-permissions?]}]
|
[{:keys [id color role-permissions?]}]
|
||||||
(let [{:keys [can-request-access? no-member-permission? networks-not-supported?
|
(let
|
||||||
highest-permission-role
|
[{:keys [can-request-access? no-member-permission? networks-not-supported?
|
||||||
tokens]} (rf/sub [:community/token-gated-overview id])
|
highest-permission-role
|
||||||
highest-role-text (i18n/label
|
tokens]} (rf/sub [:community/token-gated-overview id])
|
||||||
(communities.utils/role->translation-key highest-permission-role :t/member))
|
highest-role-text (i18n/label
|
||||||
on-press (rn/use-callback
|
(communities.utils/role->translation-key highest-permission-role
|
||||||
(fn []
|
:t/member))
|
||||||
(if config/community-accounts-selection-enabled?
|
on-press (rn/use-callback
|
||||||
(rf/dispatch [:open-modal :community-account-selection-sheet
|
(fn []
|
||||||
{:community-id id}])
|
(if config/community-accounts-selection-enabled?
|
||||||
(rf/dispatch [:open-modal :community-requests-to-join
|
(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||||
{:id id}])))
|
{:community-id id}])
|
||||||
[id])
|
(rf/dispatch [:open-modal :community-requests-to-join
|
||||||
on-press-info #(rf/dispatch
|
{:id id}])))
|
||||||
[:show-bottom-sheet {:content token-gated-communities-info}])]
|
[id])
|
||||||
|
on-press-info #(rf/dispatch
|
||||||
|
[:show-bottom-sheet {:content token-gated-communities-info}])
|
||||||
|
keycard? (rf/sub [:keycard/keycard-profile?])
|
||||||
|
keycard-feature-unavailable (rn/use-callback
|
||||||
|
#(rf/dispatch [:keycard/feature-unavailable-show
|
||||||
|
{:feature-name :community.request-to-join}]))]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
networks-not-supported?
|
networks-not-supported?
|
||||||
[network-not-supported]
|
[network-not-supported]
|
||||||
|
|
||||||
(or (not role-permissions?) no-member-permission?)
|
(or (not role-permissions?) no-member-permission?)
|
||||||
[request-access-button id color]
|
[request-access-button id color keycard? keycard-feature-unavailable]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[quo/community-token-gating
|
[quo/community-token-gating
|
||||||
@@ -154,7 +163,7 @@
|
|||||||
:tokens tokens
|
:tokens tokens
|
||||||
:community-color color
|
:community-color color
|
||||||
:satisfied? can-request-access?
|
:satisfied? can-request-access?
|
||||||
:on-press on-press
|
:on-press (if keycard? keycard-feature-unavailable on-press)
|
||||||
:on-press-info on-press-info}])))
|
:on-press-info on-press-info}])))
|
||||||
|
|
||||||
(defn- join-community
|
(defn- join-community
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
status-im.contexts.keycard.pin.events
|
status-im.contexts.keycard.pin.events
|
||||||
status-im.contexts.keycard.sign.events
|
status-im.contexts.keycard.sign.events
|
||||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||||
utils.datetime))
|
[utils.address :as address]
|
||||||
|
utils.datetime
|
||||||
|
[utils.ethereum.eip.eip55 :as eip55]))
|
||||||
|
|
||||||
(rf/reg-event-fx :keycard/on-card-connected
|
(rf/reg-event-fx :keycard/on-card-connected
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} _]
|
||||||
@@ -65,6 +67,30 @@
|
|||||||
(fn [_ [data]]
|
(fn [_ [data]]
|
||||||
{:effects.keycard/export-key data}))
|
{:effects.keycard/export-key data}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :keycard/connect-derive-address-and-add-account
|
||||||
|
(fn [_ [{:keys [pin derivation-path key-uid account-preferences]}]]
|
||||||
|
{:fx [[:dispatch
|
||||||
|
[:keycard/connect
|
||||||
|
{:key-uid key-uid
|
||||||
|
:on-success
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:keycard/export-key
|
||||||
|
{:pin pin
|
||||||
|
:path derivation-path
|
||||||
|
:on-success (fn [public-key]
|
||||||
|
(let [derived-account {:public-key (str "0x" public-key)
|
||||||
|
:address (eip55/address->checksum
|
||||||
|
(str "0x"
|
||||||
|
(address/public-key->address
|
||||||
|
(subs public-key 2))))
|
||||||
|
:path derivation-path}]
|
||||||
|
(rf/dispatch [:keycard/disconnect])
|
||||||
|
(rf/dispatch [:wallet/add-account
|
||||||
|
(assoc account-preferences :key-uid key-uid)
|
||||||
|
derived-account])))
|
||||||
|
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]]]}))
|
||||||
|
|
||||||
(rf/reg-event-fx :keycard/cancel-connection
|
(rf/reg-event-fx :keycard/cancel-connection
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
{:db (update db
|
{:db (update db
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
(ns status-im.contexts.keycard.feature-unavailable.events
|
||||||
|
(:require
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.keycard.feature-unavailable.view :as feature-unavailable]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:keycard/feature-unavailable-upvote
|
||||||
|
(fn [_ [{:keys [feature-name]}]]
|
||||||
|
{:fx [[:dispatch [:open-url constants/mobile-upvote-link]]
|
||||||
|
[:dispatch
|
||||||
|
[:centralized-metrics/track
|
||||||
|
:metric/feature-unavailable-upvote
|
||||||
|
{:feature-name feature-name}]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:keycard/feature-unavailable-show
|
||||||
|
(fn [_ [{:keys [feature-name theme] :as options}]]
|
||||||
|
{:fx [[:dispatch
|
||||||
|
[:show-bottom-sheet
|
||||||
|
{:theme theme
|
||||||
|
:content (fn []
|
||||||
|
(feature-unavailable/view options))}]]
|
||||||
|
[:dispatch
|
||||||
|
[:centralized-metrics/track
|
||||||
|
:metric/feature-unavailable
|
||||||
|
{:feature-name feature-name}]]]}))
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
(ns status-im.contexts.keycard.feature-unavailable.view
|
||||||
|
(:require
|
||||||
|
[quo.core :as quo]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn on-upvote
|
||||||
|
[feature-name]
|
||||||
|
(rf/dispatch [:keycard/feature-unavailable-upvote {:feature-name feature-name}]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[{:keys [feature-name]}]
|
||||||
|
[:<>
|
||||||
|
[quo/drawer-top
|
||||||
|
{:title (i18n/label :t/feature-unavailable)
|
||||||
|
:description (i18n/label :t/feature-unavailable-for-keycard-description)}]
|
||||||
|
[quo/information-box
|
||||||
|
{:type :default
|
||||||
|
:icon :i/info
|
||||||
|
:style {:margin-top 8 :margin-horizontal 20}}
|
||||||
|
[:<>
|
||||||
|
(i18n/label :t/feature-unavailable-info)
|
||||||
|
[quo/text
|
||||||
|
{:style {:text-decoration-line :underline}
|
||||||
|
:size :paragraph-2
|
||||||
|
:on-press #(on-upvote feature-name)}
|
||||||
|
(i18n/label :t/upvote-it)]]]])
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
:title (i18n/label :t/log-in-by-syncing)
|
:title (i18n/label :t/log-in-by-syncing)
|
||||||
:subtitle (i18n/label :t/log-in-by-syncing-subtitle)
|
:subtitle (i18n/label :t/log-in-by-syncing-subtitle)
|
||||||
:accessibility-label :log-in-by-syncing-icon-card
|
:accessibility-label :log-in-by-syncing-icon-card
|
||||||
:image (resources/get-image :ethereum-address)
|
:image (resources/get-image :login-syncing)
|
||||||
:on-press show-check-before-syncing}])
|
:on-press show-check-before-syncing}])
|
||||||
|
|
||||||
(defn- use-empty-keycard-icon-card
|
(defn- use-empty-keycard-icon-card
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
(ns status-im.contexts.onboarding.create-password.style
|
(ns status-im.contexts.onboarding.create-password.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]))
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.platform :as platform]))
|
||||||
|
|
||||||
(def heading {:margin-bottom 20})
|
(def heading {:margin-bottom 20})
|
||||||
(def heading-subtitle {:color colors/white})
|
(def heading-subtitle {:color colors/white})
|
||||||
@@ -21,6 +22,18 @@
|
|||||||
:padding-top 12
|
:padding-top 12
|
||||||
:padding-horizontal 20})
|
:padding-horizontal 20})
|
||||||
|
|
||||||
(def disclaimer-container {:padding-horizontal 20})
|
|
||||||
(def footer-container {:padding-bottom 12})
|
(def footer-container {:padding-bottom 12})
|
||||||
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
||||||
|
|
||||||
|
(def blur-options
|
||||||
|
{:blur-amount 34
|
||||||
|
:blur-radius 20
|
||||||
|
:blur-type :transparent
|
||||||
|
:overlay-color :transparent
|
||||||
|
:background-color (if platform/android?
|
||||||
|
colors/neutral-100
|
||||||
|
colors/neutral-80-opa-1-blur)
|
||||||
|
:padding-vertical 0
|
||||||
|
:padding-horizontal 0})
|
||||||
|
|
||||||
|
(def page-nav-height 56)
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
(ns status-im.contexts.onboarding.create-password.view
|
(ns status-im.contexts.onboarding.create-password.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.floating-button-page.view :as floating-button]
|
[status-im.common.floating-button-page.view :as floating-button]
|
||||||
[status-im.common.password-with-hint.view :as password-with-hint]
|
[status-im.common.password-with-hint.view :as password-with-hint]
|
||||||
@@ -29,22 +27,37 @@
|
|||||||
(i18n/label :t/password-creation-subtitle)]])
|
(i18n/label :t/password-creation-subtitle)]])
|
||||||
|
|
||||||
(defn password-inputs
|
(defn password-inputs
|
||||||
[{:keys [passwords-match? on-change-password on-change-repeat-password on-input-focus
|
[{:keys [set-password set-repeat-password same-password-length? same-passwords?
|
||||||
password-long-enough? password-short-enough? empty-password? show-password-validation?
|
password-long-enough? password-short-enough? non-empty-password?]}]
|
||||||
on-blur-repeat-password]}]
|
(let [[show-validation?
|
||||||
(let [hint-1-status (if password-long-enough? :success :default)
|
set-show-validation?] (rn/use-state false)
|
||||||
hint-2-status (if passwords-match? :success :error)
|
on-change-password (rn/use-callback
|
||||||
hint-2-text (if passwords-match?
|
(fn [new-value]
|
||||||
(i18n/label :t/password-creation-match)
|
(set-password new-value)
|
||||||
(i18n/label :t/password-creation-dont-match))
|
(when same-password-length?
|
||||||
error? (and show-password-validation?
|
(set-show-validation? true)))
|
||||||
(not passwords-match?)
|
[same-password-length?])
|
||||||
(not empty-password?))]
|
on-change-repeat-password (rn/use-callback
|
||||||
|
(fn [new-value]
|
||||||
|
(set-repeat-password new-value)
|
||||||
|
(when same-password-length?
|
||||||
|
(set-show-validation? true)))
|
||||||
|
[same-password-length?])
|
||||||
|
on-blur-repeat-password (rn/use-callback
|
||||||
|
#(set-show-validation? non-empty-password?)
|
||||||
|
[non-empty-password?])
|
||||||
|
hint-1-status (if password-long-enough? :success :default)
|
||||||
|
hint-2-status (if same-passwords? :success :error)
|
||||||
|
hint-2-text (if same-passwords?
|
||||||
|
(i18n/label :t/password-creation-match)
|
||||||
|
(i18n/label :t/password-creation-dont-match))
|
||||||
|
error? (and show-validation?
|
||||||
|
(not same-passwords?)
|
||||||
|
non-empty-password?)]
|
||||||
[:<>
|
[:<>
|
||||||
[password-with-hint/view
|
[password-with-hint/view
|
||||||
{:hint (if (not password-short-enough?)
|
{:hint (if (not password-short-enough?)
|
||||||
{:text (i18n/label
|
{:text (i18n/label :t/password-creation-max-length-hint)
|
||||||
:t/password-creation-max-length-hint)
|
|
||||||
:status :error
|
:status :error
|
||||||
:shown? true}
|
:shown? true}
|
||||||
{:text (i18n/label :t/password-creation-hint)
|
{:text (i18n/label :t/password-creation-hint)
|
||||||
@@ -52,55 +65,50 @@
|
|||||||
:shown? true})
|
:shown? true})
|
||||||
:placeholder (i18n/label :t/password-creation-placeholder-1)
|
:placeholder (i18n/label :t/password-creation-placeholder-1)
|
||||||
:on-change-text on-change-password
|
:on-change-text on-change-password
|
||||||
:on-focus on-input-focus
|
|
||||||
:auto-focus true}]
|
:auto-focus true}]
|
||||||
[rn/view {:style style/space-between-inputs}]
|
[rn/view {:style style/space-between-inputs}]
|
||||||
[password-with-hint/view
|
[password-with-hint/view
|
||||||
{:hint {:text hint-2-text
|
{:hint {:text hint-2-text
|
||||||
:status hint-2-status
|
:status hint-2-status
|
||||||
:shown? (and (not empty-password?)
|
:shown? (and non-empty-password? show-validation?)}
|
||||||
show-password-validation?)}
|
|
||||||
:error? error?
|
:error? error?
|
||||||
:placeholder (i18n/label :t/password-creation-placeholder-2)
|
:placeholder (i18n/label :t/password-creation-placeholder-2)
|
||||||
:on-change-text on-change-repeat-password
|
:on-change-text on-change-repeat-password
|
||||||
:on-focus on-input-focus
|
|
||||||
:on-blur on-blur-repeat-password}]]))
|
:on-blur on-blur-repeat-password}]]))
|
||||||
|
|
||||||
(defn help
|
(defn help
|
||||||
[{{:keys [lower-case? upper-case? numbers? symbols?]} :validations
|
[{:keys [lower-case? upper-case? numbers? symbols?] :as validations}]
|
||||||
password-strength :password-strength}]
|
(let [password-strength (constants/strength-status (password/strength validations) :info)]
|
||||||
[rn/view
|
[rn/view
|
||||||
[quo/strength-divider {:type (constants/strength-status password-strength :info)}
|
[quo/strength-divider {:type password-strength}
|
||||||
(i18n/label :t/password-creation-tips-title)]
|
(i18n/label :t/password-creation-tips-title)]
|
||||||
[rn/view {:style style/password-tips}
|
[rn/view {:style style/password-tips}
|
||||||
[quo/tips {:completed? lower-case?}
|
[quo/tips {:completed? lower-case?}
|
||||||
(i18n/label :t/password-creation-tips-1)]
|
(i18n/label :t/password-creation-tips-1)]
|
||||||
[quo/tips {:completed? upper-case?}
|
[quo/tips {:completed? upper-case?}
|
||||||
(i18n/label :t/password-creation-tips-2)]
|
(i18n/label :t/password-creation-tips-2)]
|
||||||
[quo/tips {:completed? numbers?}
|
[quo/tips {:completed? numbers?}
|
||||||
(i18n/label :t/password-creation-tips-3)]
|
(i18n/label :t/password-creation-tips-3)]
|
||||||
[quo/tips {:completed? symbols?}
|
[quo/tips {:completed? symbols?}
|
||||||
(i18n/label :t/password-creation-tips-4)]]])
|
(i18n/label :t/password-creation-tips-4)]]]))
|
||||||
|
|
||||||
(defn- use-password-checks
|
(defn- use-password-checks
|
||||||
[password]
|
[password]
|
||||||
(rn/use-memo
|
(rn/use-memo
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [long-enough? short-enough?]
|
(-> password
|
||||||
:as validations} (password/validate password)]
|
(password/validate)
|
||||||
{:password-long-enough? long-enough?
|
(assoc :non-empty? (seq password))))
|
||||||
:password-short-enough? short-enough?
|
|
||||||
:password-validations validations
|
|
||||||
:password-strength (password/strength validations)
|
|
||||||
:empty-password? (empty? password)}))
|
|
||||||
[password]))
|
[password]))
|
||||||
|
|
||||||
(defn- use-repeat-password-checks
|
(defn- use-repeat-password-checks
|
||||||
[password repeat-password]
|
[password repeat-password]
|
||||||
(rn/use-memo
|
(rn/use-memo
|
||||||
(fn []
|
(fn []
|
||||||
{:same-password-length? (and (seq password) (= (count password) (count repeat-password)))
|
{:same-password-length? (and (seq password)
|
||||||
:same-passwords? (and (seq password) (= password repeat-password))})
|
(= (count password) (count repeat-password)))
|
||||||
|
:same-passwords? (and (seq password)
|
||||||
|
(= password repeat-password))})
|
||||||
[password repeat-password]))
|
[password repeat-password]))
|
||||||
|
|
||||||
(defn create-password-doc
|
(defn create-password-doc
|
||||||
@@ -119,102 +127,70 @@
|
|||||||
{:content create-password-doc
|
{:content create-password-doc
|
||||||
:shell? true}]))
|
:shell? true}]))
|
||||||
|
|
||||||
(defn- navigate-back
|
(defn- navigate-back [] (rf/dispatch [:navigate-back]))
|
||||||
[]
|
|
||||||
(rf/dispatch [:navigate-back]))
|
|
||||||
|
|
||||||
(defn- page-nav
|
(defn- page-nav
|
||||||
[]
|
[top]
|
||||||
(let [{:keys [top]} (safe-area/get-insets)]
|
[quo/page-nav
|
||||||
[quo/page-nav
|
{:margin-top top
|
||||||
{:margin-top top
|
:background :blur
|
||||||
:background :blur
|
:icon-name :i/arrow-left
|
||||||
:icon-name :i/arrow-left
|
:on-press navigate-back
|
||||||
:on-press navigate-back
|
:right-side [{:icon-name :i/info
|
||||||
:right-side [{:icon-name :i/info
|
:on-press on-press-info}]}])
|
||||||
:on-press on-press-info}]}]))
|
|
||||||
|
(defn- help-and-confirm-button
|
||||||
|
[{:keys [password-validations same-passwords? on-submit]}]
|
||||||
|
(let [{customization-color :color} (rf/sub [:onboarding/profile])
|
||||||
|
all-requirements-met? (and (:non-empty? password-validations)
|
||||||
|
(:long-enough? password-validations)
|
||||||
|
(:short-enough? password-validations)
|
||||||
|
same-passwords?)]
|
||||||
|
[rn/view {:style style/footer-container}
|
||||||
|
[help password-validations]
|
||||||
|
[quo/button
|
||||||
|
{:container-style style/footer-button-container
|
||||||
|
:disabled? (not all-requirements-met?)
|
||||||
|
:customization-color customization-color
|
||||||
|
:on-press on-submit}
|
||||||
|
(i18n/label :t/password-creation-confirm)]]))
|
||||||
|
|
||||||
|
(defn- on-confirm-password
|
||||||
|
[password]
|
||||||
|
(rf/dispatch [:onboarding/password-set (security/mask-data password)]))
|
||||||
|
|
||||||
(defn create-password
|
(defn create-password
|
||||||
[]
|
[]
|
||||||
(let [[password set-password] (rn/use-state "")
|
(let [[password set-password] (rn/use-state "")
|
||||||
[repeat-password set-repeat-password] (rn/use-state "")
|
[repeat-password
|
||||||
[accepts-disclaimer? set-accepts-disclaimer?] (rn/use-state false)
|
set-repeat-password] (rn/use-state "")
|
||||||
[focused-input set-focused-input] (rn/use-state nil)
|
{:keys [long-enough? short-enough? non-empty?]
|
||||||
[show-password-validation?
|
:as password-validations} (use-password-checks password)
|
||||||
set-show-password-validation?] (rn/use-state false)
|
{:keys [same-password-length?
|
||||||
{user-color :color} (rf/sub [:onboarding/profile])
|
same-passwords?]} (use-repeat-password-checks password repeat-password)
|
||||||
|
on-submit (rn/use-callback
|
||||||
|
#(on-confirm-password password)
|
||||||
{:keys [password-long-enough?
|
[password])
|
||||||
password-short-enough?
|
top (safe-area/get-top)]
|
||||||
password-validations password-strength
|
|
||||||
empty-password?]} (use-password-checks password)
|
|
||||||
|
|
||||||
{:keys [same-password-length? same-passwords?]} (use-repeat-password-checks password
|
|
||||||
repeat-password)
|
|
||||||
|
|
||||||
meet-requirements? (and (not empty-password?)
|
|
||||||
password-long-enough?
|
|
||||||
password-short-enough?
|
|
||||||
same-passwords?
|
|
||||||
accepts-disclaimer?)]
|
|
||||||
|
|
||||||
[floating-button/view
|
[floating-button/view
|
||||||
{:header [page-nav]
|
{:header [page-nav top]
|
||||||
:keyboard-should-persist-taps :handled
|
:initial-header-height (+ style/page-nav-height top)
|
||||||
:content-avoid-keyboard? true
|
:keyboard-should-persist-taps :handled
|
||||||
|
:content-avoid-keyboard? true
|
||||||
:automatically-adjust-keyboard-insets true
|
:automatically-adjust-keyboard-insets true
|
||||||
:blur-options
|
:blur-options style/blur-options
|
||||||
{:blur-amount 34
|
:footer-container-padding 0
|
||||||
:blur-radius 20
|
:footer [help-and-confirm-button
|
||||||
:blur-type :transparent
|
{:password-validations password-validations
|
||||||
:overlay-color :transparent
|
:same-passwords? same-passwords?
|
||||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
:on-submit on-submit}]}
|
||||||
:padding-vertical 0
|
|
||||||
:padding-horizontal 0}
|
|
||||||
:footer-container-padding 0
|
|
||||||
:footer
|
|
||||||
[rn/view
|
|
||||||
{:style style/footer-container}
|
|
||||||
(when same-passwords?
|
|
||||||
[rn/view {:style style/disclaimer-container}
|
|
||||||
[quo/disclaimer
|
|
||||||
{:blur? true
|
|
||||||
:on-change (partial set-accepts-disclaimer? not)
|
|
||||||
:checked? accepts-disclaimer?
|
|
||||||
:customization-color user-color}
|
|
||||||
(i18n/label :t/password-creation-disclaimer)]])
|
|
||||||
(when (and (= focused-input :password) (not same-passwords?))
|
|
||||||
[help
|
|
||||||
{:validations password-validations
|
|
||||||
:password-strength password-strength}])
|
|
||||||
[quo/button
|
|
||||||
{:container-style style/footer-button-container
|
|
||||||
:disabled? (not meet-requirements?)
|
|
||||||
:customization-color user-color
|
|
||||||
:on-press #(rf/dispatch
|
|
||||||
[:onboarding/password-set
|
|
||||||
(security/mask-data password)])}
|
|
||||||
(i18n/label :t/password-creation-confirm)]]}
|
|
||||||
|
|
||||||
[rn/view {:style style/form-container}
|
[rn/view {:style style/form-container}
|
||||||
[header]
|
[header]
|
||||||
[password-inputs
|
[password-inputs
|
||||||
{:password-long-enough? password-long-enough?
|
{:password-long-enough? long-enough?
|
||||||
:password-short-enough? password-short-enough?
|
:password-short-enough? short-enough?
|
||||||
:passwords-match? same-passwords?
|
:non-empty-password? non-empty?
|
||||||
:empty-password? empty-password?
|
:same-passwords? same-passwords?
|
||||||
:show-password-validation? show-password-validation?
|
:same-password-length? same-password-length?
|
||||||
:on-input-focus #(set-focused-input :password)
|
:set-password set-password
|
||||||
:on-change-password (fn [new-value]
|
:set-repeat-password set-repeat-password}]]]))
|
||||||
(set-password new-value)
|
|
||||||
(when same-password-length?
|
|
||||||
(set-show-password-validation? true)))
|
|
||||||
|
|
||||||
:on-change-repeat-password (fn [new-value]
|
|
||||||
(set-repeat-password new-value)
|
|
||||||
(when same-password-length?
|
|
||||||
(set-show-password-validation? true)))
|
|
||||||
:on-blur-repeat-password #(if empty-password?
|
|
||||||
(set-show-password-validation? false)
|
|
||||||
(set-show-password-validation? true))}]]]))
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
(ns status-im.contexts.onboarding.create-profile.style
|
|
||||||
(:require
|
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[react-native.platform :as platform]))
|
|
||||||
|
|
||||||
(def continue-button
|
|
||||||
{:width "100%"
|
|
||||||
:margin-left :auto
|
|
||||||
:margin-top (if platform/android? :auto 0)
|
|
||||||
:margin-right :auto})
|
|
||||||
|
|
||||||
(def button-container
|
|
||||||
{:width "100%"
|
|
||||||
:padding-left 20
|
|
||||||
:padding-right 20
|
|
||||||
:padding-top 12
|
|
||||||
:align-self :flex-end
|
|
||||||
:height 64})
|
|
||||||
|
|
||||||
(defn view-button-container
|
|
||||||
[keyboard-shown?]
|
|
||||||
(merge button-container
|
|
||||||
(if platform/ios?
|
|
||||||
{:margin-bottom (if keyboard-shown? 0 34)}
|
|
||||||
{:margin-bottom (if keyboard-shown? 12 34)})))
|
|
||||||
|
|
||||||
(def blur-button-container
|
|
||||||
(merge button-container
|
|
||||||
(when platform/android? {:padding-bottom 12})))
|
|
||||||
|
|
||||||
(def page-container
|
|
||||||
{:position :absolute
|
|
||||||
:top 0
|
|
||||||
:bottom 0
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:z-index 100})
|
|
||||||
|
|
||||||
(def info-message
|
|
||||||
{:margin-top 8})
|
|
||||||
|
|
||||||
(def title
|
|
||||||
{:color colors/white
|
|
||||||
:margin-top 12
|
|
||||||
:margin-bottom 18})
|
|
||||||
|
|
||||||
(def color-title
|
|
||||||
{:color colors/white-70-blur
|
|
||||||
:margin-top 20
|
|
||||||
:margin-bottom 16})
|
|
||||||
|
|
||||||
(def content-container
|
|
||||||
{:padding-horizontal 20})
|
|
||||||
|
|
||||||
(def input-container
|
|
||||||
{:align-items :flex-start})
|
|
||||||
|
|
||||||
(def profile-input-container
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :center})
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
(ns status-im.contexts.onboarding.create-profile.view
|
|
||||||
(:require
|
|
||||||
[clojure.string :as string]
|
|
||||||
[oops.core :as oops]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[react-native.core :as rn]
|
|
||||||
[react-native.hooks :as hooks]
|
|
||||||
[react-native.platform :as platform]
|
|
||||||
[react-native.safe-area :as safe-area]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.common.avatar-picture-picker.view :as profile-picture-picker]
|
|
||||||
[status-im.common.validation.profile :as profile-validator]
|
|
||||||
[status-im.constants :as c]
|
|
||||||
[status-im.contexts.onboarding.create-profile.style :as style]
|
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[utils.responsiveness :as responsiveness]))
|
|
||||||
|
|
||||||
(def scroll-view-height (reagent/atom 0))
|
|
||||||
(def content-container-height (reagent/atom 0))
|
|
||||||
|
|
||||||
(defn show-button-background
|
|
||||||
[keyboard-height keyboard-shown content-scroll-y]
|
|
||||||
(let [button-container-height 64
|
|
||||||
keyboard-view-height (+ keyboard-height button-container-height)]
|
|
||||||
(when keyboard-shown
|
|
||||||
(cond
|
|
||||||
platform/android?
|
|
||||||
(< (- @scroll-view-height button-container-height) @content-container-height)
|
|
||||||
|
|
||||||
platform/ios?
|
|
||||||
(< (- @scroll-view-height keyboard-view-height) (- @content-container-height content-scroll-y))
|
|
||||||
|
|
||||||
:else
|
|
||||||
false))))
|
|
||||||
|
|
||||||
(defn button-container
|
|
||||||
[show-keyboard? keyboard-shown show-background? keyboard-height children]
|
|
||||||
(let [height (reagent/atom 0)]
|
|
||||||
(reset! height (if show-keyboard? (if keyboard-shown keyboard-height 0) 0))
|
|
||||||
[rn/view {:style {:margin-top :auto}}
|
|
||||||
(cond
|
|
||||||
(and (> @height 0) show-background?)
|
|
||||||
[quo/blur
|
|
||||||
(when keyboard-shown
|
|
||||||
{:blur-amount 34
|
|
||||||
:blur-type :transparent
|
|
||||||
:overlay-color :transparent
|
|
||||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
|
||||||
:style style/blur-button-container})
|
|
||||||
children]
|
|
||||||
|
|
||||||
(and (> @height 0) (not show-background?))
|
|
||||||
[rn/view {:style (style/view-button-container true)}
|
|
||||||
children]
|
|
||||||
|
|
||||||
(not show-keyboard?)
|
|
||||||
[rn/view {:style (style/view-button-container false)}
|
|
||||||
children])]))
|
|
||||||
|
|
||||||
(defn- page
|
|
||||||
[{:keys [onboarding-profile-data navigation-bar-top]}]
|
|
||||||
(reagent/with-let [show-keyboard? (reagent/atom false)
|
|
||||||
content-scroll-y (reagent/atom 0)
|
|
||||||
show-listener (oops/ocall rn/keyboard
|
|
||||||
"addListener"
|
|
||||||
(if platform/android?
|
|
||||||
"keyboardDidShow"
|
|
||||||
"keyboardWillShow")
|
|
||||||
#(reset! show-keyboard? true))
|
|
||||||
hide-listener (oops/ocall rn/keyboard
|
|
||||||
"addListener"
|
|
||||||
(if platform/android?
|
|
||||||
"keyboardDidHide"
|
|
||||||
"keyboardWillHide")
|
|
||||||
#(reset! show-keyboard? false))
|
|
||||||
{:keys [image-path display-name color]} onboarding-profile-data
|
|
||||||
full-name (reagent/atom display-name)
|
|
||||||
validation-msg (reagent/atom
|
|
||||||
(profile-validator/validation-name
|
|
||||||
@full-name))
|
|
||||||
on-change-text (fn [s]
|
|
||||||
(reset! validation-msg
|
|
||||||
(profile-validator/validation-name
|
|
||||||
s))
|
|
||||||
(reset! full-name (string/trim 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 %)]
|
|
||||||
(let [name-too-short? (profile-validator/name-too-short? @full-name)
|
|
||||||
valid-name? (and (not @validation-msg) (not name-too-short?))
|
|
||||||
info-message (if @validation-msg
|
|
||||||
@validation-msg
|
|
||||||
(i18n/label :t/minimum-characters
|
|
||||||
{:min-chars
|
|
||||||
profile-validator/min-length}))
|
|
||||||
info-type (cond @validation-msg :error
|
|
||||||
name-too-short? :default
|
|
||||||
:else :success)
|
|
||||||
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
|
||||||
show-background? (show-button-background keyboard-height
|
|
||||||
keyboard-shown
|
|
||||||
@content-scroll-y)
|
|
||||||
{window-width :width} (rn/get-window)]
|
|
||||||
[rn/view {:style style/page-container}
|
|
||||||
[quo/page-nav
|
|
||||||
{:margin-top navigation-bar-top
|
|
||||||
:background :blur
|
|
||||||
:icon-name :i/arrow-left
|
|
||||||
:on-press #(rf/dispatch [:navigate-back])}]
|
|
||||||
[rn/scroll-view
|
|
||||||
{:on-layout (fn [event]
|
|
||||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
|
||||||
(reset! scroll-view-height height)
|
|
||||||
(reset! content-scroll-y 0)))
|
|
||||||
:on-scroll (fn [event]
|
|
||||||
(let [y (oops/oget event "nativeEvent.contentOffset.y")]
|
|
||||||
(reset! content-scroll-y y)))
|
|
||||||
:scroll-event-throttle 64
|
|
||||||
:content-container-style {:flexGrow 1}}
|
|
||||||
[rn/view
|
|
||||||
{:on-layout (fn [event]
|
|
||||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
|
||||||
(reset! content-container-height height)))}
|
|
||||||
[rn/view
|
|
||||||
{:style style/content-container}
|
|
||||||
[quo/text
|
|
||||||
{:size :heading-1
|
|
||||||
:weight :semi-bold
|
|
||||||
:style style/title} (i18n/label :t/create-profile)]
|
|
||||||
[rn/view
|
|
||||||
{:style style/input-container}
|
|
||||||
[rn/view
|
|
||||||
{:style style/profile-input-container}
|
|
||||||
[quo/profile-input
|
|
||||||
{:customization-color @custom-color
|
|
||||||
:placeholder (i18n/label :t/your-name)
|
|
||||||
:on-press (fn []
|
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
|
||||||
(rf/dispatch
|
|
||||||
[:show-bottom-sheet
|
|
||||||
{:content (fn []
|
|
||||||
[profile-picture-picker/view
|
|
||||||
{:on-result on-change-profile-pic
|
|
||||||
:has-picture? false}])
|
|
||||||
:shell? true}]))
|
|
||||||
:image-picker-props {:profile-picture @profile-pic
|
|
||||||
:full-name (if (seq @full-name)
|
|
||||||
@full-name
|
|
||||||
(i18n/label :t/your-name))
|
|
||||||
:customization-color @custom-color}
|
|
||||||
:title-input-props {:default-value display-name
|
|
||||||
:auto-focus true
|
|
||||||
:max-length c/profile-name-max-length
|
|
||||||
:on-change-text on-change-text}}]]
|
|
||||||
|
|
||||||
[quo/info-message
|
|
||||||
{:status info-type
|
|
||||||
:size :default
|
|
||||||
:icon (if valid-name? :i/positive-state :i/info)
|
|
||||||
:color (when (= :default info-type) colors/white-70-blur)
|
|
||||||
:container-style style/info-message}
|
|
||||||
info-message]
|
|
||||||
[quo/text
|
|
||||||
{:size :paragraph-2
|
|
||||||
:weight :medium
|
|
||||||
:style style/color-title}
|
|
||||||
(i18n/label :t/accent-colour)]]]
|
|
||||||
[quo/color-picker
|
|
||||||
{:blur? true
|
|
||||||
:default-selected :blue
|
|
||||||
:on-change on-change
|
|
||||||
:window-width window-width
|
|
||||||
:container-style {:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
|
|
||||||
window-width)}}]]]
|
|
||||||
|
|
||||||
[rn/keyboard-avoiding-view
|
|
||||||
{:style {:position :absolute
|
|
||||||
:top 0
|
|
||||||
:bottom 0
|
|
||||||
:left 0
|
|
||||||
:right 0}
|
|
||||||
:pointer-events :box-none}
|
|
||||||
[button-container @show-keyboard? keyboard-shown show-background? keyboard-height
|
|
||||||
[quo/button
|
|
||||||
{:accessibility-label :submit-create-profile-button
|
|
||||||
:type :primary
|
|
||||||
:customization-color @custom-color
|
|
||||||
:on-press (fn []
|
|
||||||
(rf/dispatch [:onboarding/profile-data-set
|
|
||||||
{:image-path @profile-pic
|
|
||||||
:display-name @full-name
|
|
||||||
:color @custom-color}]))
|
|
||||||
:container-style style/continue-button
|
|
||||||
:disabled? (or (not valid-name?) (not (seq @full-name)))}
|
|
||||||
(i18n/label :t/continue)]]]])
|
|
||||||
(finally
|
|
||||||
(oops/ocall show-listener "remove")
|
|
||||||
(oops/ocall hide-listener "remove"))))
|
|
||||||
|
|
||||||
(defn create-profile
|
|
||||||
[]
|
|
||||||
(let [{:keys [top]} (safe-area/get-insets)
|
|
||||||
onboarding-profile-data (rf/sub [:onboarding/profile])]
|
|
||||||
[page
|
|
||||||
{:navigation-bar-top top
|
|
||||||
:onboarding-profile-data onboarding-profile-data}]))
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
(ns status-im.contexts.onboarding.events
|
(ns status-im.contexts.onboarding.events
|
||||||
(:require
|
(:require
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
status-im.common.biometric.events
|
status-im.common.biometric.events
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
@@ -111,63 +112,57 @@
|
|||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:onboarding/password-set
|
:onboarding/password-set
|
||||||
(fn [{:keys [db]} [masked-password]]
|
(fn [{:keys [db]} [masked-password]]
|
||||||
(let [biometric-supported-type (get-in db [:biometrics :supported-type])]
|
(let [biometric-supported-type (get-in db [:biometrics :supported-type])
|
||||||
|
from-screen (get db
|
||||||
|
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||||
|
:screen/onboarding.new-to-status)]
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:onboarding/profile :password] masked-password)
|
(assoc-in [:onboarding/profile :password] masked-password)
|
||||||
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
||||||
:fx [[:dispatch
|
:fx [[:dispatch
|
||||||
(if biometric-supported-type
|
(if biometric-supported-type
|
||||||
[:navigate-to-within-stack
|
[:navigate-to-within-stack [:screen/onboarding.enable-biometrics from-screen]]
|
||||||
[:screen/onboarding.enable-biometrics
|
|
||||||
(get db
|
|
||||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
|
||||||
:screen/onboarding.new-to-status)]]
|
|
||||||
[:onboarding/create-account-and-login])]]})))
|
[:onboarding/create-account-and-login])]]})))
|
||||||
|
|
||||||
(rf/defn navigate-to-enable-biometrics
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/navigate-to-enable-biometrics]}
|
:onboarding/navigate-to-enable-biometrics
|
||||||
[{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
(let [supported-type (get-in db [:biometrics :supported-type])]
|
(let [supported-type (get-in db [:biometrics :supported-type])]
|
||||||
{:dispatch (if supported-type
|
{:dispatch (if supported-type
|
||||||
[:open-modal :screen/onboarding.enable-biometrics]
|
[:open-modal :screen/onboarding.enable-biometrics]
|
||||||
[:open-modal :screen/onboarding.enable-notifications])}))
|
[:open-modal :screen/onboarding.enable-notifications])})))
|
||||||
|
|
||||||
(rf/defn seed-phrase-validated
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/seed-phrase-validated]}
|
:onboarding/seed-phrase-validated
|
||||||
[{:keys [db]} seed-phrase key-uid]
|
(fn [{:keys [db]} [seed-phrase key-uid]]
|
||||||
(let [syncing-account-recovered? (and (seq (:syncing/key-uid db))
|
(let [next-screen :screen/onboarding.create-profile-password
|
||||||
(= (:syncing/key-uid db) key-uid))
|
from-screen (get db
|
||||||
next-screen (if syncing-account-recovered?
|
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||||
:screen/onboarding.create-profile-password
|
:screen/onboarding.new-to-status)]
|
||||||
:screen/onboarding.create-profile)]
|
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
{:fx [[:effects.utils/show-confirmation
|
||||||
{:effects.utils/show-confirmation
|
{:title (i18n/label :t/multiaccount-exists-title)
|
||||||
{:title (i18n/label :t/multiaccount-exists-title)
|
:content (i18n/label :t/multiaccount-exists-content)
|
||||||
:content (i18n/label :t/multiaccount-exists-content)
|
:confirm-button-text (i18n/label :t/unlock)
|
||||||
:confirm-button-text (i18n/label :t/unlock)
|
:on-accept (fn []
|
||||||
:on-accept (fn []
|
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
(re-frame/dispatch [:profile/profile-selected key-uid]))
|
||||||
(re-frame/dispatch
|
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}]]}
|
||||||
[:profile/profile-selected key-uid]))
|
{:db (-> db
|
||||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
||||||
{:db (-> db
|
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
||||||
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
|
(assoc-in [:onboarding/profile :color] constants/profile-default-color))
|
||||||
(assoc-in [:onboarding/profile :key-uid] key-uid)
|
:fx [[:dispatch [:navigate-to-within-stack [next-screen from-screen]]]]}))))
|
||||||
(assoc-in [:onboarding/profile :color] constants/profile-default-color))
|
|
||||||
:fx [[:dispatch
|
|
||||||
[:navigate-to-within-stack
|
|
||||||
[next-screen
|
|
||||||
(get db
|
|
||||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
|
||||||
:screen/onboarding.new-to-status)]]]]})))
|
|
||||||
|
|
||||||
(rf/defn navigate-to-create-profile
|
(rf/reg-event-fx
|
||||||
{:events [:onboarding/navigate-to-create-profile]}
|
:onboarding/navigate-to-create-profile
|
||||||
[{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
;; Restart the flow
|
{:db (-> db
|
||||||
{:db (dissoc db :onboarding/profile)
|
(assoc-in [:onboarding/profile :color] (rand-nth colors/account-colors))
|
||||||
:dispatch [:navigate-to-within-stack
|
(update :onboarding/profile dissoc :image-path))
|
||||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
|
:fx [[:dispatch
|
||||||
|
[:navigate-to-within-stack
|
||||||
|
[:screen/onboarding.create-profile-password :screen/onboarding.new-to-status]]]]}))
|
||||||
|
|
||||||
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-syncing
|
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-syncing
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
@@ -180,26 +175,43 @@
|
|||||||
(fn [{:keys [db]} [auth-method]]
|
(fn [{:keys [db]} [auth-method]]
|
||||||
{:db (assoc db :auth-method auth-method)}))
|
{:db (assoc db :auth-method auth-method)}))
|
||||||
|
|
||||||
(rf/defn onboarding-new-account-finalize-setup
|
(def ^:const temp-display-name
|
||||||
{:events [:onboarding/finalize-setup]}
|
"While creating a profile, we cannot use an empty string; this value works as a
|
||||||
[{:keys [db]}]
|
placeholder that will be updated later once the compressed key exists. See
|
||||||
(let [masked-password (get-in db [:onboarding/profile :password])
|
`status-im.contexts.profile.edit.name.events/get-default-display-name` for more details."
|
||||||
key-uid (get-in db [:profile/profile :key-uid])
|
"temporal username")
|
||||||
syncing? (get-in db [:onboarding/profile :syncing?])
|
|
||||||
auth-method (get-in db [:onboarding/profile :auth-method])
|
(rf/reg-event-fx
|
||||||
biometric-enabled? (= auth-method constants/auth-method-biometric)]
|
:onboarding/use-temporary-display-name
|
||||||
(cond-> {:db (assoc db :onboarding/generated-keys? true)}
|
(fn [{:keys [db]} [temporary-display-name?]]
|
||||||
biometric-enabled?
|
{:db (assoc db
|
||||||
(assoc :keychain/save-password-and-auth-method
|
:onboarding/profile
|
||||||
{:key-uid key-uid
|
{:temporary-display-name? temporary-display-name?
|
||||||
:masked-password (if syncing?
|
:display-name (if temporary-display-name?
|
||||||
masked-password
|
temp-display-name
|
||||||
(security/hash-masked-password masked-password))
|
"")})}))
|
||||||
:on-success (fn []
|
|
||||||
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
(rf/reg-event-fx
|
||||||
(when syncing?
|
:onboarding/finalize-setup
|
||||||
(rf/dispatch
|
(fn [{db :db}]
|
||||||
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
(let [{:keys [password syncing? auth-method
|
||||||
:on-error #(log/error "failed to save biometrics"
|
temporary-display-name?]} (:onboarding/profile db)
|
||||||
{:key-uid key-uid
|
{:keys [key-uid] :as profile} (:profile/profile db)
|
||||||
:error %})}))))
|
biometric-enabled? (= auth-method constants/auth-method-biometric)]
|
||||||
|
{:db (assoc db :onboarding/generated-keys? true)
|
||||||
|
:fx [(when temporary-display-name?
|
||||||
|
[:dispatch [:profile/set-default-profile-name profile]])
|
||||||
|
(when biometric-enabled?
|
||||||
|
[:keychain/save-password-and-auth-method
|
||||||
|
{:key-uid key-uid
|
||||||
|
:masked-password (if syncing?
|
||||||
|
password
|
||||||
|
(security/hash-masked-password password))
|
||||||
|
:on-success (fn []
|
||||||
|
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
||||||
|
(when syncing?
|
||||||
|
(rf/dispatch
|
||||||
|
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
||||||
|
:on-error #(log/error "failed to save biometrics"
|
||||||
|
{:key-uid key-uid
|
||||||
|
:error %})}])]})))
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
[]
|
[]
|
||||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||||
(blur-show-fn))
|
(blur-show-fn))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||||
(rf/dispatch [:open-modal
|
(rf/dispatch [:open-modal
|
||||||
:screen/onboarding.share-usage
|
:screen/onboarding.share-usage
|
||||||
{:next-screen :screen/onboarding.sync-or-recover-profile}]))
|
{:next-screen :screen/onboarding.sync-or-recover-profile}]))
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
[]
|
[]
|
||||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||||
(blur-show-fn))
|
(blur-show-fn))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||||
(rf/dispatch [:open-modal :screen/onboarding.share-usage
|
(rf/dispatch [:open-modal :screen/onboarding.share-usage
|
||||||
{:next-screen :screen/onboarding.new-to-status}]))
|
{:next-screen :screen/onboarding.new-to-status}]))
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.common.terms.view :as terms]
|
[status-im.common.privacy.view :as privacy]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
[quo/text
|
[quo/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:weight :bold
|
:weight :bold
|
||||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content terms/terms-of-use :shell? true}])}
|
:on-press #(rf/dispatch [:show-bottom-sheet {:content privacy/privacy-statement :shell? true}])}
|
||||||
(i18n/label :t/more-details-in-privacy-policy-2)]]])
|
(i18n/label :t/more-details-in-privacy-policy-2)]]])
|
||||||
|
|
||||||
(defn- bullet-points
|
(defn- bullet-points
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
(ns status-im.contexts.onboarding.share-usage.style)
|
(ns status-im.contexts.onboarding.share-usage.style
|
||||||
|
(:require [quo.foundations.colors :as colors]))
|
||||||
|
|
||||||
(def title-container
|
(def title-container
|
||||||
{:margin-horizontal 20
|
{:margin-horizontal 20
|
||||||
@@ -16,3 +17,7 @@
|
|||||||
[insets]
|
[insets]
|
||||||
{:margin 20
|
{:margin 20
|
||||||
:margin-bottom (+ 12 (:bottom insets))})
|
:margin-bottom (+ 12 (:bottom insets))})
|
||||||
|
|
||||||
|
(def page
|
||||||
|
{:flex 1
|
||||||
|
:background-color colors/neutral-100})
|
||||||
|
|||||||
@@ -17,35 +17,38 @@
|
|||||||
(rf/dispatch [:navigate-to-within-stack [next-screen :screen/onboarding.share-usage]]) ;; Onboarding
|
(rf/dispatch [:navigate-to-within-stack [next-screen :screen/onboarding.share-usage]]) ;; Onboarding
|
||||||
(rf/dispatch [:navigate-back]))) ;; Login Screen
|
(rf/dispatch [:navigate-back]))) ;; Login Screen
|
||||||
|
|
||||||
|
(defn- learn-more
|
||||||
|
[]
|
||||||
|
(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content learn-more-sheet/view
|
||||||
|
:shell? true}]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [insets (safe-area/get-insets)
|
(let [insets (safe-area/get-insets)
|
||||||
next-screen (:next-screen (rf/sub [:get-screen-params :screen/onboarding.share-usage]))
|
next-screen (:next-screen (rf/sub [:get-screen-params :screen/onboarding.share-usage]))
|
||||||
share-usage-data (rn/use-callback #(share-usage-data-fn true next-screen))
|
share-usage-data (rn/use-callback #(share-usage-data-fn true next-screen))
|
||||||
maybe-later (rn/use-callback #(share-usage-data-fn false next-screen))
|
maybe-later (rn/use-callback #(share-usage-data-fn false next-screen))]
|
||||||
learn-more (rn/use-callback #(rf/dispatch [:show-bottom-sheet
|
[rn/view {:style style/page}
|
||||||
{:content learn-more-sheet/view
|
|
||||||
:shell? true}]))]
|
|
||||||
[:<>
|
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:margin-top (:top insets)
|
{:margin-top (:top insets)
|
||||||
:background :blur
|
:background :blur
|
||||||
:icon-name :i/arrow-left
|
:icon-name :i/close
|
||||||
:on-press events-helper/navigate-back
|
:on-press events-helper/navigate-back
|
||||||
:right-side [{:icon-left :i/info
|
:right-side [{:icon-left :i/info
|
||||||
:accessibility-label :learn-more
|
:accessibility-label :learn-more
|
||||||
:label (i18n/label :t/learn-more)
|
:label (i18n/label :t/learn-more)
|
||||||
:on-press learn-more}]}]
|
:on-press learn-more}]}]
|
||||||
[quo/text-combinations
|
[quo/page-top
|
||||||
{:container-style style/title-container
|
{:title (i18n/label :t/help-us-improve-status)
|
||||||
:title (i18n/label :t/help-us-improve-status)
|
|
||||||
:title-accessibility-label :share-usage-title
|
:title-accessibility-label :share-usage-title
|
||||||
:description (i18n/label :t/collecting-usage-data)
|
:description :text
|
||||||
|
:description-text (i18n/label :t/collecting-usage-data)
|
||||||
:description-accessibility-label :share-usage-subtitle}]
|
:description-accessibility-label :share-usage-subtitle}]
|
||||||
[rn/image
|
[rn/image
|
||||||
{:resize-mode :contain
|
{:resize-mode :contain
|
||||||
:style (style/page-illustration (:width (rn/get-window)))
|
:style (style/page-illustration (:width (rn/get-window)))
|
||||||
:source (resources/get-image :biometrics)}]
|
:source (resources/get-image :usage-data)}]
|
||||||
[rn/view {:style (style/buttons insets)}
|
[rn/view {:style (style/buttons insets)}
|
||||||
[quo/button
|
[quo/button
|
||||||
{:size 40
|
{:size 40
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/update-local-picture
|
(rf/reg-event-fx :profile/update-local-picture
|
||||||
(fn [{:keys [db]} [images]]
|
(fn [{:keys [db now]} [images]]
|
||||||
{:db (if 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))}))
|
(update db :profile/profile dissoc :images))}))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/edit-profile-picture-success
|
(rf/reg-event-fx :profile/edit-profile-picture-success
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
(ns status-im.contexts.profile.edit.name.events
|
(ns status-im.contexts.profile.edit.name.events
|
||||||
(:require [utils.i18n :as i18n]
|
(:require [clojure.string :as string]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/edit-profile-name-success
|
(rf/reg-event-fx :profile/edit-profile-name-success
|
||||||
@@ -20,3 +22,16 @@
|
|||||||
:on-success [:profile/edit-profile-name-success]}]]]})
|
:on-success [:profile/edit-profile-name-success]}]]]})
|
||||||
|
|
||||||
(rf/reg-event-fx :profile/edit-name edit-profile-name)
|
(rf/reg-event-fx :profile/edit-name edit-profile-name)
|
||||||
|
|
||||||
|
(defn display-name-from-compressed-key
|
||||||
|
[profile]
|
||||||
|
(-> profile :compressed-key (string/split #"zQ3") second (subs 0 constants/profile-name-max-length)))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:profile/set-default-profile-name
|
||||||
|
(fn [{db :db} [profile]]
|
||||||
|
(let [default-display-name (display-name-from-compressed-key profile)]
|
||||||
|
{:db (assoc-in db [:profile/profile :display-name] default-display-name)
|
||||||
|
:fx [[:json-rpc/call
|
||||||
|
[{:method "wakuext_setDisplayName"
|
||||||
|
:params [default-display-name]}]]]})))
|
||||||
|
|||||||
@@ -47,7 +47,8 @@
|
|||||||
settings
|
settings
|
||||||
{:log-level log-level}))
|
{:log-level log-level}))
|
||||||
(assoc-in [:activity-center :loading?] true)
|
(assoc-in [:activity-center :loading?] true)
|
||||||
(dissoc :centralized-metrics/onboarding-enabled?))]
|
(dissoc :centralized-metrics/onboarding-enabled?))
|
||||||
|
keycard? (get-in new-db [:profile/profile :keycard-pairing])]
|
||||||
{:db (cond-> new-db
|
{:db (cond-> new-db
|
||||||
pairing-completed? (dissoc :syncing))
|
pairing-completed? (dissoc :syncing))
|
||||||
:fx (into [[:json-rpc/call
|
:fx (into [[:json-rpc/call
|
||||||
@@ -75,8 +76,10 @@
|
|||||||
[:effects.chat/open-last-chat (:key-uid profile-overview)])
|
[:effects.chat/open-last-chat (:key-uid profile-overview)])
|
||||||
|
|
||||||
(when (:centralized-metrics/onboarding-enabled? db)
|
(when (:centralized-metrics/onboarding-enabled? db)
|
||||||
[:dispatch [:profile.settings/toggle-telemetry true]])]
|
[:dispatch [:profile.settings/toggle-telemetry true]])
|
||||||
|
|
||||||
|
(when keycard?
|
||||||
|
[:dispatch [:centralized-metrics/track :metric/keycard-login]])]
|
||||||
(cond
|
(cond
|
||||||
pairing-completed?
|
pairing-completed?
|
||||||
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
|
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
|
||||||
@@ -152,15 +155,12 @@
|
|||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:profile.login/login-node-signal
|
:profile.login/login-node-signal
|
||||||
(fn [{{:onboarding/keys [recovered-account? new-account?] :as db} :db}
|
(fn [{db :db} [{:keys [settings account ensUsernames error]}]]
|
||||||
[{:keys [settings account ensUsernames error]}]]
|
|
||||||
(log/debug "[signals] node.login" "error" error)
|
(log/debug "[signals] node.login" "error" error)
|
||||||
(if error
|
(if error
|
||||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||||
{:db (dissoc db :profile/login)
|
{:db (dissoc db :profile/login)
|
||||||
:fx [(when (and new-account? (not recovered-account?))
|
:fx [[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
||||||
[:dispatch-later [{:ms 1000 :dispatch [:wallet-legacy/set-initial-blocks-range]}]])
|
|
||||||
[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
|
||||||
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
[]
|
[]
|
||||||
(when @push-animation-fn-atom
|
(when @push-animation-fn-atom
|
||||||
(@push-animation-fn-atom))
|
(@push-animation-fn-atom))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name true])
|
||||||
(debounce/throttle-and-dispatch
|
(debounce/throttle-and-dispatch
|
||||||
[:open-modal :screen/onboarding.new-to-status]
|
[:open-modal :screen/onboarding.new-to-status]
|
||||||
1000))
|
1000))
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
[]
|
[]
|
||||||
(when @push-animation-fn-atom
|
(when @push-animation-fn-atom
|
||||||
(@push-animation-fn-atom))
|
(@push-animation-fn-atom))
|
||||||
|
(rf/dispatch [:onboarding/use-temporary-display-name false])
|
||||||
(debounce/throttle-and-dispatch
|
(debounce/throttle-and-dispatch
|
||||||
[:open-modal :screen/onboarding.sync-or-recover-profile]
|
[:open-modal :screen/onboarding.sync-or-recover-profile]
|
||||||
1000))
|
1000))
|
||||||
|
|||||||
@@ -129,8 +129,10 @@
|
|||||||
[:dispatch [:hide-bottom-sheet]]]})))
|
[:dispatch [:hide-bottom-sheet]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile.settings/update-local-picture
|
(rf/reg-event-fx :profile.settings/update-local-picture
|
||||||
(fn [{:keys [db]} [images]]
|
(fn [{:keys [db now]} [images]]
|
||||||
{:db (assoc-in db [:profile/profile :images] images)}))
|
{:db (assoc-in db
|
||||||
|
[:profile/profile :images]
|
||||||
|
(map #(assoc % :clock now) images))}))
|
||||||
|
|
||||||
(rf/reg-event-fx :profile.settings/mnemonic-was-shown
|
(rf/reg-event-fx :profile.settings/mnemonic-was-shown
|
||||||
(fn [_]
|
(fn [_]
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
:blur? true
|
:blur? true
|
||||||
:image-props :i/light})]
|
:image-props :i/light})]
|
||||||
[{:title (i18n/label :t/about)
|
[{:title (i18n/label :t/about)
|
||||||
:on-press #(rf/dispatch [:open-modal :about-app])
|
:on-press #(rf/dispatch [:open-modal :screen/settings.about])
|
||||||
:action :arrow
|
:action :arrow
|
||||||
:blur? true}
|
:blur? true}
|
||||||
{:title (i18n/label :t/status-help)
|
{:title (i18n/label :t/status-help)
|
||||||
|
|||||||
@@ -7,33 +7,39 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- on-press-biometric-enable
|
(defn- on-press-biometric-enable
|
||||||
[button-label theme]
|
[button-label theme keycard-profile?]
|
||||||
(fn []
|
(fn []
|
||||||
(rf/dispatch
|
(if keycard-profile?
|
||||||
[:standard-auth/authorize-with-password
|
(rf/dispatch [:keycard/feature-unavailable-show
|
||||||
{:blur? true
|
{:theme :dark
|
||||||
:theme theme
|
:feature-name :settings.enable-biometrics}])
|
||||||
:auth-button-label (i18n/label :t/biometric-enable-button {:bio-type-label button-label})
|
(rf/dispatch
|
||||||
:on-auth-success (fn [password]
|
[:standard-auth/authorize-with-password
|
||||||
(rf/dispatch [:hide-bottom-sheet])
|
{:blur? true
|
||||||
(rf/dispatch
|
:theme theme
|
||||||
[:biometric/authenticate
|
:auth-button-label (i18n/label :t/biometric-enable-button {:bio-type-label button-label})
|
||||||
{:on-success #(rf/dispatch [:biometric/enable password])
|
:on-auth-success (fn [password]
|
||||||
:on-fail #(rf/dispatch [:biometric/show-message (ex-cause %)])}]))}])))
|
(rf/dispatch [:hide-bottom-sheet])
|
||||||
|
(rf/dispatch
|
||||||
|
[:biometric/authenticate
|
||||||
|
{:on-success #(rf/dispatch [:biometric/enable password])
|
||||||
|
:on-fail #(rf/dispatch [:biometric/show-message
|
||||||
|
(ex-cause %)])}]))}]))))
|
||||||
|
|
||||||
(defn- get-biometric-item
|
(defn- get-biometric-item
|
||||||
[theme]
|
[theme]
|
||||||
(let [auth-method (rf/sub [:auth-method])
|
(let [auth-method (rf/sub [:auth-method])
|
||||||
biometric-type (rf/sub [:biometrics/supported-type])
|
biometric-type (rf/sub [:biometrics/supported-type])
|
||||||
label (biometric/get-label-by-type biometric-type)
|
keycard-profile? (rf/sub [:keycard/keycard-profile?])
|
||||||
icon (biometric/get-icon-by-type biometric-type)
|
label (biometric/get-label-by-type biometric-type)
|
||||||
supported? (boolean biometric-type)
|
icon (biometric/get-icon-by-type biometric-type)
|
||||||
enabled? (= auth-method constants/auth-method-biometric)
|
supported? (boolean biometric-type)
|
||||||
biometric-on? (and supported? enabled?)
|
enabled? (= auth-method constants/auth-method-biometric)
|
||||||
press-handler (when supported?
|
biometric-on? (and supported? enabled?)
|
||||||
(if biometric-on?
|
press-handler (when supported?
|
||||||
(fn [] (rf/dispatch [:biometric/disable]))
|
(if biometric-on?
|
||||||
(on-press-biometric-enable label theme)))]
|
(fn [] (rf/dispatch [:biometric/disable]))
|
||||||
|
(on-press-biometric-enable label theme keycard-profile?)))]
|
||||||
{:title label
|
{:title label
|
||||||
:image-props icon
|
:image-props icon
|
||||||
:image :icon
|
:image :icon
|
||||||
@@ -58,7 +64,8 @@
|
|||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)
|
||||||
|
keycard-profile? (rf/sub [:keycard/keycard-profile?])]
|
||||||
[quo/overlay {:type :shell :top-inset? true}
|
[quo/overlay {:type :shell :top-inset? true}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:background :blur
|
{:background :blur
|
||||||
@@ -68,6 +75,7 @@
|
|||||||
[quo/category
|
[quo/category
|
||||||
{:key :category
|
{:key :category
|
||||||
:data [(get-biometric-item theme)
|
:data [(get-biometric-item theme)
|
||||||
(get-change-password-item)]
|
(when-not keycard-profile?
|
||||||
|
(get-change-password-item))]
|
||||||
:blur? true
|
:blur? true
|
||||||
:list-type :settings}]]))
|
:list-type :settings}]]))
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
(ns status-im.contexts.settings.about.style)
|
||||||
|
|
||||||
|
(def category-spacing {:padding-bottom 12})
|
||||||
|
|
||||||
|
(def app-info-container
|
||||||
|
{:padding-horizontal 20
|
||||||
|
:padding-top 8
|
||||||
|
:padding-bottom 16
|
||||||
|
:row-gap 16})
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
(ns status-im.contexts.settings.about.view
|
||||||
|
(:require [quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.settings.about.style :as style]
|
||||||
|
[status-im.contexts.settings.common.header :as header]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn- open-link
|
||||||
|
[url]
|
||||||
|
(rf/dispatch [:browser.ui/open-url url]))
|
||||||
|
|
||||||
|
(defn- copy
|
||||||
|
[data item-name]
|
||||||
|
(rf/dispatch [:share/copy-text-and-show-toast
|
||||||
|
{:text-to-copy data
|
||||||
|
:post-copy-message (str item-name
|
||||||
|
" "
|
||||||
|
(i18n/label :t/sharing-copied-to-clipboard))}]))
|
||||||
|
|
||||||
|
(def about-data
|
||||||
|
[{:app-info? true}
|
||||||
|
{:category-label (i18n/label :t/website)
|
||||||
|
:items [{:title "status.app"
|
||||||
|
:on-press #(open-link constants/status-app-url)
|
||||||
|
:blur? true
|
||||||
|
:action :arrow
|
||||||
|
:action-props {:icon :i/external}}]}
|
||||||
|
{:category-label (i18n/label :t/github-repos)
|
||||||
|
:items [{:title "status-mobile"
|
||||||
|
:on-press #(open-link constants/status-mobile-url)
|
||||||
|
:blur? true
|
||||||
|
:action :arrow
|
||||||
|
:action-props {:icon :i/external}}
|
||||||
|
{:title "status-go"
|
||||||
|
:on-press #(open-link constants/status-go-url)
|
||||||
|
:blur? true
|
||||||
|
:action :arrow
|
||||||
|
:action-props {:icon :i/external}}
|
||||||
|
{:title "go-waku"
|
||||||
|
:on-press #(open-link constants/go-waku-url)
|
||||||
|
:blur? true
|
||||||
|
:action :arrow
|
||||||
|
:action-props {:icon :i/external}}]}
|
||||||
|
{:category-label (i18n/label :t/documents)
|
||||||
|
:items [{:title (i18n/label :t/privacy-policy)
|
||||||
|
:on-press #(rf/dispatch [:open-modal :screen/settings.privacy-policy])
|
||||||
|
:blur? true
|
||||||
|
:action :arrow}
|
||||||
|
{:title (i18n/label :t/terms-of-service)
|
||||||
|
:on-press #(rf/dispatch [:open-modal :screen/settings.terms-of-use])
|
||||||
|
:blur? true
|
||||||
|
:action :arrow}]}])
|
||||||
|
|
||||||
|
(defn info-item
|
||||||
|
[{:keys [title info]}]
|
||||||
|
[quo/data-item
|
||||||
|
{:size :default
|
||||||
|
:status :default
|
||||||
|
:right-icon :i/copy
|
||||||
|
:card? true
|
||||||
|
:blur? true
|
||||||
|
:title title
|
||||||
|
:on-press #(copy info title)
|
||||||
|
:subtitle info
|
||||||
|
:subtitle-type :default
|
||||||
|
:subtitle-text-props {:number-of-lines 1
|
||||||
|
:ellipsize-mode :middle}}])
|
||||||
|
|
||||||
|
(defn- app-info
|
||||||
|
[]
|
||||||
|
(let [app-version (rf/sub [:get-app-short-version])
|
||||||
|
commit-hash (rf/sub [:get-commit-hash])
|
||||||
|
node-version (rf/sub [:get-app-node-version])]
|
||||||
|
[rn/view {:style style/app-info-container}
|
||||||
|
[info-item {:title (i18n/label :t/version) :info app-version}]
|
||||||
|
[info-item {:title (i18n/label :t/app-commit) :info commit-hash}]
|
||||||
|
[info-item {:title (i18n/label :t/node-version) :info node-version}]]))
|
||||||
|
|
||||||
|
(defn category
|
||||||
|
[{:keys [app-info? category-label items]}]
|
||||||
|
(if app-info?
|
||||||
|
[app-info]
|
||||||
|
[quo/category
|
||||||
|
{:label category-label
|
||||||
|
:list-type :settings
|
||||||
|
:container-style style/category-spacing
|
||||||
|
:blur? true
|
||||||
|
:data items}]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
[quo/overlay {:type :shell}
|
||||||
|
[header/view {:title (i18n/label :t/about)}]
|
||||||
|
[rn/flat-list
|
||||||
|
{:data about-data
|
||||||
|
:shows-vertical-scroll-indicator false
|
||||||
|
:render-fn category
|
||||||
|
:bounces false
|
||||||
|
:over-scroll-mode :never}]])
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
(ns status-im.contexts.settings.common.header
|
||||||
|
(:require [quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
|
[status-im.common.events-helper :as events-helper]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[{:keys [title]}]
|
||||||
|
[rn/view {:style {:padding-top (safe-area/get-top)}}
|
||||||
|
[quo/page-nav
|
||||||
|
{:background :blur
|
||||||
|
:icon-name :i/arrow-left
|
||||||
|
:on-press events-helper/navigate-back}]
|
||||||
|
[quo/page-top {:title title}]])
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
(defn- keypair
|
(defn- keypair
|
||||||
[{keypair-type :type
|
[{keypair-type :type
|
||||||
:keys [accounts name]
|
:keys [accounts name keycard?]
|
||||||
:as item}
|
:as item}
|
||||||
_ _
|
_ _
|
||||||
{:keys [profile-picture compressed-key customization-color]}]
|
{:keys [profile-picture compressed-key customization-color]}]
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
:type (if default-keypair?
|
:type (if default-keypair?
|
||||||
:default-keypair
|
:default-keypair
|
||||||
:keypair)
|
:keypair)
|
||||||
:stored :on-device
|
:stored (if keycard? :on-keycard :on-device)
|
||||||
:shortened-key shortened-key
|
:shortened-key shortened-key
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:profile-picture profile-picture})}))
|
:profile-picture profile-picture})}))
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
[quo/keypair
|
[quo/keypair
|
||||||
{:blur? true
|
{:blur? true
|
||||||
:status-indicator false
|
:status-indicator false
|
||||||
:stored :on-device
|
:stored (if keycard? :on-keycard :on-device)
|
||||||
:action (if default-keypair? :none :options)
|
:action (if default-keypair? :none :options)
|
||||||
:accounts accounts
|
:accounts accounts
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
|
|||||||
@@ -38,7 +38,13 @@
|
|||||||
#(if (:enabled? %)
|
#(if (:enabled? %)
|
||||||
:paired-devices
|
:paired-devices
|
||||||
:unpaired-devices)
|
:unpaired-devices)
|
||||||
other-devices)]
|
other-devices)
|
||||||
|
keycard? (rf/sub [:keycard/keycard-profile?])
|
||||||
|
keycard-feature-unavailable (rn/use-callback
|
||||||
|
#(rf/dispatch
|
||||||
|
[:keycard/feature-unavailable-show
|
||||||
|
{:theme :dark
|
||||||
|
:feature-name :settings.setup-syncing}]))]
|
||||||
[quo/overlay {:type :shell :top-inset? true}
|
[quo/overlay {:type :shell :top-inset? true}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:type :no-title
|
{:type :no-title
|
||||||
@@ -60,7 +66,9 @@
|
|||||||
:type :primary
|
:type :primary
|
||||||
:customization-color profile-color
|
:customization-color profile-color
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
:on-press open-setup-syncing-with-customization-color}
|
:on-press (if keycard?
|
||||||
|
keycard-feature-unavailable
|
||||||
|
open-setup-syncing-with-customization-color)}
|
||||||
:i/add]]
|
:i/add]]
|
||||||
[device/view (merge user-device {:this-device? true})]
|
[device/view (merge user-device {:this-device? true})]
|
||||||
(when (seq paired-devices)
|
(when (seq paired-devices)
|
||||||
|
|||||||
@@ -69,7 +69,9 @@
|
|||||||
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
|
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
|
||||||
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||||
{keypair-name :name
|
{keypair-name :name
|
||||||
keypair-type :type} (rf/sub [:wallet/current-viewing-account-keypair])
|
keypair-type :type
|
||||||
|
keycards :keycards} (rf/sub [:wallet/current-viewing-account-keypair])
|
||||||
|
keypair-keycard? (boolean (seq keycards))
|
||||||
networks (rf/sub [:wallet/network-preference-details])
|
networks (rf/sub [:wallet/network-preference-details])
|
||||||
origin-type (case keypair-type
|
origin-type (case keypair-type
|
||||||
:seed
|
:seed
|
||||||
@@ -98,7 +100,7 @@
|
|||||||
(when (not watch-only?)
|
(when (not watch-only?)
|
||||||
[quo/account-origin
|
[quo/account-origin
|
||||||
{:type origin-type
|
{:type origin-type
|
||||||
:stored :on-device
|
:stored (if keypair-keycard? :on-keycard :on-device)
|
||||||
:profile-picture (profile.utils/photo profile)
|
:profile-picture (profile.utils/photo profile)
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:derivation-path path
|
:derivation-path path
|
||||||
|
|||||||
@@ -58,13 +58,14 @@
|
|||||||
[item _ _
|
[item _ _
|
||||||
{:keys [profile-picture compressed-key selected-key-uid set-selected-key-uid customization-color]}]
|
{:keys [profile-picture compressed-key selected-key-uid set-selected-key-uid customization-color]}]
|
||||||
(let [profile-keypair? (= (:type item) :profile)
|
(let [profile-keypair? (= (:type item) :profile)
|
||||||
|
keycard? (boolean (seq (:keycards item)))
|
||||||
accounts (parse-accounts (:accounts item))]
|
accounts (parse-accounts (:accounts item))]
|
||||||
[quo/keypair
|
[quo/keypair
|
||||||
{:customization-color customization-color
|
{:customization-color customization-color
|
||||||
:profile-picture (when profile-keypair? profile-picture)
|
:profile-picture (when profile-keypair? profile-picture)
|
||||||
:status-indicator false
|
:status-indicator false
|
||||||
:type (if profile-keypair? :default-keypair :other)
|
:type (if profile-keypair? :default-keypair :other)
|
||||||
:stored :on-device
|
:stored (if keycard? :on-keycard :on-device)
|
||||||
:on-options-press #(js/alert "Options pressed")
|
:on-options-press #(js/alert "Options pressed")
|
||||||
:action :selector
|
:action :selector
|
||||||
:blur? false
|
:blur? false
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
[utils.string]))
|
[utils.string]))
|
||||||
|
|
||||||
(defn- get-keypair-data
|
(defn- get-keypair-data
|
||||||
[{:keys [title primary-keypair? new-keypair? derivation-path customization-color]}]
|
[{:keys [title primary-keypair? new-keypair? derivation-path customization-color keycard?]}]
|
||||||
[{:title title
|
[{:title title
|
||||||
:image (if primary-keypair? :avatar :icon)
|
:image (if primary-keypair? :avatar :icon)
|
||||||
:image-props (if primary-keypair?
|
:image-props (if primary-keypair?
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
:button-text (i18n/label :t/edit)
|
:button-text (i18n/label :t/edit)
|
||||||
:alignment :flex-start}
|
:alignment :flex-start}
|
||||||
:description :text
|
:description :text
|
||||||
:description-props {:text (i18n/label :t/on-device)}}
|
:description-props {:text (i18n/label (if keycard? :on-keycard :on-device))}}
|
||||||
(when-not (string/blank? derivation-path)
|
(when-not (string/blank? derivation-path)
|
||||||
(let [formatted-path (string/replace derivation-path #"/" " / ")
|
(let [formatted-path (string/replace derivation-path #"/" " / ")
|
||||||
on-auth-success (fn [password]
|
on-auth-success (fn [password]
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
:container-style color-picker-style}]])])))
|
:container-style color-picker-style}]])])))
|
||||||
|
|
||||||
(defn- new-account-origin
|
(defn- new-account-origin
|
||||||
[{:keys [keypair-title derivation-path customization-color]}]
|
[{:keys [keypair-title derivation-path customization-color keycard?]}]
|
||||||
(let [{keypair-name :name} (rf/sub [:wallet/selected-keypair])
|
(let [{keypair-name :name} (rf/sub [:wallet/selected-keypair])
|
||||||
primary? (rf/sub [:wallet/selected-primary-keypair?])
|
primary? (rf/sub [:wallet/selected-primary-keypair?])
|
||||||
keypair-name (or keypair-title
|
keypair-name (or keypair-title
|
||||||
@@ -135,7 +135,8 @@
|
|||||||
[quo/category
|
[quo/category
|
||||||
{:list-type :settings
|
{:list-type :settings
|
||||||
:label (i18n/label :t/origin)
|
:label (i18n/label :t/origin)
|
||||||
:data (get-keypair-data {:primary-keypair? primary?
|
:data (get-keypair-data {:keycard? keycard?
|
||||||
|
:primary-keypair? primary?
|
||||||
:title keypair-name
|
:title keypair-name
|
||||||
:derivation-path derivation-path
|
:derivation-path derivation-path
|
||||||
:customization-color customization-color})}]]))
|
:customization-color customization-color})}]]))
|
||||||
@@ -229,20 +230,37 @@
|
|||||||
set-derivation-path #(reset! derivation-path %)]
|
set-derivation-path #(reset! derivation-path %)]
|
||||||
(fn [{:keys [on-change-text set-account-color set-emoji customization-color error]}]
|
(fn [{:keys [on-change-text set-account-color set-emoji customization-color error]}]
|
||||||
(let [{:keys [derived-from
|
(let [{:keys [derived-from
|
||||||
key-uid]} (rf/sub [:wallet/selected-keypair])
|
key-uid keycards]} (rf/sub [:wallet/selected-keypair])
|
||||||
on-auth-success (rn/use-callback
|
keycard? (boolean (seq keycards))
|
||||||
(fn [password]
|
on-auth-success (rn/use-callback
|
||||||
(let [preferences {:account-name @account-name
|
(fn [password]
|
||||||
:color @account-color
|
(let [preferences {:account-name @account-name
|
||||||
:emoji @emoji}]
|
:color @account-color
|
||||||
(rf/dispatch
|
:emoji @emoji}]
|
||||||
[:wallet/derive-address-and-add-account
|
(rf/dispatch
|
||||||
{:password password
|
[:wallet/derive-address-and-add-account
|
||||||
:derived-from-address derived-from
|
{:password password
|
||||||
:key-uid key-uid
|
:derived-from-address derived-from
|
||||||
:derivation-path @derivation-path
|
:key-uid key-uid
|
||||||
:account-preferences preferences}])))
|
:derivation-path @derivation-path
|
||||||
[derived-from])]
|
:account-preferences preferences}])))
|
||||||
|
[derived-from])
|
||||||
|
on-complete (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(let [preferences {:account-name @account-name
|
||||||
|
:color @account-color
|
||||||
|
:emoji @emoji}]
|
||||||
|
(rf/dispatch
|
||||||
|
[:standard-auth/authorize-with-keycard
|
||||||
|
{:on-complete
|
||||||
|
#(rf/dispatch
|
||||||
|
[:keycard/connect-derive-address-and-add-account
|
||||||
|
{:pin %
|
||||||
|
:derived-from-address derived-from
|
||||||
|
:key-uid key-uid
|
||||||
|
:derivation-path @derivation-path
|
||||||
|
:account-preferences preferences}])}])))
|
||||||
|
[derived-from])]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
#(rf/dispatch
|
#(rf/dispatch
|
||||||
[:wallet/next-derivation-path
|
[:wallet/next-derivation-path
|
||||||
@@ -252,10 +270,13 @@
|
|||||||
|
|
||||||
[floating-button
|
[floating-button
|
||||||
{:account-color @account-color
|
{:account-color @account-color
|
||||||
:slide-button-props {:on-auth-success on-auth-success
|
:slide-button-props {:on-auth-success (when-not keycard? on-auth-success)
|
||||||
:disabled? (or (empty? @account-name)
|
:on-complete
|
||||||
(string/blank? @derivation-path)
|
(when keycard? on-complete)
|
||||||
(some? error))}}
|
:disabled?
|
||||||
|
(or (empty? @account-name)
|
||||||
|
(string/blank? @derivation-path)
|
||||||
|
(some? error))}}
|
||||||
[avatar
|
[avatar
|
||||||
{:account-color @account-color
|
{:account-color @account-color
|
||||||
:emoji @emoji
|
:emoji @emoji
|
||||||
@@ -269,7 +290,8 @@
|
|||||||
{:account-color @account-color
|
{:account-color @account-color
|
||||||
:set-account-color set-account-color}]
|
:set-account-color set-account-color}]
|
||||||
[new-account-origin
|
[new-account-origin
|
||||||
{:derivation-path @derivation-path
|
{:keycard? keycard?
|
||||||
|
:derivation-path @derivation-path
|
||||||
:customization-color customization-color}]]))))
|
:customization-color customization-color}]]))))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
type :no-title}}]
|
type :no-title}}]
|
||||||
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||||
networks (rf/sub [:wallet/selected-network-details])
|
networks (rf/sub [:wallet/selected-network-details])
|
||||||
sending-collectible? (rf/sub [:wallet/sending-collectible?])]
|
sending-collectible? (rf/sub [:wallet/sending-collectible?])
|
||||||
|
keycard? (rf/sub [:wallet/selected-keypair-keycard?])]
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:type type
|
{:type type
|
||||||
:icon-name icon-name
|
:icon-name icon-name
|
||||||
@@ -45,7 +46,11 @@
|
|||||||
(not watch-only?)
|
(not watch-only?)
|
||||||
show-dapps-button?)
|
show-dapps-button?)
|
||||||
{:icon-name :i/dapps
|
{:icon-name :i/dapps
|
||||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
|
:on-press #(rf/dispatch
|
||||||
|
(if keycard?
|
||||||
|
[:keycard/feature-unavailable-show
|
||||||
|
{:feature-name :wallet.show-connected-dapps}]
|
||||||
|
[:navigate-to :screen/wallet.connected-dapps]))})
|
||||||
(when-not sending-collectible?
|
(when-not sending-collectible?
|
||||||
{:content-type :account-switcher
|
{:content-type :account-switcher
|
||||||
:customization-color color
|
:customization-color color
|
||||||
|
|||||||
@@ -291,3 +291,10 @@
|
|||||||
(cske/transform-keys transforms/->kebab-case-keyword)
|
(cske/transform-keys transforms/->kebab-case-keyword)
|
||||||
(map #(assoc % :unique-id (collectible-utils/get-collectible-unique-id %)))
|
(map #(assoc % :unique-id (collectible-utils/get-collectible-unique-id %)))
|
||||||
vec))
|
vec))
|
||||||
|
|
||||||
|
(defn selected-keypair-keycard?
|
||||||
|
[db]
|
||||||
|
(let [keypairs (get-in db [:wallet :keypairs])
|
||||||
|
selected-keypair-uid (get-in db [:wallet :ui :create-account :selected-keypair-uid])
|
||||||
|
keypair (get keypairs selected-keypair-uid)]
|
||||||
|
(boolean (seq (:keycards keypair)))))
|
||||||
|
|||||||
@@ -231,3 +231,37 @@
|
|||||||
:wallet true
|
:wallet true
|
||||||
:default-account? true})]}}}
|
:default-account? true})]}}}
|
||||||
(sut/reconcile-keypairs [raw-keypair-profile])))))
|
(sut/reconcile-keypairs [raw-keypair-profile])))))
|
||||||
|
|
||||||
|
(def mock-db
|
||||||
|
{:wallet {:keypairs
|
||||||
|
{"0x123" {:type "key"
|
||||||
|
:key-uid "0x123"
|
||||||
|
:keycards [{:id "keycard1"}]}
|
||||||
|
"0x456" {:type "key"
|
||||||
|
:key-uid "0x456"
|
||||||
|
:keycards []}}
|
||||||
|
:ui {:create-account {:selected-keypair-uid "0x123"}}}})
|
||||||
|
|
||||||
|
(deftest selected-keypair-keycard?-test
|
||||||
|
(testing "returns true when the selected keypair has keycards"
|
||||||
|
(is (true? (sut/selected-keypair-keycard? mock-db))))
|
||||||
|
|
||||||
|
(testing "returns false when the selected keypair does not have keycards"
|
||||||
|
(let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] "0x456")]
|
||||||
|
(is (false? (sut/selected-keypair-keycard? db)))))
|
||||||
|
|
||||||
|
(testing "returns false when the selected keypair does not exist"
|
||||||
|
(let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] "0x789")]
|
||||||
|
(is (false? (sut/selected-keypair-keycard? db)))))
|
||||||
|
|
||||||
|
(testing "returns false when keypairs map is empty"
|
||||||
|
(let [db (assoc-in mock-db [:wallet :keypairs] {})]
|
||||||
|
(is (false? (sut/selected-keypair-keycard? db)))))
|
||||||
|
|
||||||
|
(testing "returns false when no keypair is selected"
|
||||||
|
(let [db (assoc-in mock-db [:wallet :ui :create-account :selected-keypair-uid] nil)]
|
||||||
|
(is (false? (sut/selected-keypair-keycard? db)))))
|
||||||
|
|
||||||
|
(testing "returns false when db does not contain wallet data"
|
||||||
|
(let [db {}]
|
||||||
|
(is (false? (sut/selected-keypair-keycard? db))))))
|
||||||
|
|||||||
@@ -215,7 +215,7 @@
|
|||||||
{:db (assoc-in db [:wallet :ui :tokens-loading address] true)
|
{:db (assoc-in db [:wallet :ui :tokens-loading address] true)
|
||||||
:fx [[:json-rpc/call
|
:fx [[:json-rpc/call
|
||||||
[{:method "wallet_fetchOrGetCachedWalletBalances"
|
[{:method "wallet_fetchOrGetCachedWalletBalances"
|
||||||
:params [[address]]
|
:params [[address] true]
|
||||||
:on-success [:wallet/store-wallet-token address]
|
:on-success [:wallet/store-wallet-token address]
|
||||||
:on-error [:wallet/get-wallet-token-for-account-failed address]}]]]}))
|
:on-error [:wallet/get-wallet-token-for-account-failed address]}]]]}))
|
||||||
|
|
||||||
@@ -307,9 +307,8 @@
|
|||||||
|
|
||||||
(rf/reg-event-fx :wallet/add-account
|
(rf/reg-event-fx :wallet/add-account
|
||||||
(fn [_
|
(fn [_
|
||||||
[{:keys [key-uid password account-name emoji color type]
|
[{:keys [key-uid password account-name emoji color type] :or {type :generated}}
|
||||||
:or {type :generated}}
|
{:keys [public-key address path]}]]
|
||||||
{:keys [public-key address path] :as _derived-account}]]
|
|
||||||
(let [lowercase-address (some-> address
|
(let [lowercase-address (some-> address
|
||||||
string/lower-case)
|
string/lower-case)
|
||||||
account-config {:key-uid (when (= type :generated) key-uid)
|
account-config {:key-uid (when (= type :generated) key-uid)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
(let [expected-effects {:db {:wallet {:ui {:tokens-loading {address true}}}}
|
(let [expected-effects {:db {:wallet {:ui {:tokens-loading {address true}}}}
|
||||||
:fx [[:json-rpc/call
|
:fx [[:json-rpc/call
|
||||||
[{:method "wallet_fetchOrGetCachedWalletBalances"
|
[{:method "wallet_fetchOrGetCachedWalletBalances"
|
||||||
:params [[address]]
|
:params [[address] true]
|
||||||
:on-success [:wallet/store-wallet-token address]
|
:on-success [:wallet/store-wallet-token address]
|
||||||
:on-error [:wallet/get-wallet-token-for-account-failed
|
:on-error [:wallet/get-wallet-token-for-account-failed
|
||||||
address]}]]]}]
|
address]}]]]}]
|
||||||
|
|||||||
@@ -15,19 +15,24 @@
|
|||||||
|
|
||||||
(defn new-account
|
(defn new-account
|
||||||
[]
|
[]
|
||||||
[quo/action-drawer
|
(let [keycard? (rf/sub [:keycard/keycard-profile?])]
|
||||||
[[{:icon :i/add
|
[quo/action-drawer
|
||||||
:accessibility-label :start-a-new-chat
|
[[{:icon :i/add
|
||||||
:label (i18n/label :t/add-account)
|
:accessibility-label :start-a-new-chat
|
||||||
:sub-label (i18n/label :t/add-account-description)
|
:label (i18n/label :t/add-account)
|
||||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.create-account])}
|
:sub-label (i18n/label :t/add-account-description)
|
||||||
(when (ff/enabled? ::ff/wallet.add-watched-address)
|
:on-press (fn []
|
||||||
{:icon :i/reveal
|
(if keycard?
|
||||||
:accessibility-label :add-a-contact
|
(rf/dispatch [:keycard/feature-unavailable-show
|
||||||
:label (i18n/label :t/add-address-to-watch)
|
{:feature-name :wallet.new-account}])
|
||||||
:sub-label (i18n/label :t/add-address-to-watch-description)
|
(rf/dispatch [:navigate-to :screen/wallet.create-account])))}
|
||||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
|
(when (ff/enabled? ::ff/wallet.add-watched-address)
|
||||||
:add-divider? true})]]])
|
{:icon :i/reveal
|
||||||
|
:accessibility-label :add-a-contact
|
||||||
|
:label (i18n/label :t/add-address-to-watch)
|
||||||
|
:sub-label (i18n/label :t/add-address-to-watch-description)
|
||||||
|
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
|
||||||
|
:add-divider? true})]]]))
|
||||||
|
|
||||||
(defn- new-account-card-data
|
(defn- new-account-card-data
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -619,7 +619,7 @@
|
|||||||
|
|
||||||
(rf/reg-event-fx :wallet/clean-up-transaction-flow
|
(rf/reg-event-fx :wallet/clean-up-transaction-flow
|
||||||
(fn [_]
|
(fn [_]
|
||||||
{:fx [[:dispatch [:wallet/clean-send-data]]
|
{:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]
|
||||||
[:dispatch [:wallet/clean-scanned-address]]
|
[:dispatch [:wallet/clean-scanned-address]]
|
||||||
[:dispatch [:wallet/clean-local-suggestions]]
|
[:dispatch [:wallet/clean-local-suggestions]]
|
||||||
[:dispatch [:wallet/clean-send-address]]
|
[:dispatch [:wallet/clean-send-address]]
|
||||||
@@ -629,9 +629,11 @@
|
|||||||
(rf/reg-event-fx :wallet/end-transaction-flow
|
(rf/reg-event-fx :wallet/end-transaction-flow
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
(let [address (get-in db [:wallet :current-viewing-account-address])]
|
(let [address (get-in db [:wallet :current-viewing-account-address])]
|
||||||
{:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]
|
{:fx [[:dispatch [:wallet/navigate-to-account-within-stack address]]
|
||||||
[:dispatch [:wallet/navigate-to-account-within-stack address]]
|
[:dispatch [:wallet/select-account-tab :activity]]
|
||||||
[:dispatch [:wallet/select-account-tab :activity]]]})))
|
[:dispatch-later
|
||||||
|
[{:ms 20
|
||||||
|
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/build-transactions-from-route
|
:wallet/build-transactions-from-route
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
:wallet/wallet-send-tx-type :tx/send
|
:wallet/wallet-send-tx-type :tx/send
|
||||||
:wallet/wallet-send-fee-fiat-formatted "$5,00"
|
:wallet/wallet-send-fee-fiat-formatted "$5,00"
|
||||||
:wallet/sending-collectible? false
|
:wallet/sending-collectible? false
|
||||||
|
:wallet/selected-keypair-keycard? false
|
||||||
:wallet/send-total-amount-formatted "250 ETH"
|
:wallet/send-total-amount-formatted "250 ETH"
|
||||||
:wallet/total-amount (money/bignumber "250")
|
:wallet/total-amount (money/bignumber "250")
|
||||||
:wallet/prices-per-token {:ETH {:usd 10}}
|
:wallet/prices-per-token {:ETH {:usd 10}}
|
||||||
|
|||||||
@@ -258,8 +258,6 @@
|
|||||||
(set-input-state
|
(set-input-state
|
||||||
#(controlled-input/->crypto % conversion-rate)))
|
#(controlled-input/->crypto % conversion-rate)))
|
||||||
(set-crypto-currency (not crypto-currency?)))]
|
(set-crypto-currency (not crypto-currency?)))]
|
||||||
(rn/use-unmount
|
|
||||||
#(rf/dispatch [:wallet/clean-up-transaction-flow]))
|
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(when active-screen?
|
(when active-screen?
|
||||||
|
|||||||
@@ -248,7 +248,9 @@
|
|||||||
account))}
|
account))}
|
||||||
user-props {:full-name to-address
|
user-props {:full-name to-address
|
||||||
:address (utils/get-shortened-address
|
:address (utils/get-shortened-address
|
||||||
to-address)}]
|
to-address)}
|
||||||
|
sign-on-keycard? (get-in transaction-for-signing
|
||||||
|
[:signingDetails :signOnKeycard])]
|
||||||
;; In token send flow we already have transaction built when
|
;; In token send flow we already have transaction built when
|
||||||
;; we reach confirmation screen. But in send collectible flow
|
;; we reach confirmation screen. But in send collectible flow
|
||||||
;; routes request happens at the same time with navigation to
|
;; routes request happens at the same time with navigation to
|
||||||
@@ -279,20 +281,24 @@
|
|||||||
:transaction-type transaction-type}]
|
:transaction-type transaction-type}]
|
||||||
(when (and (not loading-suggested-routes?) route (seq route))
|
(when (and (not loading-suggested-routes?) route (seq route))
|
||||||
[standard-auth/slide-button
|
[standard-auth/slide-button
|
||||||
{:keycard-supported? true
|
{:size :size-48
|
||||||
:size :size-48
|
|
||||||
:track-text (if (= transaction-type :tx/bridge)
|
:track-text (if (= transaction-type :tx/bridge)
|
||||||
(i18n/label :t/slide-to-bridge)
|
(i18n/label :t/slide-to-bridge)
|
||||||
(i18n/label :t/slide-to-send))
|
(i18n/label :t/slide-to-send))
|
||||||
:container-style {:z-index 2}
|
:container-style {:z-index 2}
|
||||||
:disabled? (not transaction-for-signing)
|
:disabled? (not transaction-for-signing)
|
||||||
:customization-color account-color
|
:customization-color account-color
|
||||||
|
:auth-button-label (i18n/label :t/confirm)
|
||||||
|
:on-complete (when sign-on-keycard?
|
||||||
|
#(rf/dispatch
|
||||||
|
[:wallet/prepare-signatures-for-transactions
|
||||||
|
:send
|
||||||
|
""]))
|
||||||
:on-auth-success
|
:on-auth-success
|
||||||
(fn [data]
|
(fn [psw]
|
||||||
(rf/dispatch
|
(rf/dispatch
|
||||||
[:wallet/prepare-signatures-for-transactions
|
[:wallet/prepare-signatures-for-transactions :send
|
||||||
:send data]))
|
psw]))}])]
|
||||||
:auth-button-label (i18n/label :t/confirm)}])]
|
|
||||||
:gradient-cover? true
|
:gradient-cover? true
|
||||||
:customization-color (:color account)}
|
:customization-color (:color account)}
|
||||||
[rn/view
|
[rn/view
|
||||||
|
|||||||
@@ -217,18 +217,23 @@
|
|||||||
|
|
||||||
(defn- slide-button
|
(defn- slide-button
|
||||||
[]
|
[]
|
||||||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||||
account (rf/sub [:wallet/current-viewing-account])
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
on-auth-success (rn/use-callback
|
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
||||||
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap %]))]
|
sign-on-keycard? (get-in transaction-for-signing
|
||||||
|
[:signingDetails :signOnKeycard])
|
||||||
|
on-auth-success (rn/use-callback
|
||||||
|
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap %]))
|
||||||
|
on-complete (rn/use-callback
|
||||||
|
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap ""]))]
|
||||||
[standard-auth/slide-button
|
[standard-auth/slide-button
|
||||||
{:size :size-48
|
{:size :size-48
|
||||||
:track-text (i18n/label :t/slide-to-sign)
|
:track-text (i18n/label :t/slide-to-sign)
|
||||||
:container-style {:z-index 2}
|
:container-style {:z-index 2}
|
||||||
:customization-color (:color account)
|
:customization-color (:color account)
|
||||||
:disabled? (or loading-swap-proposal? (not swap-proposal))
|
:disabled? (or loading-swap-proposal? (not swap-proposal))
|
||||||
:keycard-supported? true
|
:on-complete (when sign-on-keycard? on-complete)
|
||||||
:on-auth-success on-auth-success
|
:on-auth-success on-auth-success
|
||||||
:auth-button-label (i18n/label :t/confirm)}]))
|
:auth-button-label (i18n/label :t/confirm)}]))
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,9 @@
|
|||||||
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
||||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||||
account (rf/sub [:wallet/current-viewing-account])
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
account-color (:color account)]
|
account-color (:color account)
|
||||||
|
sign-on-keycard? (get-in transaction-for-signing
|
||||||
|
[:signingDetails :signOnKeycard])]
|
||||||
[standard-auth/slide-button
|
[standard-auth/slide-button
|
||||||
{:size :size-48
|
{:size :size-48
|
||||||
:track-text (i18n/label :t/slide-to-swap)
|
:track-text (i18n/label :t/slide-to-swap)
|
||||||
@@ -178,7 +180,11 @@
|
|||||||
(not swap-proposal)
|
(not swap-proposal)
|
||||||
(not transaction-for-signing))
|
(not transaction-for-signing))
|
||||||
:auth-button-label (i18n/label :t/confirm)
|
:auth-button-label (i18n/label :t/confirm)
|
||||||
:keycard-supported? true
|
:on-complete (when sign-on-keycard?
|
||||||
|
#(rf/dispatch
|
||||||
|
[:wallet/prepare-signatures-for-transactions
|
||||||
|
:swap
|
||||||
|
""]))
|
||||||
:on-auth-success (fn [data]
|
:on-auth-success (fn [data]
|
||||||
(rf/dispatch [:wallet/stop-get-swap-proposal])
|
(rf/dispatch [:wallet/stop-get-swap-proposal])
|
||||||
(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap data]))}]))
|
(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap data]))}]))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[react-native.wallet-connect :as wallet-connect]
|
[react-native.wallet-connect :as wallet-connect]
|
||||||
|
[status-im.contexts.wallet.data-store :as wallet-data-store]
|
||||||
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
|
||||||
data-store]
|
data-store]
|
||||||
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
|
||||||
@@ -30,11 +31,19 @@
|
|||||||
expired? (-> parsed-uri
|
expired? (-> parsed-uri
|
||||||
:expiryTimestamp
|
:expiryTimestamp
|
||||||
uri/timestamp-expired?)
|
uri/timestamp-expired?)
|
||||||
version-supported? (uri/version-supported? version)]
|
version-supported? (uri/version-supported? version)
|
||||||
(if (or (not valid-wc-uri?)
|
keycard? (wallet-data-store/selected-keypair-keycard? db)]
|
||||||
(not version-supported?)
|
(cond
|
||||||
(= network-status :offline)
|
|
||||||
expired?)
|
keycard?
|
||||||
|
{:fx [[:dispatch
|
||||||
|
[:keycard/feature-unavailable-show
|
||||||
|
{:feature-name :wallet.scan-dapp-connection}]]]}
|
||||||
|
|
||||||
|
(or (not valid-wc-uri?)
|
||||||
|
(not version-supported?)
|
||||||
|
(= network-status :offline)
|
||||||
|
expired?)
|
||||||
{:fx [[:dispatch
|
{:fx [[:dispatch
|
||||||
[:toasts/upsert
|
[:toasts/upsert
|
||||||
{:type :negative
|
{:type :negative
|
||||||
@@ -54,6 +63,8 @@
|
|||||||
|
|
||||||
:else
|
:else
|
||||||
(i18n/label :t/something-went-wrong))}]]]}
|
(i18n/label :t/something-went-wrong))}]]]}
|
||||||
|
|
||||||
|
:else
|
||||||
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
|
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
status-im.contexts.contact.blocking.events
|
status-im.contexts.contact.blocking.events
|
||||||
status-im.contexts.keycard.effects
|
status-im.contexts.keycard.effects
|
||||||
status-im.contexts.keycard.events
|
status-im.contexts.keycard.events
|
||||||
|
status-im.contexts.keycard.feature-unavailable.events
|
||||||
status-im.contexts.network.effects
|
status-im.contexts.network.effects
|
||||||
status-im.contexts.network.events
|
status-im.contexts.network.events
|
||||||
status-im.contexts.onboarding.common.overlay.events
|
status-im.contexts.onboarding.common.overlay.events
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
|
|
||||||
(def ^:private initial-flags
|
(def ^:private initial-flags
|
||||||
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
||||||
|
::community.view-token-requirements (enabled-in-env? :FLAG_VIEW_TOKEN_REQUIREMENTS)
|
||||||
|
|
||||||
;; Feature toggled (off by default) because the desktop app disabled this
|
;; Feature toggled (off by default) because the desktop app disabled this
|
||||||
;; feature and we want both clients in sync. We keep the code because it
|
;; feature and we want both clients in sync. We keep the code because it
|
||||||
;; works and we may re-enable it by default.
|
;; works and we may re-enable it by default.
|
||||||
::profile-pictures-visibility (enabled-in-env? :FLAG_PROFILE_PICTURES_VISIBILITY_ENABLED)
|
::profile-pictures-visibility (enabled-in-env? :FLAG_PROFILE_PICTURES_VISIBILITY_ENABLED)
|
||||||
::settings.import-all-keypairs (enabled-in-env?
|
::settings.import-all-keypairs (enabled-in-env? :FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
|
||||||
:FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
|
|
||||||
::wallet.add-watched-address (enabled-in-env? :FLAG_ADD_WATCHED_ADDRESS)
|
::wallet.add-watched-address (enabled-in-env? :FLAG_ADD_WATCHED_ADDRESS)
|
||||||
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
|
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
|
||||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||||
|
|||||||
@@ -25,16 +25,15 @@
|
|||||||
|
|
||||||
(defn root-options
|
(defn root-options
|
||||||
[{:keys [background-color theme status-bar-theme nav-bar-color]}]
|
[{:keys [background-color theme status-bar-theme nav-bar-color]}]
|
||||||
(merge
|
(let [layout-background (or background-color
|
||||||
(statusbar-and-navbar-options theme status-bar-theme nav-bar-color)
|
(colors/theme-colors colors/white colors/neutral-100 theme))
|
||||||
{:topBar {:visible false}
|
component-background (or background-color
|
||||||
:layout {:componentBackgroundColor (or background-color
|
(colors/theme-colors colors/white colors/neutral-100 theme))]
|
||||||
(colors/theme-colors colors/white colors/neutral-100 theme))
|
(assoc (statusbar-and-navbar-options theme status-bar-theme nav-bar-color)
|
||||||
:orientation ["portrait"]
|
:topBar {:visible false}
|
||||||
:backgroundColor (or background-color
|
:layout {:componentBackgroundColor component-background
|
||||||
(colors/theme-colors colors/white
|
:orientation ["portrait"]
|
||||||
colors/neutral-100
|
:backgroundColor layout-background})))
|
||||||
theme))}}))
|
|
||||||
|
|
||||||
(defn dark-root-options
|
(defn dark-root-options
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
[status-im.common.enter-seed-phrase.view :as enter-seed-phrase]
|
[status-im.common.enter-seed-phrase.view :as enter-seed-phrase]
|
||||||
[status-im.common.lightbox.view :as lightbox]
|
[status-im.common.lightbox.view :as lightbox]
|
||||||
[status-im.common.pdf-viewer.view :as pdf-viewer]
|
[status-im.common.pdf-viewer.view :as pdf-viewer]
|
||||||
|
[status-im.common.privacy.view :as privacy-policy]
|
||||||
|
[status-im.common.terms.view :as terms-of-use]
|
||||||
[status-im.config :as config]
|
[status-im.config :as config]
|
||||||
[status-im.contexts.chat.group.create.view :as group.create]
|
[status-im.contexts.chat.group.create.view :as group.create]
|
||||||
[status-im.contexts.chat.group.details.view :as group.details]
|
[status-im.contexts.chat.group.details.view :as group.details]
|
||||||
@@ -43,7 +45,6 @@
|
|||||||
[status-im.contexts.keycard.pin.enter.view :as keycard.pin.enter]
|
[status-im.contexts.keycard.pin.enter.view :as keycard.pin.enter]
|
||||||
[status-im.contexts.onboarding.create-or-sync-profile.view :as create-or-sync-profile]
|
[status-im.contexts.onboarding.create-or-sync-profile.view :as create-or-sync-profile]
|
||||||
[status-im.contexts.onboarding.create-password.view :as create-password]
|
[status-im.contexts.onboarding.create-password.view :as create-password]
|
||||||
[status-im.contexts.onboarding.create-profile.view :as create-profile]
|
|
||||||
[status-im.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
|
[status-im.contexts.onboarding.enable-biometrics.view :as enable-biometrics]
|
||||||
[status-im.contexts.onboarding.enable-notifications.view :as enable-notifications]
|
[status-im.contexts.onboarding.enable-notifications.view :as enable-notifications]
|
||||||
[status-im.contexts.onboarding.identifiers.view :as identifiers]
|
[status-im.contexts.onboarding.identifiers.view :as identifiers]
|
||||||
@@ -74,6 +75,7 @@
|
|||||||
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
||||||
[status-im.contexts.profile.settings.screens.syncing.view :as settings.syncing]
|
[status-im.contexts.profile.settings.screens.syncing.view :as settings.syncing]
|
||||||
[status-im.contexts.profile.settings.view :as settings]
|
[status-im.contexts.profile.settings.view :as settings]
|
||||||
|
[status-im.contexts.settings.about.view :as settings.about]
|
||||||
[status-im.contexts.settings.keycard.view :as settings.keycard]
|
[status-im.contexts.settings.keycard.view :as settings.keycard]
|
||||||
[status-im.contexts.settings.language-and-currency.currency.view :as settings.currency-selection]
|
[status-im.contexts.settings.language-and-currency.currency.view :as settings.currency-selection]
|
||||||
[status-im.contexts.settings.language-and-currency.view :as settings.language-and-currency]
|
[status-im.contexts.settings.language-and-currency.view :as settings.language-and-currency]
|
||||||
@@ -154,39 +156,39 @@
|
|||||||
|
|
||||||
(def chat-screens
|
(def chat-screens
|
||||||
[{:name :start-a-new-chat
|
[{:name :start-a-new-chat
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :messenger.new-chat}
|
:alias-id :messenger.new-chat}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component new-chat/view}
|
:component new-chat/view}
|
||||||
|
|
||||||
{:name :chat
|
{:name :chat
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :messenger.chat}
|
:alias-id :messenger.chat}
|
||||||
:options {:popGesture false
|
:options {:popGesture false
|
||||||
:animations transitions/stack-transition-from-bottom}
|
:animations transitions/stack-transition-from-bottom}
|
||||||
:component chat/chat}
|
:component chat/chat}
|
||||||
|
|
||||||
{:name :screen/group-create
|
{:name :screen/group-create
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :messenger.new-group}
|
:alias-id :messenger.new-group}
|
||||||
:options {:sheet? true
|
:options {:sheet? true
|
||||||
:skip-background? true}
|
:skip-background? true}
|
||||||
:component group.create/view}
|
:component group.create/view}
|
||||||
|
|
||||||
{:name :screen/group-details
|
{:name :screen/group-details
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :messenger.group-details}
|
:alias-id :messenger.group-details}
|
||||||
:component group.details/view}
|
:component group.details/view}
|
||||||
|
|
||||||
{:name :screen/group-update
|
{:name :screen/group-update
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :messenger.group-update}
|
:alias-id :messenger.group-update}
|
||||||
:options {:sheet? true
|
:options {:sheet? true
|
||||||
:skip-background? true}
|
:skip-background? true}
|
||||||
:component group.update/view}
|
:component group.update/view}
|
||||||
|
|
||||||
{:name :screen/group-add-manage-members
|
{:name :screen/group-add-manage-members
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:flow :messenger
|
:flow :messenger
|
||||||
:alias-id :messenger.group-manage-members}
|
:alias-id :messenger.group-manage-members}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
@@ -194,12 +196,12 @@
|
|||||||
|
|
||||||
(def community-screens
|
(def community-screens
|
||||||
[{:name :discover-communities
|
[{:name :discover-communities
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.discover}
|
:alias-id :community.discover}
|
||||||
:component communities.discover/view}
|
:component communities.discover/view}
|
||||||
|
|
||||||
{:name :community-overview
|
{:name :community-overview
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.overview}
|
:alias-id :community.overview}
|
||||||
:options {:animations transitions/stack-transition-from-bottom}
|
:options {:animations transitions/stack-transition-from-bottom}
|
||||||
:component communities.overview/view}
|
:component communities.overview/view}
|
||||||
@@ -208,79 +210,79 @@
|
|||||||
;; joining a community. The non-sheet screen is used when editing shared
|
;; joining a community. The non-sheet screen is used when editing shared
|
||||||
;; addresses after the join request was sent.
|
;; addresses after the join request was sent.
|
||||||
{:name :community-account-selection-sheet
|
{:name :community-account-selection-sheet
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.select-addresses-for-joining-community}
|
:alias-id :community.select-addresses-for-joining-community}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component communities.accounts-selection/view}
|
:component communities.accounts-selection/view}
|
||||||
{:name :community-account-selection
|
{:name :community-account-selection
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.select-addresses-for-community}
|
:alias-id :community.select-addresses-for-community}
|
||||||
:options {:insets {:top? true}}
|
:options {:insets {:top? true}}
|
||||||
:component communities.accounts-selection/view}
|
:component communities.accounts-selection/view}
|
||||||
|
|
||||||
{:name :community-requests-to-join
|
{:name :community-requests-to-join
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.request-to-join}
|
:alias-id :community.request-to-join}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component join-menu/view}
|
:component join-menu/view}
|
||||||
|
|
||||||
{:name :screen/share-community
|
{:name :screen/share-community
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.share-community}
|
:alias-id :community.share-community}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component share-community/view}
|
:component share-community/view}
|
||||||
|
|
||||||
{:name :invite-people-community
|
{:name :invite-people-community
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.invite-people}
|
:alias-id :community.invite-people}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component communities.invite/view}
|
:component communities.invite/view}
|
||||||
|
|
||||||
{:name :share-community-channel
|
{:name :share-community-channel
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.share-channel}
|
:alias-id :community.share-channel}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component share-community-channel/view}
|
:component share-community-channel/view}
|
||||||
|
|
||||||
{:name :screen/chat.view-channel-members-and-details
|
{:name :screen/chat.view-channel-members-and-details
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.view-channel-members-and-details}
|
:alias-id :community.view-channel-members-and-details}
|
||||||
:options {:insets {:top? true}}
|
:options {:insets {:top? true}}
|
||||||
:component channel-view-channel-members-and-details/view}
|
:component channel-view-channel-members-and-details/view}
|
||||||
|
|
||||||
{:name :addresses-for-permissions
|
{:name :addresses-for-permissions
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.choose-addresses-for-permissions}
|
:alias-id :community.choose-addresses-for-permissions}
|
||||||
:options {:insets {:top? true}}
|
:options {:insets {:top? true}}
|
||||||
:component addresses-for-permissions/view}
|
:component addresses-for-permissions/view}
|
||||||
|
|
||||||
{:name :address-for-airdrop
|
{:name :address-for-airdrop
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :community.choose-addresses-for-airdrop}
|
:alias-id :community.choose-addresses-for-airdrop}
|
||||||
:options {:insets {:top? true}}
|
:options {:insets {:top? true}}
|
||||||
:component airdrop-addresses/view}])
|
:component airdrop-addresses/view}])
|
||||||
|
|
||||||
(def contact-screens
|
(def contact-screens
|
||||||
[{:name :new-contact
|
[{:name :new-contact
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :contact.new-contact}
|
:alias-id :contact.new-contact}
|
||||||
:options {:sheet? true}
|
:options {:sheet? true}
|
||||||
:component add-new-contact/new-contact}
|
:component add-new-contact/new-contact}
|
||||||
|
|
||||||
{:name :scan-profile-qr-code
|
{:name :scan-profile-qr-code
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :contact.scan-profile-qr-code}
|
:alias-id :contact.scan-profile-qr-code}
|
||||||
:options options/dark-screen
|
:options options/dark-screen
|
||||||
:component scan-profile-qr-page/view}
|
:component scan-profile-qr-page/view}
|
||||||
|
|
||||||
{:name :contact-profile
|
{:name :contact-profile
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :contact.contact-profile}
|
:alias-id :contact.contact-profile}
|
||||||
:options {:modalPresentationStyle :overCurrentContext}
|
:options {:modalPresentationStyle :overCurrentContext}
|
||||||
:component contact-profile/view}
|
:component contact-profile/view}
|
||||||
|
|
||||||
{:name :share-contact
|
{:name :share-contact
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :contact.share-profile}
|
:alias-id :contact.share-profile}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component share-contact/view}])
|
:component share-contact/view}])
|
||||||
@@ -312,56 +314,56 @@
|
|||||||
|
|
||||||
(def settings-screens
|
(def settings-screens
|
||||||
[{:name :settings
|
[{:name :settings
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.profile-settings}
|
:alias-id :settings.profile-settings}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component settings/view}
|
:component settings/view}
|
||||||
|
|
||||||
{:name :screen/settings.keycard
|
{:name :screen/settings.keycard
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.keycard}
|
:alias-id :settings.keycard}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component settings.keycard/view}
|
:component settings.keycard/view}
|
||||||
|
|
||||||
{:name :edit-profile
|
{:name :edit-profile
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.edit-profile}
|
:alias-id :settings.edit-profile}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component edit-profile/view}
|
:component edit-profile/view}
|
||||||
|
|
||||||
{:name :edit-accent-colour
|
{:name :edit-accent-colour
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.edit-profile-accent-colour}
|
:alias-id :settings.edit-profile-accent-colour}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component edit-accent-colour/view}
|
:component edit-accent-colour/view}
|
||||||
|
|
||||||
{:name :edit-name
|
{:name :edit-name
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.edit-profile-name}
|
:alias-id :settings.edit-profile-name}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component edit-name/view}
|
:component edit-name/view}
|
||||||
|
|
||||||
{:name :edit-bio
|
{:name :edit-bio
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.edit-profile-bio}
|
:alias-id :settings.edit-profile-bio}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component edit-bio/view}
|
:component edit-bio/view}
|
||||||
|
|
||||||
{:name :screen/settings-password
|
{:name :screen/settings-password
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.password}
|
:alias-id :settings.password}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings-password/view}
|
:component settings-password/view}
|
||||||
|
|
||||||
{:name :screen/change-password
|
{:name :screen/change-password
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.change-password}
|
:alias-id :settings.change-password}
|
||||||
:options (assoc options/transparent-modal-screen-options :theme :dark)
|
:options (assoc options/transparent-modal-screen-options :theme :dark)
|
||||||
:component change-password/view}
|
:component change-password/view}
|
||||||
|
|
||||||
{:name :screen/change-password-loading
|
{:name :screen/change-password-loading
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.change-password-loading}
|
:alias-id :settings.change-password-loading}
|
||||||
:options (assoc
|
:options (assoc
|
||||||
options/transparent-modal-screen-options
|
options/transparent-modal-screen-options
|
||||||
@@ -372,25 +374,25 @@
|
|||||||
:component change-password-loading/view}
|
:component change-password-loading/view}
|
||||||
|
|
||||||
{:name :screen/settings-messages
|
{:name :screen/settings-messages
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.messages}
|
:alias-id :settings.messages}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.messages/view}
|
:component settings.messages/view}
|
||||||
|
|
||||||
{:name :screen/settings-blocked-users
|
{:name :screen/settings-blocked-users
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.blocked-users}
|
:alias-id :settings.blocked-users}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.blocked-users/view}
|
:component settings.blocked-users/view}
|
||||||
|
|
||||||
{:name :screen/settings-privacy-and-security
|
{:name :screen/settings-privacy-and-security
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.private-and-security}
|
:alias-id :settings.private-and-security}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.privacy-and-security/view}
|
:component settings.privacy-and-security/view}
|
||||||
|
|
||||||
{:name :screen/settings.share-usage-data
|
{:name :screen/settings.share-usage-data
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.share-usage/view}
|
:component settings.share-usage/view}
|
||||||
|
|
||||||
@@ -406,89 +408,104 @@
|
|||||||
:component syncing-devices-list/view}
|
:component syncing-devices-list/view}
|
||||||
|
|
||||||
{:name :screen/settings.language-and-currency
|
{:name :screen/settings.language-and-currency
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.language-and-currency/view}
|
:component settings.language-and-currency/view}
|
||||||
|
|
||||||
{:name :screen/settings.currency-selection
|
{:name :screen/settings.currency-selection
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component settings.currency-selection/view}])
|
:component settings.currency-selection/view}
|
||||||
|
|
||||||
|
{:name :screen/settings.about
|
||||||
|
:metrics {:track? true}
|
||||||
|
:options options/transparent-modal-screen-options
|
||||||
|
:component settings.about/view}
|
||||||
|
|
||||||
|
{:name :screen/settings.privacy-policy
|
||||||
|
:metrics {:track? true}
|
||||||
|
:options options/transparent-modal-screen-options
|
||||||
|
:component privacy-policy/view}
|
||||||
|
|
||||||
|
{:name :screen/settings.terms-of-use
|
||||||
|
:metrics {:track? true}
|
||||||
|
:options options/transparent-modal-screen-options
|
||||||
|
:component terms-of-use/view}])
|
||||||
|
|
||||||
(def wallet-settings-screens
|
(def wallet-settings-screens
|
||||||
[{:name :screen/settings.wallet
|
[{:name :screen/settings.wallet
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component wallet-options/view}
|
:component wallet-options/view}
|
||||||
|
|
||||||
{:name :screen/settings.rename-keypair
|
{:name :screen/settings.rename-keypair
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-rename-keypair}
|
:alias-id :settings.wallet-rename-keypair}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component keypair-rename/view}
|
:component keypair-rename/view}
|
||||||
|
|
||||||
{:name :screen/settings.encrypted-keypair-qr
|
{:name :screen/settings.encrypted-keypair-qr
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-encrypted-keypair-qr}
|
:alias-id :settings.wallet-encrypted-keypair-qr}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component encrypted-keypair-qr/view}
|
:component encrypted-keypair-qr/view}
|
||||||
|
|
||||||
{:name :screen/settings.saved-addresses
|
{:name :screen/settings.saved-addresses
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-saved-addresses}
|
:alias-id :settings.wallet-saved-addresses}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component saved-addresses-settings/view}
|
:component saved-addresses-settings/view}
|
||||||
|
|
||||||
{:name :screen/settings.keypairs-and-accounts
|
{:name :screen/settings.keypairs-and-accounts
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-keypairs-and-accounts}
|
:alias-id :settings.wallet-keypairs-and-accounts}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component keypairs-and-accounts/view}
|
:component keypairs-and-accounts/view}
|
||||||
|
|
||||||
{:name :screen/settings.scan-keypair-qr
|
{:name :screen/settings.scan-keypair-qr
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-scan-keypair-qr}
|
:alias-id :settings.wallet-scan-keypair-qr}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component scan-keypair-qr/view}
|
:component scan-keypair-qr/view}
|
||||||
|
|
||||||
{:name :screen/settings.missing-keypair.import-seed-phrase
|
{:name :screen/settings.missing-keypair.import-seed-phrase
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-missing-keypair-import-seed-phrase}
|
:alias-id :settings.wallet-missing-keypair-import-seed-phrase}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component missing-keypairs.import-seed-phrase/view}
|
:component missing-keypairs.import-seed-phrase/view}
|
||||||
|
|
||||||
{:name :screen/settings.missing-keypair-import-private-key
|
{:name :screen/settings.missing-keypair-import-private-key
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-missing-keypair-import-private-key}
|
:alias-id :settings.wallet-missing-keypair-import-private-key}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component missing-keypairs.import-private-key/view}
|
:component missing-keypairs.import-private-key/view}
|
||||||
|
|
||||||
{:name :screen/settings.network-settings
|
{:name :screen/settings.network-settings
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-network-settings}
|
:alias-id :settings.wallet-network-settings}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component network-settings/view}
|
:component network-settings/view}
|
||||||
|
|
||||||
{:name :screen/settings.save-address
|
{:name :screen/settings.save-address
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-saved-addresses}
|
:alias-id :settings.wallet-saved-addresses}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component wallet-save-address/view}
|
:component wallet-save-address/view}
|
||||||
|
|
||||||
{:name :screen/settings.edit-saved-address
|
{:name :screen/settings.edit-saved-address
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-edit-saved-addresses}
|
:alias-id :settings.wallet-edit-saved-addresses}
|
||||||
:options (assoc options/dark-screen :sheet? true)
|
:options (assoc options/dark-screen :sheet? true)
|
||||||
:component wallet-save-address/view}
|
:component wallet-save-address/view}
|
||||||
|
|
||||||
{:name :screen/settings.add-address-to-save
|
{:name :screen/settings.add-address-to-save
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-add-saved-address}
|
:alias-id :settings.wallet-add-saved-address}
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component wallet-add-address-to-save/view}
|
:component wallet-add-address-to-save/view}
|
||||||
|
|
||||||
{:name :screen/settings.share-saved-address
|
{:name :screen/settings.share-saved-address
|
||||||
:metrics {:track? :true
|
:metrics {:track? true
|
||||||
:alias-id :settings.wallet-share-saved-address}
|
:alias-id :settings.wallet-share-saved-address}
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component share-saved-address/view}])
|
:component share-saved-address/view}])
|
||||||
@@ -728,16 +745,6 @@
|
|||||||
:modalPresentationStyle :overCurrentContext}
|
:modalPresentationStyle :overCurrentContext}
|
||||||
:component create-or-sync-profile/sync-or-recover-profile})
|
:component create-or-sync-profile/sync-or-recover-profile})
|
||||||
|
|
||||||
(def onboarding-create-profile
|
|
||||||
{:name :screen/onboarding.create-profile
|
|
||||||
:metrics {:track? true
|
|
||||||
:alias-id :onboarding.create-profile-info}
|
|
||||||
:options {:theme :dark
|
|
||||||
:layout options/onboarding-transparent-layout
|
|
||||||
:animations transitions/push-animations-for-transparent-background
|
|
||||||
:popGesture false}
|
|
||||||
:component create-profile/create-profile})
|
|
||||||
|
|
||||||
(def onboarding-create-profile-password
|
(def onboarding-create-profile-password
|
||||||
{:name :screen/onboarding.create-profile-password
|
{:name :screen/onboarding.create-profile-password
|
||||||
:metrics {:track? true
|
:metrics {:track? true
|
||||||
@@ -768,9 +775,7 @@
|
|||||||
:metrics {:track? true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:layout options/onboarding-transparent-layout
|
:layout options/onboarding-transparent-layout
|
||||||
:animations (merge
|
:animations transitions/modal-animations-vertical
|
||||||
transitions/new-to-status-modal-animations
|
|
||||||
transitions/push-animations-for-transparent-background)
|
|
||||||
:popGesture false
|
:popGesture false
|
||||||
:modalPresentationStyle :overCurrentContext}
|
:modalPresentationStyle :overCurrentContext}
|
||||||
:component onboarding.share-usage/view})
|
:component onboarding.share-usage/view})
|
||||||
@@ -872,7 +877,6 @@
|
|||||||
[onboarding-intro
|
[onboarding-intro
|
||||||
onboarding-new-to-status
|
onboarding-new-to-status
|
||||||
onboarding-sync-or-recover-profile
|
onboarding-sync-or-recover-profile
|
||||||
onboarding-create-profile
|
|
||||||
onboarding-create-profile-password
|
onboarding-create-profile-password
|
||||||
onboarding-enable-biometrics
|
onboarding-enable-biometrics
|
||||||
onboarding-preparing-status
|
onboarding-preparing-status
|
||||||
@@ -888,48 +892,48 @@
|
|||||||
|
|
||||||
(def keycard-screens
|
(def keycard-screens
|
||||||
[{:name :screen/keycard.check
|
[{:name :screen/keycard.check
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.check/view}
|
:component keycard.check/view}
|
||||||
|
|
||||||
{:name :screen/keycard.empty
|
{:name :screen/keycard.empty
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.empty/view}
|
:component keycard.empty/view}
|
||||||
|
|
||||||
{:name :screen/keycard.empty-create
|
{:name :screen/keycard.empty-create
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:insets {:top? true :bottom? true}}
|
:options {:insets {:top? true :bottom? true}}
|
||||||
:component keycard.empty/create}
|
:component keycard.empty/create}
|
||||||
|
|
||||||
{:name :screen/keycard.error
|
{:name :screen/keycard.error
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.error/view}
|
:component keycard.error/view}
|
||||||
|
|
||||||
{:name :screen/keycard.not-keycard
|
{:name :screen/keycard.not-keycard
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.not-keycard/view}
|
:component keycard.not-keycard/view}
|
||||||
|
|
||||||
{:name :screen/keycard.authorise
|
{:name :screen/keycard.authorise
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.authorise/view}
|
:component keycard.authorise/view}
|
||||||
|
|
||||||
{:name :screen/keycard.migrate
|
{:name :screen/keycard.migrate
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.migrate/view}
|
:component keycard.migrate/view}
|
||||||
|
|
||||||
{:name :screen/keycard.re-encrypting
|
{:name :screen/keycard.re-encrypting
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}
|
:insets {:top? true :bottom? true}
|
||||||
:popGesture false
|
:popGesture false
|
||||||
@@ -938,7 +942,7 @@
|
|||||||
:component keycard.re-encrypting/view}
|
:component keycard.re-encrypting/view}
|
||||||
|
|
||||||
{:name :screen/keycard.migrate.success
|
{:name :screen/keycard.migrate.success
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}
|
:insets {:top? true :bottom? true}
|
||||||
:popGesture false
|
:popGesture false
|
||||||
@@ -947,7 +951,7 @@
|
|||||||
:component keycard.migrate.success/view}
|
:component keycard.migrate.success/view}
|
||||||
|
|
||||||
{:name :screen/keycard.migrate.fail
|
{:name :screen/keycard.migrate.fail
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}
|
:insets {:top? true :bottom? true}
|
||||||
:popGesture false
|
:popGesture false
|
||||||
@@ -956,30 +960,30 @@
|
|||||||
:component keycard.migrate.fail/view}
|
:component keycard.migrate.fail/view}
|
||||||
|
|
||||||
{:name :screen/keycard.pin.create
|
{:name :screen/keycard.pin.create
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.pin.create/view}
|
:component keycard.pin.create/view}
|
||||||
|
|
||||||
{:name :screen/keycard.pin.enter
|
{:name :screen/keycard.pin.enter
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.pin.enter/view}
|
:component keycard.pin.enter/view}
|
||||||
|
|
||||||
{:name :screen/keycard.profile-keys
|
{:name :screen/keycard.profile-keys
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:theme :dark
|
:options {:theme :dark
|
||||||
:insets {:top? true :bottom? true}}
|
:insets {:top? true :bottom? true}}
|
||||||
:component keycard.migrate.profile-keys/view}
|
:component keycard.migrate.profile-keys/view}
|
||||||
|
|
||||||
{:name :screen/keycard.create-profile
|
{:name :screen/keycard.create-profile
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:insets {:top? true :bottom? true}}
|
:options {:insets {:top? true :bottom? true}}
|
||||||
:component keycard.create/view}
|
:component keycard.create/view}
|
||||||
|
|
||||||
{:name :screen/keycard.create.ready-to-add
|
{:name :screen/keycard.create.ready-to-add
|
||||||
:metrics {:track? :true}
|
:metrics {:track? true}
|
||||||
:options {:insets {:top? true :bottom? true}}
|
:options {:insets {:top? true :bottom? true}}
|
||||||
:component keycard.create/ready-to-add}])
|
:component keycard.create/ready-to-add}])
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,14 @@
|
|||||||
:to (:width (rn/get-window))
|
:to (:width (rn/get-window))
|
||||||
:duration constants/onboarding-modal-animation-duration}}})
|
:duration constants/onboarding-modal-animation-duration}}})
|
||||||
|
|
||||||
|
(def modal-animations-vertical
|
||||||
|
{:showModal {:translationY {:from (:height (rn/get-window))
|
||||||
|
:to 0
|
||||||
|
:duration constants/onboarding-modal-animation-duration}}
|
||||||
|
:dismissModal {:translationY {:from 0
|
||||||
|
:to (:height (rn/get-window))
|
||||||
|
:duration constants/onboarding-modal-animation-duration}}})
|
||||||
|
|
||||||
;;;; Stack Transitions
|
;;;; Stack Transitions
|
||||||
(def stack-slide-transition
|
(def stack-slide-transition
|
||||||
{:push {:content {:translationX {:from (:width (rn/get-window))
|
{:push {:content {:translationX {:from (:width (rn/get-window))
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
(fn [[profiles port font-file theme] [_ target-key-uid]]
|
(fn [[profiles port font-file theme] [_ target-key-uid]]
|
||||||
(let [{:keys [images ens-name? customization-color] :as profile} (get profiles target-key-uid)
|
(let [{:keys [images ens-name? customization-color] :as profile} (get profiles target-key-uid)
|
||||||
image-name (-> images first :type)
|
image-name (-> images first :type)
|
||||||
|
image-clock (-> images first :clock)
|
||||||
override-ring? (when ens-name? false)]
|
override-ring? (when ens-name? false)]
|
||||||
(when (and profile port)
|
(when (and profile port)
|
||||||
{:config
|
{:config
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
:image-name image-name
|
:image-name image-name
|
||||||
:key-uid target-key-uid
|
:key-uid target-key-uid
|
||||||
:theme theme
|
:theme theme
|
||||||
|
:clock image-clock
|
||||||
:override-ring? override-ring?}}
|
:override-ring? override-ring?}}
|
||||||
{:type :initials
|
{:type :initials
|
||||||
:options {:port port
|
:options {:port port
|
||||||
@@ -281,7 +283,10 @@
|
|||||||
customization-color]} profile
|
customization-color]} profile
|
||||||
ens-name? (or ens-name? (seq ens-names))
|
ens-name? (or ens-name? (seq ens-names))
|
||||||
avatar-opts (assoc avatar-opts :override-ring? (when ens-name? false))
|
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
|
(assoc image
|
||||||
:config
|
:config
|
||||||
{:type :account
|
{:type :account
|
||||||
@@ -289,6 +294,7 @@
|
|||||||
{:port port
|
{:port port
|
||||||
:ratio pixel-ratio/ratio
|
:ratio pixel-ratio/ratio
|
||||||
:image-name image-name
|
:image-name image-name
|
||||||
|
:clock image-clock
|
||||||
:key-uid key-uid
|
:key-uid key-uid
|
||||||
:theme theme}
|
:theme theme}
|
||||||
avatar-opts)}))
|
avatar-opts)}))
|
||||||
|
|||||||
@@ -286,6 +286,12 @@
|
|||||||
:<- [:wallet/create-account]
|
:<- [:wallet/create-account]
|
||||||
:-> :selected-keypair-uid)
|
:-> :selected-keypair-uid)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/selected-keypair-keycard?
|
||||||
|
:<- [:wallet/selected-keypair]
|
||||||
|
(fn [{:keys [keycards]}]
|
||||||
|
(boolean (seq keycards))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/selected-keypair
|
:wallet/selected-keypair
|
||||||
:<- [:wallet/keypairs]
|
:<- [:wallet/keypairs]
|
||||||
@@ -343,12 +349,13 @@
|
|||||||
:<- [:wallet/keypairs-list]
|
:<- [:wallet/keypairs-list]
|
||||||
(fn [keypairs [_ format-options]]
|
(fn [keypairs [_ format-options]]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc {:keys [accounts name type key-uid lowest-operability]}]
|
(fn [acc {:keys [accounts name type key-uid lowest-operability keycards]}]
|
||||||
(if (= lowest-operability :no)
|
(if (= lowest-operability :no)
|
||||||
(update acc
|
(update acc
|
||||||
:missing
|
:missing
|
||||||
conj
|
conj
|
||||||
{:type type
|
{:type type
|
||||||
|
:keycard? (boolean (seq keycards))
|
||||||
:name name
|
:name name
|
||||||
:key-uid key-uid
|
:key-uid key-uid
|
||||||
:accounts (format-settings-missing-keypair-accounts accounts)})
|
:accounts (format-settings-missing-keypair-accounts accounts)})
|
||||||
@@ -356,6 +363,7 @@
|
|||||||
:operable
|
:operable
|
||||||
conj
|
conj
|
||||||
{:type type
|
{:type type
|
||||||
|
:keycard? (boolean (seq keycards))
|
||||||
:name name
|
:name name
|
||||||
:key-uid key-uid
|
:key-uid key-uid
|
||||||
:accounts (format-settings-keypair-accounts accounts format-options)})))
|
:accounts (format-settings-keypair-accounts accounts format-options)})))
|
||||||
@@ -711,13 +719,11 @@
|
|||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/zero-balance-in-all-non-watched-accounts?
|
:wallet/zero-balance-in-all-non-watched-accounts?
|
||||||
:<- [:wallet/aggregated-tokens]
|
:<- [:wallet/aggregated-tokens]
|
||||||
:<- [:profile/currency]
|
(fn [aggregated-tokens]
|
||||||
:<- [:wallet/prices-per-token]
|
(let [zero-balance? (->> aggregated-tokens
|
||||||
(fn [[aggregated-tokens currency prices-per-token]]
|
(mapcat (comp vals :balances-per-chain))
|
||||||
(let [balance (utils/calculate-balance-from-tokens {:currency currency
|
(every? #(money/equal-to (:raw-balance %) 0)))]
|
||||||
:tokens aggregated-tokens
|
(and (not-empty aggregated-tokens) zero-balance?))))
|
||||||
:prices-per-token prices-per-token})]
|
|
||||||
(and (not-empty aggregated-tokens) (money/equal-to balance 0)))))
|
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/network-preference-details
|
:wallet/network-preference-details
|
||||||
|
|||||||
@@ -1008,3 +1008,150 @@
|
|||||||
(update accounts "0x2" assoc :operable :partially)))
|
(update accounts "0x2" assoc :operable :partially)))
|
||||||
(is (true? (rf/sub [sub-name])))))
|
(is (true? (rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/zero-balance-in-all-non-watched-accounts?
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns true if the balance is zero in all non-watched accounts"
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in %
|
||||||
|
[:wallet :accounts]
|
||||||
|
{"0x1" {:address "0x1"
|
||||||
|
:watch-only? false
|
||||||
|
:tokens
|
||||||
|
[{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}
|
||||||
|
{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}]}
|
||||||
|
"0x2" {:address "0x2"
|
||||||
|
:watch-only? false
|
||||||
|
:tokens
|
||||||
|
[{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}
|
||||||
|
{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}]}
|
||||||
|
|
||||||
|
"0x3"
|
||||||
|
{:address "0x3"
|
||||||
|
:watch-only? true
|
||||||
|
:tokens [{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"1")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}
|
||||||
|
{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance
|
||||||
|
(money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error
|
||||||
|
false}}}]}}))
|
||||||
|
(is (true? (rf/sub [sub-name]))))
|
||||||
|
(testing "returns false if the balance is not zero in all non-watched accounts"
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in %
|
||||||
|
[:wallet :accounts]
|
||||||
|
{"0x1" {:address "0x1"
|
||||||
|
:watch-only? false
|
||||||
|
:tokens
|
||||||
|
[{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"1")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}
|
||||||
|
{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}]}
|
||||||
|
"0x2" {:address "0x2"
|
||||||
|
:watch-only? true
|
||||||
|
:tokens
|
||||||
|
[{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"1")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}
|
||||||
|
{:balances-per-chain {constants/ethereum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}
|
||||||
|
constants/optimism-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"2")
|
||||||
|
:has-error false}
|
||||||
|
constants/arbitrum-mainnet-chain-id {:raw-balance (money/bignumber
|
||||||
|
"0")
|
||||||
|
:has-error false}}}]}}))
|
||||||
|
(is (false? (rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/selected-keypair-keycard?
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns true if the selected keypair has keycards"
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in %
|
||||||
|
[:wallet :keypairs]
|
||||||
|
{:keypair-1 {:id :keypair-1
|
||||||
|
:keycards [:keycard-1 :keycard-2]}}))
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in % [:wallet :ui :create-account :selected-keypair-uid] :keypair-1))
|
||||||
|
(is (true? (rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "returns false if the selected keypair has no keycards"
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in %
|
||||||
|
[:wallet :keypairs]
|
||||||
|
{:keypair-2 {:id :keypair-2
|
||||||
|
:keycards []}}))
|
||||||
|
(swap! rf-db/app-db
|
||||||
|
#(assoc-in % [:wallet :ui :create-account :selected-keypair-uid] :keypair-2))
|
||||||
|
(is (false? (rf/sub [sub-name])))))
|
||||||
|
|||||||
@@ -141,3 +141,14 @@
|
|||||||
(defn zero-address?
|
(defn zero-address?
|
||||||
[address]
|
[address]
|
||||||
(= address zero-address))
|
(= address zero-address))
|
||||||
|
|
||||||
|
(defn public-key->address
|
||||||
|
[public-key]
|
||||||
|
(let [length (count public-key)
|
||||||
|
normalized-key (case length
|
||||||
|
132 (str "0x" (subs public-key 4))
|
||||||
|
130 public-key
|
||||||
|
128 (str "0x" public-key)
|
||||||
|
nil)]
|
||||||
|
(when normalized-key
|
||||||
|
(subs (native-module/sha3 normalized-key) 26))))
|
||||||
|
|||||||
@@ -285,10 +285,14 @@
|
|||||||
[bn1 bn2]
|
[bn1 bn2]
|
||||||
(.round (.mul ^js bn1 bn2) 0))
|
(.round (.mul ^js bn1 bn2) 0))
|
||||||
|
|
||||||
(defn div
|
(defn- div*
|
||||||
[bn1 bn2]
|
[bn1 bn2]
|
||||||
(.dividedBy ^js bn1 bn2))
|
(.dividedBy ^js bn1 bn2))
|
||||||
|
|
||||||
|
(def div
|
||||||
|
"Divides with defaults, this version is able to receive `nil` and takes them as 0."
|
||||||
|
(fnil div* (bignumber 0) (bignumber 1)))
|
||||||
|
|
||||||
(defn div-and-round
|
(defn div-and-round
|
||||||
[bn1 bn2]
|
[bn1 bn2]
|
||||||
(.round (.dividedBy ^js bn1 bn2) 0))
|
(.round (.dividedBy ^js bn1 bn2) 0))
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v7.0.0",
|
"version": "release/7.1.x",
|
||||||
"commit-sha1": "84493728d9ac41553297e8084943c1429cdfe59a",
|
"commit-sha1": "b84be51f912fa129dbcdb05ba672846826ed1e12",
|
||||||
"src-sha256": "11dwdlk9svmc6f8wmya43fis9jfigvh5idxpiwmia9gkad1zal6y"
|
"src-sha256": "0zrfvhpqjhdbz3rmlvb8vjadibl1ym2bxkqx8153m97w0pwsljh6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,10 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user,))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
|
||||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||||
self.public_key_1 = self.home_1.get_public_key()
|
self.public_key_1 = self.home_1.get_public_key()
|
||||||
self.profile_link_2 = self.home_2.get_link_to_profile()
|
self.profile_link_2 = self.home_2.get_link_to_profile()
|
||||||
@@ -98,8 +97,8 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||||||
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
|
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
|
||||||
self.device_2.just_fyi('Creating a new user on Device2')
|
self.device_2.just_fyi('Creating a new user on Device2')
|
||||||
self.home_2.reopen_app(sign_in=False)
|
self.home_2.reopen_app(sign_in=False)
|
||||||
new_username = "new user"
|
self.device_2.create_user(first_user=False)
|
||||||
self.device_2.create_user(username=new_username, first_user=False)
|
new_username = self.home_2.get_username()
|
||||||
|
|
||||||
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
|
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
|
||||||
self.home_2.chats_tab.click()
|
self.home_2.chats_tab.click()
|
||||||
@@ -159,20 +158,19 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
|||||||
self.username_2, self.profile_link_2, decoded_username))
|
self.username_2, self.profile_link_2, decoded_username))
|
||||||
public_key_2 = self.profile_link_2.split("#")[-1]
|
public_key_2 = self.profile_link_2.split("#")[-1]
|
||||||
|
|
||||||
new_username_1 = "test user 123"
|
|
||||||
|
|
||||||
def _device_1_creates_user():
|
def _device_1_creates_user():
|
||||||
self.home_1.just_fyi("Device 1 creates a new user")
|
self.home_1.just_fyi("Device 1 creates a new user")
|
||||||
self.home_1.reopen_app(sign_in=False)
|
self.home_1.reopen_app(sign_in=False)
|
||||||
self.device_1.create_user(username=new_username_1, first_user=False)
|
self.device_1.create_user(first_user=False)
|
||||||
|
return self.home_1.get_username()
|
||||||
|
|
||||||
def _device_2_sign_in():
|
def _device_2_sign_in():
|
||||||
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
|
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
|
||||||
self.home_2.reopen_app(sign_in=False)
|
self.home_2.reopen_app(sign_in=False)
|
||||||
self.device_2.sign_in(user_name=self.username_2)
|
self.device_2.sign_in(user_name=self.username_2)
|
||||||
|
|
||||||
self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
new_username_1, _ = self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
|
||||||
(_device_2_sign_in, {}))))
|
(_device_2_sign_in, {}))))
|
||||||
|
|
||||||
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
|
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
|
||||||
self.home_1.chats_tab.click()
|
self.home_1.chats_tab.click()
|
||||||
@@ -242,11 +240,11 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
self.username_1, self.username_2 = 'user1', 'user2'
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
run_in_parallel(((self.device_1.create_user,),
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
(self.device_2.create_user,))))
|
||||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
self.home_2.navigate_back_to_home_view()
|
self.home_2.navigate_back_to_home_view()
|
||||||
@@ -382,11 +380,11 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
self.username_1, self.username_2 = 'user1', 'user2'
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.device_1.create_user, {'username': self.username_1}),
|
run_in_parallel(((self.device_1.create_user,),
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
(self.device_2.create_user,))))
|
||||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
self.home_2.navigate_back_to_home_view()
|
self.home_2.navigate_back_to_home_view()
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
|||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
|
|
||||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
self.homes = (self.home_1, self.home_2)
|
self.homes = (self.home_1, self.home_2)
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
|
|
||||||
@@ -543,13 +541,11 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
|
|||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
|
|
||||||
self.username_1, self.username_2 = 'sender', 'receiver'
|
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
self.homes = (self.home_1, self.home_2)
|
self.homes = (self.home_1, self.home_2)
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
self.profile_1, self.profile_2 = (home.get_profile_view() for home in self.homes)
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,25 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
|||||||
self.message_to_admin = 'Hey, admin!'
|
self.message_to_admin = 'Hey, admin!'
|
||||||
self.public_keys, self.usernames, self.chats = {}, {}, {}
|
self.public_keys, self.usernames, self.chats = {}, {}, {}
|
||||||
self.sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers]
|
self.sign_in_views = [SignInView(self.drivers[key]) for key in self.drivers]
|
||||||
self.usernames = ('user admin', 'member_1', 'member_2')
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(
|
run_in_parallel(
|
||||||
(
|
(
|
||||||
(self.sign_in_views[0].create_user, {'enable_notifications': True, 'username': self.usernames[0]}),
|
(self.sign_in_views[0].create_user, {'enable_notifications': True}),
|
||||||
(self.sign_in_views[1].create_user, {'enable_notifications': True, 'username': self.usernames[1]}),
|
(self.sign_in_views[1].create_user, {'enable_notifications': True}),
|
||||||
(self.sign_in_views[2].create_user, {'enable_notifications': True, 'username': self.usernames[2]})
|
(self.sign_in_views[2].create_user, {'enable_notifications': True})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.homes = [sign_in.get_home_view() for sign_in in self.sign_in_views]
|
self.homes = [sign_in.get_home_view() for sign_in in self.sign_in_views]
|
||||||
|
self.usernames = self.loop.run_until_complete(
|
||||||
|
run_in_parallel(
|
||||||
|
(
|
||||||
|
(self.homes[0].get_username,),
|
||||||
|
(self.homes[1].get_username,),
|
||||||
|
(self.homes[2].get_username,)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
self.public_keys = self.loop.run_until_complete(
|
self.public_keys = self.loop.run_until_complete(
|
||||||
run_in_parallel(
|
run_in_parallel(
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(1)
|
self.drivers, self.loop = create_shared_drivers(1)
|
||||||
self.sign_in = SignInView(self.drivers[0])
|
self.sign_in = SignInView(self.drivers[0])
|
||||||
self.username = 'first user'
|
|
||||||
|
|
||||||
self.home = self.sign_in.create_user(username=self.username)
|
self.home = self.sign_in.create_user()
|
||||||
|
self.username = self.home.get_username()
|
||||||
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||||
self.community_name = "closed community"
|
self.community_name = "closed community"
|
||||||
self.channel_name = "cats"
|
self.channel_name = "cats"
|
||||||
@@ -158,8 +158,8 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
|||||||
def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self):
|
def test_restore_multiaccount_with_waku_backup_remove_profile_switch(self):
|
||||||
self.home.reopen_app(sign_in=False)
|
self.home.reopen_app(sign_in=False)
|
||||||
self.home.just_fyi("Restore user with predefined communities and contacts")
|
self.home.just_fyi("Restore user with predefined communities and contacts")
|
||||||
recover_user_name = 'Recover user'
|
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True)
|
||||||
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True, username=recover_user_name)
|
recover_user_name = self.home.get_username()
|
||||||
|
|
||||||
self.home.just_fyi("Check contacts/blocked users")
|
self.home.just_fyi("Check contacts/blocked users")
|
||||||
self.home.chats_tab.click()
|
self.home.chats_tab.click()
|
||||||
@@ -306,11 +306,10 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
self.username_1, self.username_2 = "user_1", "user_2"
|
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user,))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'username': self.username_2}))))
|
|
||||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
self.profile_1 = self.home_1.get_profile_view()
|
self.profile_1 = self.home_1.get_profile_view()
|
||||||
[home.navigate_back_to_home_view() for home in self.homes]
|
[home.navigate_back_to_home_view() for home in self.homes]
|
||||||
@@ -836,12 +835,10 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
|
|||||||
def prepare_devices(self):
|
def prepare_devices(self):
|
||||||
self.drivers, self.loop = create_shared_drivers(2)
|
self.drivers, self.loop = create_shared_drivers(2)
|
||||||
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
self.device_1, self.device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||||
self.username_1, self.username_2 = "user_1", "user_2"
|
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True}),
|
||||||
self.loop.run_until_complete(run_in_parallel(((self.device_1.create_user, {'enable_notifications': True,
|
(self.device_2.create_user, {'enable_notifications': True}))))
|
||||||
'username': self.username_1}),
|
|
||||||
(self.device_2.create_user, {'enable_notifications': True,
|
|
||||||
'username': self.username_2}))))
|
|
||||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||||
|
self.username_1, self.username_2 = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.public_key_2 = self.home_2.get_public_key()
|
self.public_key_2 = self.home_2.get_public_key()
|
||||||
self.profile_1 = self.home_1.get_profile_view()
|
self.profile_1 = self.home_1.get_profile_view()
|
||||||
[home.navigate_back_to_home_view() for home in self.homes]
|
[home.navigate_back_to_home_view() for home in self.homes]
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
|
|||||||
self.drivers, self.loop = create_shared_drivers(1)
|
self.drivers, self.loop = create_shared_drivers(1)
|
||||||
self.driver = self.drivers[0]
|
self.driver = self.drivers[0]
|
||||||
self.sign_in = SignInView(self.driver)
|
self.sign_in = SignInView(self.driver)
|
||||||
self.username = 'test user'
|
|
||||||
|
|
||||||
self.home = self.sign_in.create_user(username=self.username)
|
self.home = self.sign_in.create_user()
|
||||||
|
self.username = self.home.get_username()
|
||||||
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
self.home.communities_tab.click_until_presence_of_element(self.home.plus_community_button)
|
||||||
self.open_community_name = "open community"
|
self.open_community_name = "open community"
|
||||||
self.channel_name = "general"
|
self.channel_name = "general"
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
|
|||||||
self.sign_in_3.get_home_view()
|
self.sign_in_3.get_home_view()
|
||||||
self.sign_in_1.just_fyi("Device 1: create a new user")
|
self.sign_in_1.just_fyi("Device 1: create a new user")
|
||||||
self.sign_in_3.just_fyi("Device 3: create a new user")
|
self.sign_in_3.just_fyi("Device 3: create a new user")
|
||||||
self.user_name_1, self.user_name_3 = 'first user', 'third user'
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.sign_in_1.create_user, {'username': self.user_name_1}),
|
run_in_parallel(((self.sign_in_1.create_user,),
|
||||||
(self.sign_in_3.create_user, {'username': self.user_name_3}))))
|
(self.sign_in_3.create_user,))))
|
||||||
|
self.user_name_1, self.user_name_3 = self.home_1.get_username(), self.home_3.get_username()
|
||||||
self.profile_1 = self.home_1.profile_button.click()
|
self.profile_1 = self.home_1.profile_button.click()
|
||||||
self.profile_2 = self.home_2.get_profile_view()
|
self.profile_2 = self.home_2.get_profile_view()
|
||||||
self.sign_in_3.just_fyi("Device 3: get public key")
|
self.sign_in_3.just_fyi("Device 3: get public key")
|
||||||
|
|||||||
@@ -24,13 +24,11 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
|
|||||||
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||||
self.sender_username, self.receiver_username = 'sender', 'receiver'
|
|
||||||
self.loop.run_until_complete(
|
self.loop.run_until_complete(
|
||||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase'],
|
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase']}),
|
||||||
'username': self.sender_username}),
|
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase']}))))
|
||||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase'],
|
|
||||||
'username': self.receiver_username}))))
|
|
||||||
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
||||||
|
self.sender_username, self.receiver_username = self.home_1.get_username(), self.home_2.get_username()
|
||||||
self.wallet_1, self.wallet_2 = self.sign_in_1.get_wallet_view(), self.sign_in_2.get_wallet_view()
|
self.wallet_1, self.wallet_2 = self.sign_in_1.get_wallet_view(), self.sign_in_2.get_wallet_view()
|
||||||
self.wallet_1.wallet_tab.click()
|
self.wallet_1.wallet_tab.click()
|
||||||
self.wallet_2.wallet_tab.click()
|
self.wallet_2.wallet_tab.click()
|
||||||
@@ -206,10 +204,10 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
|
|||||||
self.arb_balance = {'Ether': 0.0001, 'USDCoin': 0.0, 'Status': 0.0, 'Uniswap': 0.5, 'Dai Stablecoin': 0.0}
|
self.arb_balance = {'Ether': 0.0001, 'USDCoin': 0.0, 'Status': 0.0, 'Uniswap': 0.5, 'Dai Stablecoin': 0.0}
|
||||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||||
self.sender_username, self.receiver_username = 'sender', 'receiver'
|
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'])
|
||||||
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'], username=self.sender_username)
|
|
||||||
|
|
||||||
self.home_view = self.sign_in_view.get_home_view()
|
self.home_view = self.sign_in_view.get_home_view()
|
||||||
|
self.sender_username = self.home_view.get_username()
|
||||||
self.wallet_view = self.home_view.wallet_tab.click()
|
self.wallet_view = self.home_view.wallet_tab.click()
|
||||||
|
|
||||||
@marks.testrail_id(740490)
|
@marks.testrail_id(740490)
|
||||||
|
|||||||
@@ -624,3 +624,11 @@ class HomeView(BaseView):
|
|||||||
element = Text(self.driver, accessibility_id='new-device-installation-id')
|
element = Text(self.driver, accessibility_id='new-device-installation-id')
|
||||||
element.wait_for_visibility_of_element()
|
element.wait_for_visibility_of_element()
|
||||||
return element.text
|
return element.text
|
||||||
|
|
||||||
|
def get_username(self):
|
||||||
|
profile_view = self.get_profile_view()
|
||||||
|
profile_view = 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()
|
||||||
|
return username
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ class ProfileView(BaseView):
|
|||||||
|
|
||||||
# Header
|
# Header
|
||||||
self.public_key_text = Text(self.driver, accessibility_id="chat-key")
|
self.public_key_text = Text(self.driver, accessibility_id="chat-key")
|
||||||
self.default_username_text = Text(self.driver, accessibility_id="default-username")
|
self.default_username_text = Text(self.driver, accessibility_id="username")
|
||||||
self.contact_name_text = Text(self.driver, accessibility_id="contact-name")
|
self.contact_name_text = Text(self.driver, accessibility_id="contact-name")
|
||||||
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
|
self.share_my_profile_button = Button(self.driver, accessibility_id="share-header-button")
|
||||||
self.profile_picture = ProfilePictureElement(self.driver)
|
self.profile_picture = ProfilePictureElement(self.driver)
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class SignInView(BaseView):
|
|||||||
self.profile_continue_button = Button(self.driver, accessibility_id="submit-create-profile-button")
|
self.profile_continue_button = Button(self.driver, accessibility_id="submit-create-profile-button")
|
||||||
self.profile_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-1")
|
self.profile_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-1")
|
||||||
self.profile_repeat_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-2")
|
self.profile_repeat_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-2")
|
||||||
self.profile_confirm_password_button = Button(self.driver, translation_id="password-creation-confirm")
|
self.profile_confirm_password_button = Button(self.driver, accessibility_id="Confirm password")
|
||||||
self.enable_biometric_maybe_later_button = Button(self.driver, translation_id="maybe-later")
|
self.enable_biometric_maybe_later_button = Button(self.driver, translation_id="maybe-later")
|
||||||
self.identifiers_button = Button(self.driver, accessibility_id="skip-identifiers")
|
self.identifiers_button = Button(self.driver, accessibility_id="skip-identifiers")
|
||||||
self.start_button = Button(self.driver, accessibility_id="welcome-button")
|
self.start_button = Button(self.driver, accessibility_id="welcome-button")
|
||||||
@@ -228,8 +228,6 @@ class SignInView(BaseView):
|
|||||||
input_elements[0].send_keys(password)
|
input_elements[0].send_keys(password)
|
||||||
input_elements[1].click()
|
input_elements[1].click()
|
||||||
input_elements[1].send_keys(password)
|
input_elements[1].send_keys(password)
|
||||||
self.checkbox_button.scroll_to_element()
|
|
||||||
self.checkbox_button.click()
|
|
||||||
self.profile_confirm_password_button.click()
|
self.profile_confirm_password_button.click()
|
||||||
|
|
||||||
def set_profile(self, username: str, set_image=False):
|
def set_profile(self, username: str, set_image=False):
|
||||||
@@ -238,7 +236,7 @@ class SignInView(BaseView):
|
|||||||
if set_image:
|
if set_image:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_user(self, password=common_password, username="test user", first_user=True, enable_notifications=False):
|
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)
|
self.driver.info("## Creating new multiaccount with password:'%s'" % password, device=False)
|
||||||
if first_user:
|
if first_user:
|
||||||
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
|
self.create_profile_button.click_until_presence_of_element(self.start_fresh_lets_go_button)
|
||||||
@@ -249,7 +247,6 @@ class SignInView(BaseView):
|
|||||||
self.plus_profiles_button.click()
|
self.plus_profiles_button.click()
|
||||||
self.create_new_profile_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_until_presence_of_element(self.profile_title_input)
|
||||||
self.set_profile(username)
|
|
||||||
self.set_password(password)
|
self.set_password(password)
|
||||||
self.chats_tab.wait_for_visibility_of_element(30)
|
self.chats_tab.wait_for_visibility_of_element(30)
|
||||||
self.driver.info("## New multiaccount is created successfully!", device=False)
|
self.driver.info("## New multiaccount is created successfully!", device=False)
|
||||||
@@ -261,7 +258,7 @@ class SignInView(BaseView):
|
|||||||
return home_view
|
return home_view
|
||||||
|
|
||||||
def recover_access(self, passphrase: str, password: str = common_password, enable_notifications=False,
|
def recover_access(self, passphrase: str, password: str = common_password, enable_notifications=False,
|
||||||
second_user=False, username='Restore user', set_image=False, after_sync_code=False):
|
second_user=False, after_sync_code=False):
|
||||||
self.driver.info("## Recover access (password:%s)" % password, device=False)
|
self.driver.info("## Recover access (password:%s)" % password, device=False)
|
||||||
|
|
||||||
if not after_sync_code:
|
if not after_sync_code:
|
||||||
@@ -274,8 +271,6 @@ class SignInView(BaseView):
|
|||||||
self.use_recovery_phrase_button.click()
|
self.use_recovery_phrase_button.click()
|
||||||
self.passphrase_edit_box.send_keys(passphrase)
|
self.passphrase_edit_box.send_keys(passphrase)
|
||||||
self.continue_button.click_until_presence_of_element(self.profile_title_input)
|
self.continue_button.click_until_presence_of_element(self.profile_title_input)
|
||||||
if not after_sync_code:
|
|
||||||
self.set_profile(username, set_image)
|
|
||||||
self.set_password(password)
|
self.set_password(password)
|
||||||
self.chats_tab.wait_for_visibility_of_element(30)
|
self.chats_tab.wait_for_visibility_of_element(30)
|
||||||
self.driver.info("## Multiaccount is recovered successfully!", device=False)
|
self.driver.info("## Multiaccount is recovered successfully!", device=False)
|
||||||
|
|||||||
@@ -800,6 +800,7 @@
|
|||||||
"do-not-quit": "Do not quit the application or turn off your device. Doing so will lead to data corruption, loss of your Status profile and the inability to use Status.",
|
"do-not-quit": "Do not quit the application or turn off your device. Doing so will lead to data corruption, loss of your Status profile and the inability to use Status.",
|
||||||
|
|
||||||
"do-not-share": "Do not share",
|
"do-not-share": "Do not share",
|
||||||
|
"documents": "Documents",
|
||||||
"done": "Done",
|
"done": "Done",
|
||||||
"dont-ask": "Don't ask me again",
|
"dont-ask": "Don't ask me again",
|
||||||
"dont-auto-recalculate-network": "Don't auto recalculate {{network}}",
|
"dont-auto-recalculate-network": "Don't auto recalculate {{network}}",
|
||||||
@@ -1036,6 +1037,9 @@
|
|||||||
"favourite-description": "Your favourite websites will appear here",
|
"favourite-description": "Your favourite websites will appear here",
|
||||||
"favourites": "Favourites",
|
"favourites": "Favourites",
|
||||||
"favourites-empty": "Addresses added to favourites will appear here",
|
"favourites-empty": "Addresses added to favourites will appear here",
|
||||||
|
"feature-unavailable": "Feature unavailable",
|
||||||
|
"feature-unavailable-for-keycard-description": "It’s not currently supported for Keycard users.",
|
||||||
|
"feature-unavailable-info": "If you'd like this feature on mobile, feel free to ",
|
||||||
"featured": "Featured",
|
"featured": "Featured",
|
||||||
"feb": "Feb",
|
"feb": "Feb",
|
||||||
"fee-cap": "Fee cap",
|
"fee-cap": "Fee cap",
|
||||||
@@ -1112,6 +1116,7 @@
|
|||||||
"getting-started-generate-keys-on-keycard-description": "A Keycard is a physical card (similar to a credit card) that securely stores your Status keys. Using a Keycard adds an extra layer of security to your digital assets and identity. This option creates a new Ethereum address.",
|
"getting-started-generate-keys-on-keycard-description": "A Keycard is a physical card (similar to a credit card) that securely stores your Status keys. Using a Keycard adds an extra layer of security to your digital assets and identity. This option creates a new Ethereum address.",
|
||||||
"getting-started-with-status": "Getting started with Status",
|
"getting-started-with-status": "Getting started with Status",
|
||||||
"gif": "GIF",
|
"gif": "GIF",
|
||||||
|
"github-repos": "GitHub repos",
|
||||||
"give-a-short-description": "Give a short description",
|
"give-a-short-description": "Give a short description",
|
||||||
"give-a-short-description-community": "Give it a short description",
|
"give-a-short-description-community": "Give it a short description",
|
||||||
"give-permissions-camera": "Give permission\nto access camera",
|
"give-permissions-camera": "Give permission\nto access camera",
|
||||||
@@ -1929,7 +1934,7 @@
|
|||||||
"password-creation-max-length-hint": "Maximum 100 characters",
|
"password-creation-max-length-hint": "Maximum 100 characters",
|
||||||
"password-creation-placeholder-1": "Type password",
|
"password-creation-placeholder-1": "Type password",
|
||||||
"password-creation-placeholder-2": "Repeat password",
|
"password-creation-placeholder-2": "Repeat password",
|
||||||
"password-creation-subtitle": "To log in to Status and sign transactions",
|
"password-creation-subtitle": "This password can't be recovered",
|
||||||
"password-creation-tips-1": "Lower case",
|
"password-creation-tips-1": "Lower case",
|
||||||
"password-creation-tips-2": "Upper case",
|
"password-creation-tips-2": "Upper case",
|
||||||
"password-creation-tips-3": "Numbers",
|
"password-creation-tips-3": "Numbers",
|
||||||
@@ -2718,6 +2723,7 @@
|
|||||||
"update-to-see-sticker": "Update to latest version to see a nice sticker here!",
|
"update-to-see-sticker": "Update to latest version to see a nice sticker here!",
|
||||||
"updates-to-tos": "Updates to Terms of Use",
|
"updates-to-tos": "Updates to Terms of Use",
|
||||||
"updates-to-tos-desc": "Before you continue, please review the Terms of Use and confirm you take full responsibility for how you use the app.",
|
"updates-to-tos-desc": "Before you continue, please review the Terms of Use and confirm you take full responsibility for how you use the app.",
|
||||||
|
"upvote-it": "upvote it",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"usage-data-shared-from-all-profiles": "Usage data will be shared from all profiles added to device. ",
|
"usage-data-shared-from-all-profiles": "Usage data will be shared from all profiles added to device. ",
|
||||||
"usd-currency": "USD",
|
"usd-currency": "USD",
|
||||||
@@ -2867,6 +2873,7 @@
|
|||||||
"we-will-receive-from-all-profiles": "We will receive from all profiles:",
|
"we-will-receive-from-all-profiles": "We will receive from all profiles:",
|
||||||
"we-will-receive-from-the-current-profile": "We will receive from the current profile:",
|
"we-will-receive-from-the-current-profile": "We will receive from the current profile:",
|
||||||
"web-view-error": "Unable to load page",
|
"web-view-error": "Unable to load page",
|
||||||
|
"website": "Website",
|
||||||
"websites": "Websites",
|
"websites": "Websites",
|
||||||
"webview-camera-permission-requests": "Webview camera permission requests",
|
"webview-camera-permission-requests": "Webview camera permission requests",
|
||||||
"webview-camera-permission-requests-subtitle": "When enabled, websites and dapps can ask to use your camera",
|
"webview-camera-permission-requests-subtitle": "When enabled, websites and dapps can ask to use your camera",
|
||||||
|
|||||||