From ca9346a931277b0fc2844e7d8abd93a63354d216 Mon Sep 17 00:00:00 2001 From: Sean Hagstrom Date: Mon, 11 Mar 2024 09:43:18 +0000 Subject: [PATCH] Implement reviewal of contact requests from contact profile (#19119) * chore: add english translation for contact-request-review * feature: integrate contact-request-review button * tweak: render the locked-input label when provided * tweak: allow locked-input component to grow in height * chore: add english translation for "ignore" * feature: add subscription for retrieving a pending contact-request by contact-id * feature: integrate initial contact request review flow * tweak: display send-message button on contact profile when contact-request-state is mutual * tidy: refactor button-wrapper view to be button container-styles * feature: add toast for accepting contact request --- .../components/inputs/locked_input/style.cljs | 2 +- .../components/inputs/locked_input/view.cljs | 11 ++-- .../profile/contact/contact_request/view.cljs | 1 + .../profile/contact/contact_review/style.cljs | 8 +++ .../profile/contact/contact_review/view.cljs | 52 +++++++++++++++++++ .../profile/contact/header/style.cljs | 4 +- .../contexts/profile/contact/header/view.cljs | 35 ++++++++++--- src/status_im/subs/activity_center.cljs | 8 +++ src/status_im/subs/activity_center_test.cljs | 18 +++++++ translations/en.json | 2 + 10 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 src/status_im/contexts/profile/contact/contact_review/style.cljs create mode 100644 src/status_im/contexts/profile/contact/contact_review/view.cljs diff --git a/src/quo/components/inputs/locked_input/style.cljs b/src/quo/components/inputs/locked_input/style.cljs index 5ce78bfabd..d4645a9031 100644 --- a/src/quo/components/inputs/locked_input/style.cljs +++ b/src/quo/components/inputs/locked_input/style.cljs @@ -10,7 +10,7 @@ :background-color (colors/theme-colors colors/neutral-10 colors/neutral-80-opa-80 theme) - :height 40 + :min-height 40 :padding-horizontal 12 :padding-vertical 9 :margin-top 4}) diff --git a/src/quo/components/inputs/locked_input/view.cljs b/src/quo/components/inputs/locked_input/view.cljs index 9141017775..cd1c3daf51 100644 --- a/src/quo/components/inputs/locked_input/view.cljs +++ b/src/quo/components/inputs/locked_input/view.cljs @@ -22,11 +22,12 @@ (defn- locked-input-internal [{:keys [label icon container-style theme]} value] [rn/view {:style container-style} - [text/text - {:size :paragraph-2 - :weight :medium - :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} - label] + (when label + [text/text + {:size :paragraph-2 + :weight :medium + :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} + label]) [info-box {:theme theme :icon icon diff --git a/src/status_im/contexts/profile/contact/contact_request/view.cljs b/src/status_im/contexts/profile/contact/contact_request/view.cljs index 55c016403a..4019306be5 100644 --- a/src/status_im/contexts/profile/contact/contact_request/view.cljs +++ b/src/status_im/contexts/profile/contact/contact_request/view.cljs @@ -44,3 +44,4 @@ :button-one-props {:disabled? (string/blank? message) :on-press on-message-submit} :button-one-label (i18n/label :t/send-contact-request)}]])) + diff --git a/src/status_im/contexts/profile/contact/contact_review/style.cljs b/src/status_im/contexts/profile/contact/contact_review/style.cljs new file mode 100644 index 0000000000..c8c6a878b7 --- /dev/null +++ b/src/status_im/contexts/profile/contact/contact_review/style.cljs @@ -0,0 +1,8 @@ +(ns status-im.contexts.profile.contact.contact-review.style) + +(def message-input-wrapper + {:padding-vertical 8 + :padding-horizontal 20}) + +(def bottom-actions-wrapper + {:padding-vertical 4}) diff --git a/src/status_im/contexts/profile/contact/contact_review/view.cljs b/src/status_im/contexts/profile/contact/contact_review/view.cljs new file mode 100644 index 0000000000..4a26fad104 --- /dev/null +++ b/src/status_im/contexts/profile/contact/contact_review/view.cljs @@ -0,0 +1,52 @@ +(ns status-im.contexts.profile.contact.contact-review.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [status-im.contexts.profile.contact.contact-review.style :as style] + [status-im.contexts.profile.utils :as profile.utils] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (let [{:keys [public-key customization-color] + :as profile} (rf/sub [:contacts/current-contact]) + {contact-request-id :id + :keys [message]} (rf/sub [:activity-center/pending-contact-request-from-contact-id + public-key]) + ;; TODO(@seanstrom): https://github.com/status-im/status-mobile/issues/18733 + customization-color (or customization-color :blue) + full-name (profile.utils/displayed-name profile) + profile-picture (profile.utils/photo profile) + on-contact-accept (rn/use-callback + (fn [] + (rf/dispatch [:hide-bottom-sheet]) + (rf/dispatch [:activity-center.contact-requests/accept + contact-request-id]) + (rf/dispatch [:toasts/upsert + {:id :accept-contact-request + :type :positive + :text (i18n/label + :t/contact-request-was-accepted)}])) + [contact-request-id]) + on-contact-ignore (rn/use-callback (fn [] + (rf/dispatch [:hide-bottom-sheet])))] + [:<> + [quo/drawer-top + {:type :context-tag + :context-tag-type :default + :title (i18n/label :t/contact-request-review) + :full-name full-name + :profile-picture profile-picture + :customization-color customization-color}] + [rn/view {:style style/message-input-wrapper} + [quo/locked-input {} + (-> message :content :text)]] + [rn/view {:style style/bottom-actions-wrapper} + [quo/bottom-actions + {:actions :two-actions + :button-one-label (i18n/label :t/accept) + :button-one-props {:type :positive + :on-press on-contact-accept} + :button-two-props {:type :danger + :on-press on-contact-ignore} + :button-two-label (i18n/label :t/ignore)}]]])) diff --git a/src/status_im/contexts/profile/contact/header/style.cljs b/src/status_im/contexts/profile/contact/header/style.cljs index 926b72e118..a2b2025c00 100644 --- a/src/status_im/contexts/profile/contact/header/style.cljs +++ b/src/status_im/contexts/profile/contact/header/style.cljs @@ -8,8 +8,8 @@ :align-items :flex-start}) (def button-wrapper - {:padding-top 8 - :padding-bottom 16 + {:margin-top 8 + :margin-bottom 16 :padding-horizontal 20}) (defn header-container diff --git a/src/status_im/contexts/profile/contact/header/view.cljs b/src/status_im/contexts/profile/contact/header/view.cljs index 2f8f2af825..a165fb8adb 100644 --- a/src/status_im/contexts/profile/contact/header/view.cljs +++ b/src/status_im/contexts/profile/contact/header/view.cljs @@ -7,6 +7,7 @@ [status-im.common.scalable-avatar.view :as avatar] [status-im.constants :as constants] [status-im.contexts.profile.contact.contact-request.view :as contact-request] + [status-im.contexts.profile.contact.contact-review.view :as contact-review] [status-im.contexts.profile.contact.header.style :as style] [status-im.contexts.profile.utils :as profile.utils] [utils.i18n :as i18n] @@ -14,7 +15,7 @@ (defn view [{:keys [scroll-y]}] - (let [{:keys [public-key customization-color + (let [{:keys [public-key customization-color ens-name emoji-hash bio contact-request-state] :as profile} (rf/sub [:contacts/current-contact]) customization-color (or customization-color :blue) @@ -23,7 +24,13 @@ online? (rf/sub [:visibility-status-updates/online? public-key]) theme (quo.theme/use-theme-value) on-contact-request (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:content (fn [] [contact-request/view])}]))] + {:content (fn [] [contact-request/view])}])) + on-contact-review (rn/use-callback #(rf/dispatch [:show-bottom-sheet + {:content (fn [] [contact-review/view])}])) + on-start-chat (rn/use-callback #(rf/dispatch [:chat.ui/start-chat + public-key + ens-name]) + [ens-name public-key])] [rn/view {:style style/header-container} [rn/view {:style style/header-top-wrapper} [rn/view {:style style/avatar-wrapper} @@ -49,10 +56,24 @@ (cond (or (not contact-request-state) (= contact-request-state constants/contact-request-state-none)) - [rn/view {:style style/button-wrapper} - [quo/button - {:on-press on-contact-request - :icon-left :i/add-user} - (i18n/label :t/send-contact-request)]] + [quo/button + {:container-style style/button-wrapper + :on-press on-contact-request + :icon-left :i/add-user} + (i18n/label :t/send-contact-request)] + + (= contact-request-state constants/contact-request-state-received) + [quo/button + {:container-style style/button-wrapper + :on-press on-contact-review + :icon-left :i/add-user} + (i18n/label :t/contact-request-review)] + + (= contact-request-state constants/contact-request-state-mutual) + [quo/button + {:container-style style/button-wrapper + :on-press on-start-chat + :icon-left :i/messages} + (i18n/label :t/send-message)] :else nil)])) diff --git a/src/status_im/subs/activity_center.cljs b/src/status_im/subs/activity_center.cljs index 4e34f1f5aa..e72dc7414c 100644 --- a/src/status_im/subs/activity_center.cljs +++ b/src/status_im/subs/activity_center.cljs @@ -80,3 +80,11 @@ :<- [:activity-center] (fn [activity-center] (:contact-requests activity-center))) + +(re-frame/reg-sub + :activity-center/pending-contact-request-from-contact-id + :<- [:activity-center/pending-contact-requests] + (fn [pending-contact-requests [_ contact-id]] + (->> pending-contact-requests + (filter #(= contact-id (:author %))) + (first)))) diff --git a/src/status_im/subs/activity_center_test.cljs b/src/status_im/subs/activity_center_test.cljs index 8f18321702..2b976d9578 100644 --- a/src/status_im/subs/activity_center_test.cljs +++ b/src/status_im/subs/activity_center_test.cljs @@ -86,3 +86,21 @@ (swap! rf-db/app-db assoc-in [:activity-center :unread-counts-by-type] {types/one-to-one-chat 1}) (swap! rf-db/app-db assoc-in [:activity-center :seen?] true) (is (= :unread-indicator/seen (rf/sub [sub-name]))))) + +(h/deftest-sub :activity-center/pending-contact-request-from-contact-id + [sub-name] + (testing "returns contact request data if it finds a matching contact-id" + (let [contact-id "0x01" + contact-request {:author contact-id + :message {:content {:text "Hey there"}}}] + (swap! rf-db/app-db assoc-in [:activity-center :contact-requests] [contact-request]) + (is (match? contact-request + (rf/sub [sub-name contact-id]))))) + + (testing "returns nil if it does not find a matching contact-id" + (let [contact-id "0x01" + contact-request {:author "0x02" + :message {:content {:text "Hey there"}}}] + (swap! rf-db/app-db assoc-in [:activity-center :contact-requests] [contact-request]) + (is (match? nil + (rf/sub [sub-name contact-id])))))) diff --git a/translations/en.json b/translations/en.json index 2ca00ee34b..ea9098d32a 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1666,6 +1666,7 @@ "remove-nickname-toast": "You have removed {{secondary-name}}'s nickname", "nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames you’ve added", "accept": "Accept", + "ignore": "Ignore", "group-invite": "Group invite", "group-invite-link": "Group invite link", "pending-invitations": "Pending membership requests", @@ -1986,6 +1987,7 @@ "accepted": "Accepted", "declined": "Declined", "contact-request-sent": "sent contact request", + "contact-request-review": "Review contact request", "contact-request-sent-toast": "{{name}} sent you a contact request", "contact-request-accepted-toast": "{{name}} accepted your contact request", "contact-request-outgoing": "You’re trying to connect with",