[#10891] Add 'Add new contact' and 'Invite friends' button to Contact screen

Signed-off-by: andrey <motor4ik@gmail.com>
This commit is contained in:
andrey 2020-06-30 15:05:30 +02:00
parent 4dda20999b
commit 3800f3f7da
No known key found for this signature in database
GPG Key ID: 89B67245FD2F0272
6 changed files with 115 additions and 37 deletions

View File

@ -860,10 +860,14 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:contact.ui/contact-code-submitted :contact.ui/contact-code-submitted
[(re-frame/inject-cofx :random-id-generator)] [(re-frame/inject-cofx :random-id-generator)]
(fn [{{:contacts/keys [new-identity]} :db :as cofx} _] (fn [{{:contacts/keys [new-identity]} :db :as cofx} [_ new-contact?]]
(let [{:keys [public-key ens-name]} new-identity] (let [{:keys [public-key ens-name]} new-identity]
(fx/merge cofx (fx/merge cofx
(chat/start-chat public-key {:navigation-reset? true}) #(if new-contact?
(contact/add-contact % public-key)
(chat/start-chat % public-key {:navigation-reset? true}))
#(when new-contact?
(navigation/navigate-back %))
#(when ens-name #(when ens-name
(contact/name-verified % public-key ens-name)))))) (contact/name-verified % public-key ens-name))))))

View File

@ -12,7 +12,9 @@
[status-im.utils.utils :as utils] [status-im.utils.utils :as utils]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.chat.models :as chat] [status-im.chat.models :as chat]
[status-im.i18n :as i18n])) [status-im.i18n :as i18n]
[status-im.contact.core :as contact]
[status-im.navigation :as navigation]))
(defn- ens-name-parse [contact-identity] (defn- ens-name-parse [contact-identity]
(when (string? contact-identity) (when (string? contact-identity)
@ -79,22 +81,26 @@
(fx/defn qr-code-scanned (fx/defn qr-code-scanned
{:events [:contact/qr-code-scanned]} {:events [:contact/qr-code-scanned]}
[{:keys [db] :as cofx} contact-identity] [{:keys [db] :as cofx} contact-identity {:keys [new-contact?] :as opts}]
(let [public-key? (and (string? contact-identity) (let [public-key? (and (string? contact-identity)
(string/starts-with? contact-identity "0x")) (string/starts-with? contact-identity "0x"))
validation-result (db/validate-pub-key db contact-identity)] validation-result (db/validate-pub-key db contact-identity)]
(cond (cond
(and public-key? (not (some? validation-result))) (and public-key? (not (some? validation-result)))
(chat/start-chat cofx contact-identity {:navigation-reset? true}) (if new-contact?
(fx/merge cofx
(contact/add-contact contact-identity)
(navigation/navigate-to-cofx :contacts-list {}))
(chat/start-chat cofx contact-identity {:navigation-reset? true}))
(and (string? contact-identity) (ul/match-url contact-identity ul/profile-regex)) (and (string? contact-identity) (ul/match-url contact-identity ul/profile-regex))
(qr-code-scanned cofx (ul/match-url contact-identity ul/profile-regex)) (qr-code-scanned cofx (ul/match-url contact-identity ul/profile-regex) opts)
(and (not public-key?) (string? contact-identity)) (and (not public-key?) (string? contact-identity))
(let [chain (ethereum/chain-keyword db)] (let [chain (ethereum/chain-keyword db)]
{:resolve-public-key {:chain chain {:resolve-public-key {:chain chain
:contact-identity contact-identity :contact-identity contact-identity
:cb #(re-frame/dispatch [:contact/qr-code-scanned %])}}) :cb #(re-frame/dispatch [:contact/qr-code-scanned % opts])}})
:else :else
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)

View File

@ -35,20 +35,21 @@
icon]) icon])
(defn- input-icon (defn- input-icon
[state] [state new-contact?]
(case state (let [icon (if new-contact? :main-icons/add :main-icons/arrow-right)]
:searching (case state
[icon-wrapper colors/gray :searching
[react/activity-indicator {:color colors/white-persist}]] [icon-wrapper colors/gray
[react/activity-indicator {:color colors/white-persist}]]
:valid :valid
[react/touchable-highlight [react/touchable-highlight
{:on-press #(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted] 3000)} {:on-press #(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted new-contact?] 3000)}
[icon-wrapper colors/blue [icon-wrapper colors/blue
[vector-icons/icon :main-icons/arrow-right {:color colors/white-persist}]]] [vector-icons/icon icon {:color colors/white-persist}]]]
[icon-wrapper colors/gray [icon-wrapper colors/gray
[vector-icons/icon :main-icons/arrow-right {:color colors/white-persist}]])) [vector-icons/icon icon {:color colors/white-persist}]])))
(defn get-validation-label [value] (defn get-validation-label [value]
(case value (case value
@ -80,7 +81,7 @@
(debounce/debounce-and-dispatch [:new-chat/set-new-identity %] 600)) (debounce/debounce-and-dispatch [:new-chat/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] 3000)) (debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false] 3000))
:placeholder (i18n/label :t/enter-contact-code) :placeholder (i18n/label :t/enter-contact-code)
:show-cancel false :show-cancel false
:accessibility-label :enter-contact-code-input :accessibility-label :enter-contact-code-input
@ -88,7 +89,7 @@
:return-key-type :go}]] :return-key-type :go}]]
[react/view {:justify-content :center [react/view {:justify-content :center
:align-items :center} :align-items :center}
[input-icon state]]] [input-icon state false]]]
[react/view {:min-height 30 :justify-content :flex-end} [react/view {:min-height 30 :justify-content :flex-end}
[react/text {:style styles/message} [react/text {:style styles/message}
(cond (= state :error) (cond (= state :error)
@ -102,3 +103,44 @@
:render-fn render-row :render-fn render-row
:enableEmptySections true :enableEmptySections true
:keyboardShouldPersistTaps :always}]])) :keyboardShouldPersistTaps :always}]]))
(views/defview new-contact []
(views/letsubs [{:keys [state ens-name public-key error]} [:contacts/new-identity]]
[react/view {:style {:flex 1}}
[topbar/topbar
{:title :t/new-contact
:modal? true
:accessories [{:icon :qr
:accessibility-label :scan-contact-code-button
:handler #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
{:title (i18n/label :t/new-contact)
:handler :contact/qr-code-scanned
:new-contact? true}])}]}]
[react/view {:flex-direction :row
:padding 16}
[react/view {:flex 1
:padding-right 16}
[quo/text-input
{:on-change-text
#(do
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
(debounce/debounce-and-dispatch [:new-chat/set-new-identity %] 600))
:on-submit-editing
#(when (= state :valid)
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted true] 3000))
:placeholder (i18n/label :t/enter-contact-code)
:show-cancel false
:accessibility-label :enter-contact-code-input
:auto-capitalize :none
:return-key-type :go}]]
[react/view {:justify-content :center
:align-items :center}
[input-icon state true]]]
[react/view {:min-height 30 :justify-content :flex-end}
[react/text {:style styles/message}
(cond (= state :error)
(get-validation-label error)
(= state :valid)
(str (when ens-name (str ens-name " • "))
(utils/get-shortened-address public-key))
:else "")]]]))

View File

@ -6,6 +6,7 @@
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.ui.components.list-selection :as list-selection]
[quo.core :as quo] [quo.core :as quo]
[status-im.ui.components.topbar :as topbar]) [status-im.ui.components.topbar :as topbar])
(:require-macros [status-im.utils.views :refer [defview letsubs]])) (:require-macros [status-im.utils.views :refer [defview letsubs]]))
@ -18,27 +19,46 @@
:chevron true :chevron true
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]) :on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}])
(defn add-new-contact []
[quo/list-item
{:icon :main-icons/add
:theme :accent
:title (i18n/label :t/add-new-contact)
:accessibility-label :add-new-contact-button
:on-press #(re-frame/dispatch [:navigate-to :new-contact])}])
(defview contacts-list [] (defview contacts-list []
(letsubs [blocked-contacts-count [:contacts/blocked-count] (letsubs [blocked-contacts-count [:contacts/blocked-count]
contacts [:contacts/active]] contacts [:contacts/active]]
[react/view {:flex 1} [react/view {:flex 1}
[topbar/topbar {:title :t/contacts}] [topbar/topbar {:title :t/contacts}]
[react/scroll-view {:flex 1} (if (seq contacts)
(when (pos? blocked-contacts-count) [react/scroll-view {:flex 1}
[react/view {:margin-vertical 16} [add-new-contact]
[quo/list-item (when (pos? blocked-contacts-count)
{:title (i18n/label :t/blocked-users) [react/view {:margin-vertical 16}
:icon :main-icons/cancel [quo/list-item
:theme :negative {:title (i18n/label :t/blocked-users)
:accessibility-label :blocked-users-list-button :icon :main-icons/cancel
:chevron true :theme :negative
:accessory :text :accessibility-label :blocked-users-list-button
:accessory-text blocked-contacts-count :chevron true
:on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]]) :accessory :text
[list.views/flat-list :accessory-text blocked-contacts-count
{:data contacts :on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]])
:key-fn :address [list.views/flat-list
:render-fn contacts-list-item}]]])) {:data contacts
:key-fn :address
:render-fn contacts-list-item}]]
[react/view {:flex 1}
[add-new-contact]
[react/view {:align-items :center :flex 1 :justify-content :center}
[react/text {:style {:color colors/gray :margin-vertical 24}}
(i18n/label :t/you-dont-have-contacts)]
[quo/button
{:accessibility-label :invite-friends
:on-press #(list-selection/open-share {:message (i18n/label :t/get-status-at)})}
(i18n/label :t/invite-friends)]]])]))
(defview blocked-users-list [] (defview blocked-users-list []
(letsubs [blocked-contacts [:contacts/blocked]] (letsubs [blocked-contacts [:contacts/blocked]]

View File

@ -69,6 +69,10 @@
:on-focus [::new-chat.events/new-chat-focus] :on-focus [::new-chat.events/new-chat-focus]
:transition :presentation-ios :transition :presentation-ios
:component new-chat/new-chat} :component new-chat/new-chat}
{:name :new-contact
:on-focus [::new-chat.events/new-chat-focus]
:transition :presentation-ios
:component new-chat/new-contact}
{:name :new-public-chat {:name :new-public-chat
:transition :presentation-ios :transition :presentation-ios
:component new-public-chat/new-public-chat} :component new-public-chat/new-public-chat}

View File

@ -1157,6 +1157,8 @@
"tx-fail-description2" : "This transaction is likely to fail. Set a custom network fee to sign at your own risk.", "tx-fail-description2" : "This transaction is likely to fail. Set a custom network fee to sign at your own risk.",
"set-custom-fee" : "Set custom fee", "set-custom-fee" : "Set custom fee",
"not-enough-snt": "Not enough SNT", "not-enough-snt": "Not enough SNT",
"add-new-contact": "Add new contact",
"you-dont-have-contacts": "You dont have any contacts yet.",
"set-max": "Set max", "set-max": "Set max",
"continue-anyway": "Continue anyway" "continue-anyway": "Continue anyway"
} }