From 3800f3f7daf076e949fe622aecfcd9b9d4601aae Mon Sep 17 00:00:00 2001 From: andrey Date: Tue, 30 Jun 2020 15:05:30 +0200 Subject: [PATCH] [#10891] Add 'Add new contact' and 'Invite friends' button to Contact screen Signed-off-by: andrey --- src/status_im/events.cljs | 8 ++- .../ui/screens/add_new/new_chat/events.cljs | 16 +++-- .../ui/screens/add_new/new_chat/views.cljs | 70 +++++++++++++++---- .../ui/screens/contacts_list/views.cljs | 52 +++++++++----- src/status_im/ui/screens/routing/main.cljs | 4 ++ translations/en.json | 2 + 6 files changed, 115 insertions(+), 37 deletions(-) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index d16158b134..9e965638c0 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -860,10 +860,14 @@ (handlers/register-handler-fx :contact.ui/contact-code-submitted [(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] (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 (contact/name-verified % public-key ens-name)))))) diff --git a/src/status_im/ui/screens/add_new/new_chat/events.cljs b/src/status_im/ui/screens/add_new/new_chat/events.cljs index 3d0a3faf01..27de3f18c5 100644 --- a/src/status_im/ui/screens/add_new/new_chat/events.cljs +++ b/src/status_im/ui/screens/add_new/new_chat/events.cljs @@ -12,7 +12,9 @@ [status-im.utils.utils :as utils] [status-im.utils.fx :as fx] [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] (when (string? contact-identity) @@ -79,22 +81,26 @@ (fx/defn 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) (string/starts-with? contact-identity "0x")) validation-result (db/validate-pub-key db contact-identity)] (cond (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)) - (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)) (let [chain (ethereum/chain-keyword db)] {:resolve-public-key {:chain chain :contact-identity contact-identity - :cb #(re-frame/dispatch [:contact/qr-code-scanned %])}}) + :cb #(re-frame/dispatch [:contact/qr-code-scanned % opts])}}) :else {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) diff --git a/src/status_im/ui/screens/add_new/new_chat/views.cljs b/src/status_im/ui/screens/add_new/new_chat/views.cljs index 7ac9c4e60b..9f52d99a4b 100644 --- a/src/status_im/ui/screens/add_new/new_chat/views.cljs +++ b/src/status_im/ui/screens/add_new/new_chat/views.cljs @@ -35,20 +35,21 @@ icon]) (defn- input-icon - [state] - (case state - :searching - [icon-wrapper colors/gray - [react/activity-indicator {:color colors/white-persist}]] + [state new-contact?] + (let [icon (if new-contact? :main-icons/add :main-icons/arrow-right)] + (case state + :searching + [icon-wrapper colors/gray + [react/activity-indicator {:color colors/white-persist}]] - :valid - [react/touchable-highlight - {:on-press #(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted] 3000)} - [icon-wrapper colors/blue - [vector-icons/icon :main-icons/arrow-right {:color colors/white-persist}]]] + :valid + [react/touchable-highlight + {:on-press #(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted new-contact?] 3000)} + [icon-wrapper colors/blue + [vector-icons/icon icon {:color colors/white-persist}]]] - [icon-wrapper colors/gray - [vector-icons/icon :main-icons/arrow-right {:color colors/white-persist}]])) + [icon-wrapper colors/gray + [vector-icons/icon icon {:color colors/white-persist}]]))) (defn get-validation-label [value] (case value @@ -80,7 +81,7 @@ (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] 3000)) + (debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false] 3000)) :placeholder (i18n/label :t/enter-contact-code) :show-cancel false :accessibility-label :enter-contact-code-input @@ -88,7 +89,7 @@ :return-key-type :go}]] [react/view {:justify-content :center :align-items :center} - [input-icon state]]] + [input-icon state false]]] [react/view {:min-height 30 :justify-content :flex-end} [react/text {:style styles/message} (cond (= state :error) @@ -102,3 +103,44 @@ :render-fn render-row :enableEmptySections true :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 "")]]])) diff --git a/src/status_im/ui/screens/contacts_list/views.cljs b/src/status_im/ui/screens/contacts_list/views.cljs index d955bfad55..527104409d 100644 --- a/src/status_im/ui/screens/contacts_list/views.cljs +++ b/src/status_im/ui/screens/contacts_list/views.cljs @@ -6,6 +6,7 @@ [status-im.ui.components.react :as react] [status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.i18n :as i18n] + [status-im.ui.components.list-selection :as list-selection] [quo.core :as quo] [status-im.ui.components.topbar :as topbar]) (:require-macros [status-im.utils.views :refer [defview letsubs]])) @@ -18,27 +19,46 @@ :chevron true :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 [] (letsubs [blocked-contacts-count [:contacts/blocked-count] contacts [:contacts/active]] [react/view {:flex 1} [topbar/topbar {:title :t/contacts}] - [react/scroll-view {:flex 1} - (when (pos? blocked-contacts-count) - [react/view {:margin-vertical 16} - [quo/list-item - {:title (i18n/label :t/blocked-users) - :icon :main-icons/cancel - :theme :negative - :accessibility-label :blocked-users-list-button - :chevron true - :accessory :text - :accessory-text blocked-contacts-count - :on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]]) - [list.views/flat-list - {:data contacts - :key-fn :address - :render-fn contacts-list-item}]]])) + (if (seq contacts) + [react/scroll-view {:flex 1} + [add-new-contact] + (when (pos? blocked-contacts-count) + [react/view {:margin-vertical 16} + [quo/list-item + {:title (i18n/label :t/blocked-users) + :icon :main-icons/cancel + :theme :negative + :accessibility-label :blocked-users-list-button + :chevron true + :accessory :text + :accessory-text blocked-contacts-count + :on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]]) + [list.views/flat-list + {: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 [] (letsubs [blocked-contacts [:contacts/blocked]] diff --git a/src/status_im/ui/screens/routing/main.cljs b/src/status_im/ui/screens/routing/main.cljs index 7769a8e762..b55c62bc0b 100644 --- a/src/status_im/ui/screens/routing/main.cljs +++ b/src/status_im/ui/screens/routing/main.cljs @@ -69,6 +69,10 @@ :on-focus [::new-chat.events/new-chat-focus] :transition :presentation-ios :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 :transition :presentation-ios :component new-public-chat/new-public-chat} diff --git a/translations/en.json b/translations/en.json index 4b716fea08..7755ad97da 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1157,6 +1157,8 @@ "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", "not-enough-snt": "Not enough SNT", + "add-new-contact": "Add new contact", + "you-dont-have-contacts": "You don’t have any contacts yet.", "set-max": "Set max", "continue-anyway": "Continue anyway" }