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
This commit is contained in:
parent
7065f4abd2
commit
ca9346a931
|
@ -10,7 +10,7 @@
|
||||||
:background-color (colors/theme-colors colors/neutral-10
|
:background-color (colors/theme-colors colors/neutral-10
|
||||||
colors/neutral-80-opa-80
|
colors/neutral-80-opa-80
|
||||||
theme)
|
theme)
|
||||||
:height 40
|
:min-height 40
|
||||||
:padding-horizontal 12
|
:padding-horizontal 12
|
||||||
:padding-vertical 9
|
:padding-vertical 9
|
||||||
:margin-top 4})
|
:margin-top 4})
|
||||||
|
|
|
@ -22,11 +22,12 @@
|
||||||
(defn- locked-input-internal
|
(defn- locked-input-internal
|
||||||
[{:keys [label icon container-style theme]} value]
|
[{:keys [label icon container-style theme]} value]
|
||||||
[rn/view {:style container-style}
|
[rn/view {:style container-style}
|
||||||
[text/text
|
(when label
|
||||||
{:size :paragraph-2
|
[text/text
|
||||||
:weight :medium
|
{:size :paragraph-2
|
||||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
:weight :medium
|
||||||
label]
|
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||||
|
label])
|
||||||
[info-box
|
[info-box
|
||||||
{:theme theme
|
{:theme theme
|
||||||
:icon icon
|
:icon icon
|
||||||
|
|
|
@ -44,3 +44,4 @@
|
||||||
:button-one-props {:disabled? (string/blank? message)
|
:button-one-props {:disabled? (string/blank? message)
|
||||||
:on-press on-message-submit}
|
:on-press on-message-submit}
|
||||||
:button-one-label (i18n/label :t/send-contact-request)}]]))
|
:button-one-label (i18n/label :t/send-contact-request)}]]))
|
||||||
|
|
||||||
|
|
|
@ -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})
|
|
@ -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)}]]]))
|
|
@ -8,8 +8,8 @@
|
||||||
:align-items :flex-start})
|
:align-items :flex-start})
|
||||||
|
|
||||||
(def button-wrapper
|
(def button-wrapper
|
||||||
{:padding-top 8
|
{:margin-top 8
|
||||||
:padding-bottom 16
|
:margin-bottom 16
|
||||||
:padding-horizontal 20})
|
:padding-horizontal 20})
|
||||||
|
|
||||||
(defn header-container
|
(defn header-container
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
[status-im.common.scalable-avatar.view :as avatar]
|
[status-im.common.scalable-avatar.view :as avatar]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.profile.contact.contact-request.view :as contact-request]
|
[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.contact.header.style :as style]
|
||||||
[status-im.contexts.profile.utils :as profile.utils]
|
[status-im.contexts.profile.utils :as profile.utils]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [scroll-y]}]
|
[{:keys [scroll-y]}]
|
||||||
(let [{:keys [public-key customization-color
|
(let [{:keys [public-key customization-color ens-name
|
||||||
emoji-hash bio contact-request-state]
|
emoji-hash bio contact-request-state]
|
||||||
:as profile} (rf/sub [:contacts/current-contact])
|
:as profile} (rf/sub [:contacts/current-contact])
|
||||||
customization-color (or customization-color :blue)
|
customization-color (or customization-color :blue)
|
||||||
|
@ -23,7 +24,13 @@
|
||||||
online? (rf/sub [:visibility-status-updates/online? public-key])
|
online? (rf/sub [:visibility-status-updates/online? public-key])
|
||||||
theme (quo.theme/use-theme-value)
|
theme (quo.theme/use-theme-value)
|
||||||
on-contact-request (rn/use-callback #(rf/dispatch [:show-bottom-sheet
|
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-container}
|
||||||
[rn/view {:style style/header-top-wrapper}
|
[rn/view {:style style/header-top-wrapper}
|
||||||
[rn/view {:style style/avatar-wrapper}
|
[rn/view {:style style/avatar-wrapper}
|
||||||
|
@ -49,10 +56,24 @@
|
||||||
(cond
|
(cond
|
||||||
(or (not contact-request-state)
|
(or (not contact-request-state)
|
||||||
(= contact-request-state constants/contact-request-state-none))
|
(= contact-request-state constants/contact-request-state-none))
|
||||||
[rn/view {:style style/button-wrapper}
|
[quo/button
|
||||||
[quo/button
|
{:container-style style/button-wrapper
|
||||||
{:on-press on-contact-request
|
:on-press on-contact-request
|
||||||
:icon-left :i/add-user}
|
:icon-left :i/add-user}
|
||||||
(i18n/label :t/send-contact-request)]]
|
(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)]))
|
:else nil)]))
|
||||||
|
|
|
@ -80,3 +80,11 @@
|
||||||
:<- [:activity-center]
|
:<- [:activity-center]
|
||||||
(fn [activity-center]
|
(fn [activity-center]
|
||||||
(:contact-requests 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))))
|
||||||
|
|
|
@ -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 :unread-counts-by-type] {types/one-to-one-chat 1})
|
||||||
(swap! rf-db/app-db assoc-in [:activity-center :seen?] true)
|
(swap! rf-db/app-db assoc-in [:activity-center :seen?] true)
|
||||||
(is (= :unread-indicator/seen (rf/sub [sub-name])))))
|
(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]))))))
|
||||||
|
|
|
@ -1666,6 +1666,7 @@
|
||||||
"remove-nickname-toast": "You have removed {{secondary-name}}'s nickname",
|
"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",
|
"nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames you’ve added",
|
||||||
"accept": "Accept",
|
"accept": "Accept",
|
||||||
|
"ignore": "Ignore",
|
||||||
"group-invite": "Group invite",
|
"group-invite": "Group invite",
|
||||||
"group-invite-link": "Group invite link",
|
"group-invite-link": "Group invite link",
|
||||||
"pending-invitations": "Pending membership requests",
|
"pending-invitations": "Pending membership requests",
|
||||||
|
@ -1986,6 +1987,7 @@
|
||||||
"accepted": "Accepted",
|
"accepted": "Accepted",
|
||||||
"declined": "Declined",
|
"declined": "Declined",
|
||||||
"contact-request-sent": "sent contact request",
|
"contact-request-sent": "sent contact request",
|
||||||
|
"contact-request-review": "Review contact request",
|
||||||
"contact-request-sent-toast": "{{name}} sent you a contact request",
|
"contact-request-sent-toast": "{{name}} sent you a contact request",
|
||||||
"contact-request-accepted-toast": "{{name}} accepted your contact request",
|
"contact-request-accepted-toast": "{{name}} accepted your contact request",
|
||||||
"contact-request-outgoing": "You’re trying to connect with",
|
"contact-request-outgoing": "You’re trying to connect with",
|
||||||
|
|
Loading…
Reference in New Issue