Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43ad3ccb95 |
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
@@ -1,7 +1,7 @@
|
|||||||
(ns status-im.add-new.db
|
(ns status-im.add-new.db
|
||||||
(:require [cljs.spec.alpha :as spec]
|
(:require [cljs.spec.alpha :as spec]
|
||||||
[status-im.ethereum.ens :as ens]
|
[status-im.ethereum.ens :as ens]
|
||||||
[status-im.utils.db :as utils.db]))
|
[status-im2.utils.validators :as validators]))
|
||||||
|
|
||||||
(defn own-public-key?
|
(defn own-public-key?
|
||||||
[{:keys [multiaccount]} public-key]
|
[{:keys [multiaccount]} public-key]
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
(defn validate-pub-key
|
(defn validate-pub-key
|
||||||
[db public-key]
|
[db public-key]
|
||||||
(cond
|
(cond
|
||||||
(or (not (utils.db/valid-public-key? public-key))
|
(or (not (validators/valid-public-key? public-key))
|
||||||
(= public-key ens/default-key))
|
(= public-key ens/default-key))
|
||||||
:invalid
|
:invalid
|
||||||
(own-public-key? db public-key)
|
(own-public-key? db public-key)
|
||||||
@@ -27,4 +27,4 @@
|
|||||||
[topic]
|
[topic]
|
||||||
(and topic
|
(and topic
|
||||||
(spec/valid? ::topic topic)
|
(spec/valid? ::topic topic)
|
||||||
(not (utils.db/valid-public-key? topic))))
|
(not (validators/valid-public-key? topic))))
|
||||||
|
|||||||
@@ -35,15 +35,16 @@
|
|||||||
:on-error #(cb "0x")}))
|
:on-error #(cb "0x")}))
|
||||||
|
|
||||||
(defn pubkey
|
(defn pubkey
|
||||||
[chain-id ens-name cb]
|
([chain-id ens-name on-success on-error]
|
||||||
{:pre [(is-valid-eth-name? ens-name)]}
|
{:pre [(is-valid-eth-name? ens-name)]}
|
||||||
(json-rpc/call {:method "ens_publicKeyOf"
|
(json-rpc/call {:method "ens_publicKeyOf"
|
||||||
:params [chain-id ens-name]
|
:params [chain-id ens-name]
|
||||||
:on-success cb
|
:on-success on-success
|
||||||
;;at some point infura started to return execution reverted error instead of "0x"
|
:on-error on-error}))
|
||||||
;;result
|
;; At some point, infura started to return "execution reverted" error
|
||||||
;;our code expects "0x" result
|
;; instead of "0x" result. Our code expects "0x" result.
|
||||||
:on-error #(cb "0x")}))
|
([chain-id ens-name cb]
|
||||||
|
(pubkey chain-id ens-name cb #(cb "0x"))))
|
||||||
|
|
||||||
(defn owner
|
(defn owner
|
||||||
[chain-id ens-name cb]
|
[chain-id ens-name cb]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require
|
(:require
|
||||||
clojure.set
|
clojure.set
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
status-im.add-new.core
|
|
||||||
[status-im.async-storage.core :as async-storage]
|
[status-im.async-storage.core :as async-storage]
|
||||||
status-im.backup.core
|
status-im.backup.core
|
||||||
status-im.bootnodes.core
|
status-im.bootnodes.core
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(ns status-im.native-module.core
|
(ns status-im.native-module.core
|
||||||
(:require ["react-native" :as react-native]
|
(:require ["react-native" :as react-native]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.utils.db :as utils.db]
|
[status-im2.utils.validators :as validators]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.utils.react-native :as react-native-utils]
|
[status-im.utils.react-native :as react-native-utils]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
@@ -471,14 +471,14 @@
|
|||||||
(defn generate-gfycat
|
(defn generate-gfycat
|
||||||
"Generate a 3 words random name based on the user public-key, synchronously"
|
"Generate a 3 words random name based on the user public-key, synchronously"
|
||||||
[public-key]
|
[public-key]
|
||||||
{:pre [(utils.db/valid-public-key? public-key)]}
|
{:pre [(validators/valid-public-key? public-key)]}
|
||||||
(log/debug "[native-module] generate-gfycat")
|
(log/debug "[native-module] generate-gfycat")
|
||||||
(.generateAlias ^js (status) public-key))
|
(.generateAlias ^js (status) public-key))
|
||||||
|
|
||||||
(defn generate-gfycat-async
|
(defn generate-gfycat-async
|
||||||
"Generate a 3 words random name based on the user public-key, asynchronously"
|
"Generate a 3 words random name based on the user public-key, asynchronously"
|
||||||
[public-key callback]
|
[public-key callback]
|
||||||
{:pre [(utils.db/valid-public-key? public-key)]}
|
{:pre [(validators/valid-public-key? public-key)]}
|
||||||
(.generateAliasAsync ^js (status) public-key callback))
|
(.generateAliasAsync ^js (status) public-key callback))
|
||||||
|
|
||||||
(defn identicon
|
(defn identicon
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
{:empty-chats-header (js/require "../resources/images/ui/empty-chats-header.png")
|
{:empty-chats-header (js/require "../resources/images/ui/empty-chats-header.png")
|
||||||
:welcome (js/require "../resources/images/ui/welcome.jpg")
|
:welcome (js/require "../resources/images/ui/welcome.jpg")
|
||||||
:welcome-dark (js/require "../resources/images/ui/welcome-dark.jpg")
|
:welcome-dark (js/require "../resources/images/ui/welcome-dark.jpg")
|
||||||
|
:add-new-contact (js/require "../resources/images/ui/add-contact.png")
|
||||||
:chat (js/require "../resources/images/ui/chat.jpg")
|
:chat (js/require "../resources/images/ui/chat.jpg")
|
||||||
:chat-dark (js/require "../resources/images/ui/chat-dark.jpg")
|
:chat-dark (js/require "../resources/images/ui/chat-dark.jpg")
|
||||||
:wallet (js/require "../resources/images/ui/wallet.jpg")
|
:wallet (js/require "../resources/images/ui/wallet.jpg")
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
[status-im.ethereum.eip681 :as eip681]
|
[status-im.ethereum.eip681 :as eip681]
|
||||||
[status-im.ethereum.ens :as ens]
|
[status-im.ethereum.ens :as ens]
|
||||||
[status-im.ethereum.stateofus :as stateofus]
|
[status-im.ethereum.stateofus :as stateofus]
|
||||||
[status-im.utils.db :as utils.db]
|
[status-im2.utils.validators :as validators]
|
||||||
[status-im.utils.http :as http]
|
[status-im.utils.http :as http]
|
||||||
[status-im.utils.wallet-connect :as wallet-connect]
|
[status-im.utils.wallet-connect :as wallet-connect]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
(defn match-contact-async
|
(defn match-contact-async
|
||||||
[chain {:keys [user-id ens-name]} callback]
|
[chain {:keys [user-id ens-name]} callback]
|
||||||
(let [valid-key (and (utils.db/valid-public-key? user-id)
|
(let [valid-key (and (validators/valid-public-key? user-id)
|
||||||
(not= user-id ens/default-key))]
|
(not= user-id ens/default-key))]
|
||||||
(cond
|
(cond
|
||||||
valid-key
|
valid-key
|
||||||
@@ -113,8 +113,8 @@
|
|||||||
(not (string/blank? chat-name))
|
(not (string/blank? chat-name))
|
||||||
(> (count chat-id-parts) 1)
|
(> (count chat-id-parts) 1)
|
||||||
(not (string/blank? (first chat-id-parts)))
|
(not (string/blank? (first chat-id-parts)))
|
||||||
(utils.db/valid-public-key? admin-pk)
|
(validators/valid-public-key? admin-pk)
|
||||||
(utils.db/valid-public-key? (last chat-id-parts)))
|
(validators/valid-public-key? (last chat-id-parts)))
|
||||||
{:type :group-chat
|
{:type :group-chat
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:invitation-admin admin-pk
|
:invitation-admin admin-pk
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
(= handler :group-chat)
|
(= handler :group-chat)
|
||||||
(cb (match-group-chat chats query-params))
|
(cb (match-group-chat chats query-params))
|
||||||
|
|
||||||
(utils.db/valid-public-key? uri)
|
(validators/valid-public-key? uri)
|
||||||
(match-contact-async chain {:user-id uri} cb)
|
(match-contact-async chain {:user-id uri} cb)
|
||||||
|
|
||||||
(= handler :community-requests)
|
(= handler :community-requests)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.utils.db :as utils.db]
|
[status-im2.utils.validators :as validators]
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
[status-im.utils.identicon :as identicon]
|
[status-im.utils.identicon :as identicon]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
#(do
|
#(do
|
||||||
(reset! search-value %)
|
(reset! search-value %)
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :empty])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :empty])
|
||||||
(debounce/debounce-and-dispatch [:new-chat/set-new-identity %] 600))
|
(debounce/debounce-and-dispatch [:contacts/set-new-identity %] 600))
|
||||||
:on-submit-editing
|
:on-submit-editing
|
||||||
#(when (= state :valid)
|
#(when (= state :valid)
|
||||||
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false nil] 3000))
|
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false nil] 3000))
|
||||||
@@ -301,7 +301,7 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [state ens-name public-key error]} @(re-frame/subscribe [:contacts/new-identity])
|
(let [{:keys [state ens-name public-key error]} @(re-frame/subscribe [:contacts/new-identity])
|
||||||
blocked? (and
|
blocked? (and
|
||||||
(utils.db/valid-public-key? (or public-key ""))
|
(validators/valid-public-key? (or public-key ""))
|
||||||
@(re-frame/subscribe [:contacts/contact-blocked?
|
@(re-frame/subscribe [:contacts/contact-blocked?
|
||||||
public-key]))]
|
public-key]))]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
{:on-change-text
|
{:on-change-text
|
||||||
#(do
|
#(do
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
(debounce/debounce-and-dispatch [:new-chat/set-new-identity %] 600))
|
(debounce/debounce-and-dispatch [:contacts/set-new-identity %] 600))
|
||||||
:on-submit-editing
|
:on-submit-editing
|
||||||
#(when (= state :valid)
|
#(when (= state :valid)
|
||||||
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted true @entered-nickname]
|
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted true @entered-nickname]
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
[quo2.foundations.colors :as quo2.colors]
|
[quo2.foundations.colors :as quo2.colors]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.add-new.core :as new-chat]
|
|
||||||
[status-im.add-new.db :as db]
|
[status-im.add-new.db :as db]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.qr-scanner.core :as qr-scanner]
|
[status-im.qr-scanner.core :as qr-scanner]
|
||||||
@@ -82,15 +81,15 @@
|
|||||||
:on-blur (fn []
|
:on-blur (fn []
|
||||||
(when chats-empty
|
(when chats-empty
|
||||||
(re-frame/dispatch [:search/home-filter-changed nil]))
|
(re-frame/dispatch [:search/home-filter-changed nil]))
|
||||||
(re-frame/dispatch [::new-chat/clear-new-identity]))
|
(re-frame/dispatch [:contacts/clear-new-identity]))
|
||||||
:on-focus (fn [search-filter]
|
:on-focus (fn [search-filter]
|
||||||
(when-not search-filter
|
(when-not search-filter
|
||||||
(re-frame/dispatch [:search/home-filter-changed ""])
|
(re-frame/dispatch [:search/home-filter-changed ""])
|
||||||
(re-frame/dispatch [::new-chat/clear-new-identity])))
|
(re-frame/dispatch [:contacts/clear-new-identity])))
|
||||||
:on-change (fn [text]
|
:on-change (fn [text]
|
||||||
(re-frame/dispatch [:search/home-filter-changed text])
|
(re-frame/dispatch [:search/home-filter-changed text])
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]])
|
(debounce/debounce-and-dispatch [:contacts/set-new-identity text] 300))}]])
|
||||||
|
|
||||||
(defn search-input-wrapper-old
|
(defn search-input-wrapper-old
|
||||||
[search-filter chats-empty]
|
[search-filter chats-empty]
|
||||||
@@ -104,11 +103,11 @@
|
|||||||
:on-blur (fn []
|
:on-blur (fn []
|
||||||
(when chats-empty
|
(when chats-empty
|
||||||
(re-frame/dispatch [:search/home-filter-changed nil]))
|
(re-frame/dispatch [:search/home-filter-changed nil]))
|
||||||
(re-frame/dispatch [::new-chat/clear-new-identity]))
|
(re-frame/dispatch [:contacts/clear-new-identity]))
|
||||||
:on-focus (fn [search-filter]
|
:on-focus (fn [search-filter]
|
||||||
(when-not search-filter
|
(when-not search-filter
|
||||||
(re-frame/dispatch [:search/home-filter-changed ""])
|
(re-frame/dispatch [:search/home-filter-changed ""])
|
||||||
(re-frame/dispatch [::new-chat/clear-new-identity])))
|
(re-frame/dispatch [:contacts/clear-new-identity])))
|
||||||
:on-change (fn [text]
|
:on-change (fn [text]
|
||||||
(re-frame/dispatch [:search/home-filter-changed text])
|
(re-frame/dispatch [:search/home-filter-changed text])
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
(ns status-im.ui.screens.screens
|
(ns status-im.ui.screens.screens
|
||||||
(:require
|
(:require
|
||||||
[quo.design-system.colors :as colors]
|
[quo.design-system.colors :as colors]
|
||||||
[status-im.add-new.core :as new-chat.events]
|
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[status-im.ui.components.icons.icons :as icons]
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
[status-im.ui.screens.about-app.views :as about-app]
|
[status-im.ui.screens.about-app.views :as about-app]
|
||||||
@@ -545,7 +544,7 @@
|
|||||||
|
|
||||||
;[Chat] New Chat
|
;[Chat] New Chat
|
||||||
{:name :new-chat
|
{:name :new-chat
|
||||||
:on-focus [::new-chat.events/new-chat-focus]
|
:on-focus [:contacts/new-chat-focus]
|
||||||
;;TODO accessories
|
;;TODO accessories
|
||||||
:options {:topBar {:visible false}}
|
:options {:topBar {:visible false}}
|
||||||
:component new-chat/new-chat}
|
:component new-chat/new-chat}
|
||||||
@@ -569,7 +568,7 @@
|
|||||||
:component contact/nickname}
|
:component contact/nickname}
|
||||||
|
|
||||||
{:name :new-chat-aio
|
{:name :new-chat-aio
|
||||||
:on-focus [::new-chat.events/new-chat-focus]
|
:on-focus [:contacts/new-chat-focus]
|
||||||
;;TODO accessories
|
;;TODO accessories
|
||||||
:options {:topBar {:visible false}}
|
:options {:topBar {:visible false}}
|
||||||
:component new-chat-aio/contact-selection-list}
|
:component new-chat-aio/contact-selection-list}
|
||||||
@@ -595,13 +594,6 @@
|
|||||||
:component communities.invite/invite
|
:component communities.invite/invite
|
||||||
:insets {:bottom true}}
|
:insets {:bottom true}}
|
||||||
|
|
||||||
;New Contact
|
|
||||||
{:name :new-contact
|
|
||||||
:on-focus [::new-chat.events/new-chat-focus]
|
|
||||||
;;TODO accessories
|
|
||||||
:options {:topBar {:visible false}}
|
|
||||||
:component new-chat/new-contact}
|
|
||||||
|
|
||||||
;[Wallet] Recipient
|
;[Wallet] Recipient
|
||||||
{:name :recipient
|
{:name :recipient
|
||||||
:insets {:bottom true}
|
:insets {:bottom true}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
:on-change (fn [text]
|
:on-change (fn [text]
|
||||||
(re-frame/dispatch [:search/recipient-filter-changed text])
|
(re-frame/dispatch [:search/recipient-filter-changed text])
|
||||||
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
|
||||||
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]]))
|
(debounce/debounce-and-dispatch [:contacts/set-new-identity text] 300))}]]))
|
||||||
|
|
||||||
(defn section
|
(defn section
|
||||||
[_ _ _]
|
[_ _ _]
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
(ns status-im.utils.db)
|
|
||||||
|
|
||||||
(defn valid-public-key?
|
|
||||||
[s]
|
|
||||||
(and (string? s) (not-empty s) (boolean (re-matches #"0x04[0-9a-f]{128}" s))))
|
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
(ns status-im2.contexts.add-new-contact.events
|
||||||
|
(:require [utils.re-frame :as rf]
|
||||||
|
[status-im.utils.types :as types]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.ethereum.core :as ethereum]
|
||||||
|
[status-im.ethereum.ens :as ens]
|
||||||
|
[status-im.ethereum.stateofus :as stateofus]
|
||||||
|
[status-im.native-module.core :as status]
|
||||||
|
[status-im2.utils.validators :as validators]
|
||||||
|
[status-im.utils.utils :as utils]))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:contacts/resolve-public-key-from-ens-name
|
||||||
|
(fn [{:keys [chain-id ens-name on-success on-error]}]
|
||||||
|
(ens/pubkey chain-id ens-name on-success on-error)))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:contacts/decompress-public-key
|
||||||
|
(fn [{:keys [public-key on-success on-error]}]
|
||||||
|
(status/compressed-key->public-key
|
||||||
|
public-key
|
||||||
|
(fn [resp]
|
||||||
|
(let [{:keys [error]} (types/json->clj resp)]
|
||||||
|
(if error
|
||||||
|
(on-error error)
|
||||||
|
(on-success
|
||||||
|
(str "0x" (subs resp 5)))))))))
|
||||||
|
|
||||||
|
(rf/defn set-new-identity
|
||||||
|
{:events [:contacts/set-new-identity]}
|
||||||
|
[{:keys [db]} input]
|
||||||
|
(let [input (utils/safe-trim input)
|
||||||
|
public-key? (validators/valid-public-key? input)
|
||||||
|
compressed-key? (validators/valid-compressed-key? input)
|
||||||
|
ens-name (if compressed-key? nil (stateofus/ens-name-parse input))
|
||||||
|
on-success (fn [pubkey]
|
||||||
|
(rf/dispatch
|
||||||
|
[:contacts/set-new-identity-success
|
||||||
|
input ens-name pubkey]))
|
||||||
|
on-error (fn [err]
|
||||||
|
(rf/dispatch
|
||||||
|
[:contacts/set-new-identity-error err input]))]
|
||||||
|
(cond
|
||||||
|
(empty? input) {:db (dissoc db :contacts/new-identity)}
|
||||||
|
public-key? {:db (assoc db
|
||||||
|
:contacts/new-identity
|
||||||
|
{:input input
|
||||||
|
:public-key input
|
||||||
|
:ens-name nil
|
||||||
|
:state :error
|
||||||
|
:error :uncompressed-key})}
|
||||||
|
:else
|
||||||
|
(cond->
|
||||||
|
{:db (assoc db
|
||||||
|
:contacts/new-identity
|
||||||
|
{:input input
|
||||||
|
:public-key nil
|
||||||
|
:ens-name nil
|
||||||
|
:state :searching
|
||||||
|
:error nil})}
|
||||||
|
compressed-key? (assoc :contacts/decompress-public-key
|
||||||
|
{:public-key input
|
||||||
|
:on-success on-success
|
||||||
|
:on-error on-error})
|
||||||
|
(not compressed-key?) (assoc :contacts/resolve-public-key-from-ens-name
|
||||||
|
{:chain-id (ethereum/chain-id db)
|
||||||
|
:ens-name ens-name
|
||||||
|
:on-success on-success
|
||||||
|
:on-error on-error})))))
|
||||||
|
|
||||||
|
(rf/defn set-new-identity-success
|
||||||
|
{:events [:contacts/set-new-identity-success]}
|
||||||
|
[{:keys [db]} input ens-name pubkey]
|
||||||
|
{:db (assoc db
|
||||||
|
:contacts/new-identity
|
||||||
|
{:input input
|
||||||
|
:public-key pubkey
|
||||||
|
:ens-name ens-name
|
||||||
|
:state :valid
|
||||||
|
:error nil})})
|
||||||
|
|
||||||
|
(rf/defn set-new-identity-error
|
||||||
|
{:events [:contacts/set-new-identity-error]}
|
||||||
|
[{:keys [db]} error input]
|
||||||
|
{:db (assoc db
|
||||||
|
:contacts/new-identity
|
||||||
|
{:input input
|
||||||
|
:public-key nil
|
||||||
|
:ens-name nil
|
||||||
|
:state :error
|
||||||
|
:error :invalid})})
|
||||||
|
|
||||||
|
(rf/defn clear-new-identity
|
||||||
|
{:events [:contacts/clear-new-identity :contacts/new-chat-focus]}
|
||||||
|
[{:keys [db]}]
|
||||||
|
{:db (dissoc db :contacts/new-identity)})
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
(ns status-im2.contexts.add-new-contact.events-test
|
||||||
|
(:require [cljs.test :refer-macros [deftest is]]
|
||||||
|
[status-im2.contexts.add-new-contact.events :as core]))
|
||||||
|
|
||||||
|
(def init-db
|
||||||
|
{:networks/current-network "mainnet_rpc"
|
||||||
|
:networks/networks {"mainnet_rpc"
|
||||||
|
{:id "mainnet_rpc"
|
||||||
|
:config {:NetworkId 1}}}})
|
||||||
|
|
||||||
|
(defn search-db
|
||||||
|
[input]
|
||||||
|
{:contacts/new-identity {:input input
|
||||||
|
:public-key nil
|
||||||
|
:ens-name nil
|
||||||
|
:state :searching
|
||||||
|
:error nil}})
|
||||||
|
|
||||||
|
(deftest search-empty-string
|
||||||
|
(let [input ""
|
||||||
|
expected {:db init-db}
|
||||||
|
actual (core/set-new-identity {:db init-db} input)]
|
||||||
|
(is (= actual expected))))
|
||||||
|
|
||||||
|
(deftest search-ens
|
||||||
|
(let [input "esep"
|
||||||
|
clean (fn [db]
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:contacts/resolve-public-key-from-ens-name :on-success] nil)
|
||||||
|
(assoc-in [:contacts/resolve-public-key-from-ens-name :on-error] nil)))
|
||||||
|
expected {:db (merge init-db (search-db input))
|
||||||
|
:contacts/resolve-public-key-from-ens-name
|
||||||
|
{:chain-id 1
|
||||||
|
:ens-name (str input ".stateofus.eth")
|
||||||
|
:on-success nil
|
||||||
|
:on-error nil}}
|
||||||
|
actual (core/set-new-identity {:db init-db} input)]
|
||||||
|
(is (= (clean actual) expected))))
|
||||||
|
|
||||||
|
(deftest search-compressed-key
|
||||||
|
(let [input "zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA"
|
||||||
|
clean (fn [db]
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:contacts/decompress-public-key :on-success] nil)
|
||||||
|
(assoc-in [:contacts/decompress-public-key :on-error] nil)))
|
||||||
|
expected {:db (merge init-db (search-db input))
|
||||||
|
:contacts/decompress-public-key
|
||||||
|
{:public-key input
|
||||||
|
:on-success nil
|
||||||
|
:on-error nil}}
|
||||||
|
actual (core/set-new-identity {:db init-db} input)]
|
||||||
|
(is (= (clean actual) expected))))
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
(ns status-im2.contexts.add-new-contact.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]
|
||||||
|
[status-im.react-native.resources :as resources]
|
||||||
|
[react-native.platform :as platform]
|
||||||
|
[quo2.foundations.typography :as typography]))
|
||||||
|
|
||||||
|
(defn container-kbd
|
||||||
|
[]
|
||||||
|
{:style {:flex 1}
|
||||||
|
:keyboardVerticalOffset 60})
|
||||||
|
|
||||||
|
(def container-image
|
||||||
|
{:style {:flex 1
|
||||||
|
:flex-direction :row}})
|
||||||
|
|
||||||
|
(defn image
|
||||||
|
[file]
|
||||||
|
{:source (resources/get-image file)
|
||||||
|
:style {:flex 1}})
|
||||||
|
|
||||||
|
(defn container-outer
|
||||||
|
[]
|
||||||
|
{:style {:flex (if platform/ios? 4.5 5)
|
||||||
|
:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||||
|
:justify-content :space-between
|
||||||
|
:align-items :center
|
||||||
|
:padding 16
|
||||||
|
:border-radius 20}})
|
||||||
|
|
||||||
|
(def container-inner
|
||||||
|
{:style {:flex-direction :column
|
||||||
|
:align-items :flex-start}})
|
||||||
|
|
||||||
|
(def container-text-input
|
||||||
|
{:style {:flex-direction :row
|
||||||
|
:justify-content :space-between}})
|
||||||
|
|
||||||
|
(def container-error
|
||||||
|
{:style {:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:margin-top 8}})
|
||||||
|
|
||||||
|
(defn text-title
|
||||||
|
[]
|
||||||
|
{:size :heading-1
|
||||||
|
:weight :semi-bold
|
||||||
|
:style {:margin-bottom 6
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/neutral-100
|
||||||
|
colors/white)}})
|
||||||
|
|
||||||
|
(defn text-subtitle
|
||||||
|
[]
|
||||||
|
{:size :paragraph-1
|
||||||
|
:weight :regular
|
||||||
|
:style {:margin-bottom 20
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/neutral-100
|
||||||
|
colors/white)}})
|
||||||
|
|
||||||
|
(defn text-description
|
||||||
|
[]
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style {:margin-bottom 6
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/neutral-50
|
||||||
|
colors/neutral-40)}})
|
||||||
|
|
||||||
|
(def icon-error
|
||||||
|
{:size 16
|
||||||
|
:color colors/danger-50})
|
||||||
|
|
||||||
|
(def text-error
|
||||||
|
{:size :paragraph-2
|
||||||
|
:align :left
|
||||||
|
:style {:margin-left 4
|
||||||
|
:color colors/danger-50}})
|
||||||
|
|
||||||
|
(defn text-input
|
||||||
|
[error?]
|
||||||
|
{:accessibility-label :enter-contact-code-input
|
||||||
|
:auto-capitalize :none
|
||||||
|
:placeholder-text-color (colors/theme-colors
|
||||||
|
colors/neutral-40
|
||||||
|
colors/neutral-50)
|
||||||
|
:multiline true
|
||||||
|
:style
|
||||||
|
(merge typography/monospace
|
||||||
|
typography/paragraph-1
|
||||||
|
{:padding-top 8
|
||||||
|
:padding-left 12
|
||||||
|
:padding-right 12
|
||||||
|
:padding-bottom 8
|
||||||
|
:margin-right 10
|
||||||
|
:flex 1
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/black
|
||||||
|
colors/white)
|
||||||
|
:background-color (colors/theme-colors
|
||||||
|
colors/white
|
||||||
|
colors/neutral-95)
|
||||||
|
:border-width 1
|
||||||
|
:border-radius 12
|
||||||
|
:border-color (if error?
|
||||||
|
colors/danger-50-opa-40
|
||||||
|
(colors/theme-colors
|
||||||
|
colors/neutral-20
|
||||||
|
colors/neutral-80))})})
|
||||||
|
|
||||||
|
(defn button-close
|
||||||
|
[]
|
||||||
|
{:type :grey
|
||||||
|
:icon true
|
||||||
|
:accessibility-label :new-contact-close-button
|
||||||
|
:size 32
|
||||||
|
:override-background-color (colors/theme-colors
|
||||||
|
colors/white-opa-60
|
||||||
|
colors/neutral-80-opa-60)
|
||||||
|
:style {:position :absolute
|
||||||
|
:left 20
|
||||||
|
:top 20}})
|
||||||
|
|
||||||
|
(def button-qr
|
||||||
|
{:type :outline
|
||||||
|
:icon true
|
||||||
|
:size 40})
|
||||||
|
|
||||||
|
(defn button-view-profile
|
||||||
|
[state]
|
||||||
|
{:type :primary
|
||||||
|
:size 40
|
||||||
|
:width 335
|
||||||
|
:style {:margin-top 24
|
||||||
|
:margin-bottom 24}
|
||||||
|
:accessibility-label :new-contact-button
|
||||||
|
:before :i/profile
|
||||||
|
:disabled (not= state :valid)})
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
(ns status-im2.contexts.add-new-contact.views
|
||||||
|
(:require [status-im2.contexts.add-new-contact.style :as style]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
|
[utils.debounce :as debounce]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[quo2.core :as quo]))
|
||||||
|
|
||||||
|
(defn new-contact
|
||||||
|
[]
|
||||||
|
(let [{:keys [input public-key state error]} (rf/sub
|
||||||
|
[:contacts/new-identity])
|
||||||
|
error? (and (= state :error)
|
||||||
|
(= error :uncompressed-key))]
|
||||||
|
[rn/keyboard-avoiding-view (style/container-kbd)
|
||||||
|
[rn/view style/container-image
|
||||||
|
[rn/image (style/image :add-new-contact)]
|
||||||
|
[quo/button
|
||||||
|
(merge (style/button-close)
|
||||||
|
{:on-press
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:contacts/clear-new-identity])
|
||||||
|
(rf/dispatch [:navigate-back]))}) :i/close]]
|
||||||
|
[rn/view (style/container-outer)
|
||||||
|
[rn/view style/container-inner
|
||||||
|
[quo/text (style/text-title)
|
||||||
|
(i18n/label :t/add-a-contact)]
|
||||||
|
[quo/text (style/text-subtitle)
|
||||||
|
(i18n/label :t/find-your-friends)]
|
||||||
|
[quo/text (style/text-description)
|
||||||
|
(i18n/label :t/ens-or-chat-key)]
|
||||||
|
[rn/view style/container-text-input
|
||||||
|
[rn/text-input
|
||||||
|
(merge (style/text-input error?)
|
||||||
|
{:default-value input
|
||||||
|
:placeholder (i18n/label :t/type-some-chat-key)
|
||||||
|
:on-change-text #(debounce/debounce-and-dispatch
|
||||||
|
[:contacts/set-new-identity %]
|
||||||
|
600)})]
|
||||||
|
[quo/button
|
||||||
|
(merge style/button-qr
|
||||||
|
{:on-press #(js/alert "TODO: to be implemented")})
|
||||||
|
:i/scan]]
|
||||||
|
(when error?
|
||||||
|
[rn/view style/container-error
|
||||||
|
[quo/icon :i/alert style/icon-error]
|
||||||
|
[quo/text style/text-error (i18n/label :t/not-a-chatkey)]])]
|
||||||
|
[rn/view
|
||||||
|
[quo/button
|
||||||
|
(merge (style/button-view-profile state)
|
||||||
|
{:on-press
|
||||||
|
(fn []
|
||||||
|
(rf/dispatch [:contacts/clear-new-identity])
|
||||||
|
(rf/dispatch [:navigate-back])
|
||||||
|
(rf/dispatch [:chat.ui/show-profile public-key]))})
|
||||||
|
(i18n/label :t/view-profile)]]]]))
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
[status-im2.common.json-rpc.events]
|
[status-im2.common.json-rpc.events]
|
||||||
[status-im2.common.theme.core :as theme]
|
[status-im2.common.theme.core :as theme]
|
||||||
[status-im2.common.toasts.events]
|
[status-im2.common.toasts.events]
|
||||||
|
[status-im2.contexts.add-new-contact.events]
|
||||||
[status-im2.navigation.events :as navigation]
|
[status-im2.navigation.events :as navigation]
|
||||||
[status-im2.db :as db]
|
[status-im2.db :as db]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
[status-im.ui.screens.screens :as old-screens]
|
[status-im.ui.screens.screens :as old-screens]
|
||||||
[status-im2.contexts.activity-center.view :as activity-center]
|
[status-im2.contexts.activity-center.view :as activity-center]
|
||||||
[status-im2.contexts.chat.messages.view :as chat]
|
[status-im2.contexts.chat.messages.view :as chat]
|
||||||
|
[status-im2.contexts.add-new-contact.views :as add-new-contact]
|
||||||
[status-im2.contexts.communities.discover.view :as communities.discover]
|
[status-im2.contexts.communities.discover.view :as communities.discover]
|
||||||
[status-im2.contexts.communities.overview.view :as communities.overview]
|
[status-im2.contexts.communities.overview.view :as communities.overview]
|
||||||
[status-im2.contexts.quo-preview.main :as quo.preview]
|
[status-im2.contexts.quo-preview.main :as quo.preview]
|
||||||
@@ -47,6 +48,10 @@
|
|||||||
:decelerate}}]}}}
|
:decelerate}}]}}}
|
||||||
:component images-horizontal/images-horizontal}
|
:component images-horizontal/images-horizontal}
|
||||||
|
|
||||||
|
{:name :new-contact
|
||||||
|
:options {:topBar {:visible false}}
|
||||||
|
:component add-new-contact/new-contact}
|
||||||
|
|
||||||
{:name :discover-communities
|
{:name :discover-communities
|
||||||
:options {:topBar {:visible false}}
|
:options {:topBar {:visible false}}
|
||||||
:component communities.discover/discover}
|
:component communities.discover/discover}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
(ns status-im2.utils.validators)
|
||||||
|
|
||||||
|
(defn valid-public-key?
|
||||||
|
[s]
|
||||||
|
(and (string? s)
|
||||||
|
(not-empty s)
|
||||||
|
(boolean (re-matches #"0x04[0-9a-f]{128}" s))))
|
||||||
|
|
||||||
|
(defn valid-compressed-key?
|
||||||
|
[s]
|
||||||
|
(and (string? s)
|
||||||
|
(not-empty s)
|
||||||
|
(boolean (re-matches #"^zQ3[0-9A-HJ-NP-Za-km-z]{46}" s))))
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
(ns status-im2.utils.validators-test
|
||||||
|
(:require [cljs.test :refer-macros [deftest testing is]]
|
||||||
|
[status-im2.utils.validators :refer [valid-compressed-key?]]))
|
||||||
|
|
||||||
|
(deftest test-valid-compressed-key
|
||||||
|
(testing "valid"
|
||||||
|
(is (valid-compressed-key?
|
||||||
|
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA")))
|
||||||
|
(testing "uncompressed key"
|
||||||
|
(is
|
||||||
|
(not
|
||||||
|
(valid-compressed-key?
|
||||||
|
"0x048a6773339d11ccf5fd81677b7e54daeec544a1287bd92b725047ad6faa9a9b9f8ea86ed5a226d2a994f5f46d0b43321fd8de7b7997a166e67905c8c73cd37ce"))))
|
||||||
|
(testing "nil"
|
||||||
|
(is (not (valid-compressed-key? nil))))
|
||||||
|
(testing "empty string"
|
||||||
|
(is (not (valid-compressed-key? ""))))
|
||||||
|
(testing "too short"
|
||||||
|
(is (not (valid-compressed-key? "zQ3FGR5y6U5a6"))))
|
||||||
|
(testing "too long"
|
||||||
|
(is (not (valid-compressed-key?
|
||||||
|
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA2"))))
|
||||||
|
(testing "0x prefix"
|
||||||
|
(is (not (valid-compressed-key? "0xFGR5y6U5a6"))))
|
||||||
|
(testing "contains I"
|
||||||
|
(is (not (valid-compressed-key?
|
||||||
|
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gI"))))
|
||||||
|
(testing "contains O"
|
||||||
|
(is (not (valid-compressed-key?
|
||||||
|
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gO"))))
|
||||||
|
(testing "contains l"
|
||||||
|
(is (not (valid-compressed-key?
|
||||||
|
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gl")))))
|
||||||
@@ -570,6 +570,7 @@
|
|||||||
"skip": "Skip",
|
"skip": "Skip",
|
||||||
"password-placeholder": "Password...",
|
"password-placeholder": "Password...",
|
||||||
"confirm-password-placeholder": "Confirm your password...",
|
"confirm-password-placeholder": "Confirm your password...",
|
||||||
|
"ens-or-chat-key": "ENS or Chat key",
|
||||||
"enter-pin": "Enter 6-digit passcode",
|
"enter-pin": "Enter 6-digit passcode",
|
||||||
"enter-puk-code": "Enter PUK code",
|
"enter-puk-code": "Enter PUK code",
|
||||||
"enter-puk-code-description": "6-digit passcode has been blocked.\n Please enter PUK code to unblock passcode.",
|
"enter-puk-code-description": "6-digit passcode has been blocked.\n Please enter PUK code to unblock passcode.",
|
||||||
@@ -597,6 +598,7 @@
|
|||||||
"fetch-messages": "Fetch messages",
|
"fetch-messages": "Fetch messages",
|
||||||
"fetch-timeline": "↓ Fetch",
|
"fetch-timeline": "↓ Fetch",
|
||||||
"find": "Find",
|
"find": "Find",
|
||||||
|
"find-your-friends": "Find your friends with their ENS or Chatkey",
|
||||||
"finish": "Finish",
|
"finish": "Finish",
|
||||||
"finishing-card-setup": "Finishing card setup",
|
"finishing-card-setup": "Finishing card setup",
|
||||||
"fleet": "Fleet",
|
"fleet": "Fleet",
|
||||||
@@ -986,6 +988,7 @@
|
|||||||
"node-version": "Node version",
|
"node-version": "Node version",
|
||||||
"nonce": "Nonce",
|
"nonce": "Nonce",
|
||||||
"none": "None",
|
"none": "None",
|
||||||
|
"not-a-chatkey": "This is not a chatkey",
|
||||||
"not-applicable": "Not applicable for unsigned transactions",
|
"not-applicable": "Not applicable for unsigned transactions",
|
||||||
"not-keycard-text": "The card you used is not a Keycard. You need to purchase a Keycard to use it",
|
"not-keycard-text": "The card you used is not a Keycard. You need to purchase a Keycard to use it",
|
||||||
"not-keycard-title": "Not a Keycard",
|
"not-keycard-title": "Not a Keycard",
|
||||||
@@ -1871,6 +1874,7 @@
|
|||||||
"identity-verification-request": "Identity verification",
|
"identity-verification-request": "Identity verification",
|
||||||
"identity-verification-request-sent": "asks",
|
"identity-verification-request-sent": "asks",
|
||||||
"type-something": "Type something",
|
"type-something": "Type something",
|
||||||
|
"type-some-chat-key": "0x123abc",
|
||||||
"your-answer": "Your answer",
|
"your-answer": "Your answer",
|
||||||
"membership": "Membership",
|
"membership": "Membership",
|
||||||
"jump-to": "Jump to",
|
"jump-to": "Jump to",
|
||||||
|
|||||||
Reference in New Issue
Block a user