Outgoing contact requests (#14853)

* First thoughts/ideas

* Showing "Cancel contact request" button

* Fixes

* Restructuring, `retractContactRequest`

* Pending label

* Proper buttons for activity notifications

* New updates

* Returning back `activity-log` `items`

* Last changes in code

* Lint fix

* Lint fix (2)

* Style fixes

* Style fixes

* Code fixes

* Style fixes

* Fixes

1d9d7343...0082f7e9

* Footer update

* Toasts done

* Formatting fix

* Go version update

* Fixes for deletion

* status-go-version.json

* Lint fix

* Fixes

* Lint fix

* status-go version

* status-go version
This commit is contained in:
Alexander 2023-02-21 22:45:54 +01:00 committed by GitHub
parent 888bf12856
commit 1b33aa4988
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 448 additions and 302 deletions

View File

@ -33,25 +33,16 @@
:padding-vertical 8
:background-color colors/white-opa-5})
(def buttons-container
(def footer-container
{:margin-top 12
:flex-direction :row
:align-items :flex-start})
(def status
{:margin-top 12
:align-items :flex-start
:flex 1})
:flex-direction :row})
(defn title
[replying?]
{:color colors/white
:flex-shrink 1
:max-width (when-not replying? "60%")})
[]
{:color colors/white})
(def timestamp
{:text-transform :none
:flex-grow 1
:margin-left 8
:color colors/neutral-40})
@ -75,3 +66,8 @@
(def top-section-container
{:align-items :center
:flex-direction :row})
(def title-container
{:flex 1
:flex-direction :row
:align-items :center})

View File

@ -11,15 +11,8 @@
[reagent.core :as reagent]
[utils.i18n :as i18n]))
(def ^:private max-reply-length
280)
(defn- valid-reply?
[reply]
(<= (count reply) max-reply-length))
(defn- activity-reply-text-input
[reply-input on-update-reply]
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input]
[rn/view
[rn/view
{:style {:margin-top 16
@ -99,44 +92,12 @@
body]
body)])
(defn- activity-buttons
[button-1 button-2 replying? reply-input]
(let [size (if replying? 40 24)
common-style (when replying?
{:padding-vertical 9
:flex-grow 1
:flex-basis 0})]
[rn/view style/buttons-container
(when button-1
[button/button
(-> button-1
(assoc :size size)
(update :style merge common-style {:margin-right 8}))
(:label button-1)])
(when button-2
[button/button
(-> button-2
(assoc :size size)
(assoc :disabled (and replying? (not (valid-reply? @reply-input))))
(update :style merge common-style))
(:label button-2)])]))
(defn- activity-status
[status]
[rn/view
{:style style/status
:accessibility-label :activity-status}
[status-tags/status-tag
{:size :small
:label (:label status)
:status status}]])
(defn- activity-title
[title replying?]
[text/text
{:weight :semi-bold
:accessibility-label :activity-title
:style (style/title replying?)
:style (style/title)
:size (if replying? :heading-2 :paragraph-1)}
title])
@ -155,18 +116,42 @@
:style style/unread-dot-container}
[rn/view {:style style/unread-dot}]])
(defmulti footer-item-view (fn [item _ _] (:type item)))
(defmethod footer-item-view :button
[{:keys [label subtype disable-when] :as button} replying? reply-input]
(let [size (if replying? 40 24)
common-style (when replying?
{:padding-vertical 9
:flex-grow 1
:flex-basis 0})]
[button/button
(-> button
(assoc :size size)
(assoc :type subtype)
(assoc :disabled (and replying? (disable-when @reply-input)))
(update :style merge common-style {:margin-right 8}))
label]))
(defmethod footer-item-view :status
[{:keys [label subtype]} _ _]
[status-tags/status-tag
{:size :small
:label label
:status {:type subtype}}])
(defn- footer
[_]
[_ _]
(let [reply-input (reagent/atom "")]
(fn [{:keys [replying? on-update-reply status button-1 button-2]}]
(fn [{:keys [replying? items] :as props}]
[:<>
(when replying?
[activity-reply-text-input reply-input on-update-reply])
(cond (some? status)
[activity-status status]
(or button-1 button-2)
[activity-buttons button-1 button-2 replying? reply-input])])))
[activity-reply-text-input props reply-input])
(when items
[rn/view style/footer-container
(for [{:keys [key] :as item} items]
^{:key key}
[footer-item-view item replying? reply-input])])])))
(defn view
[{:keys [icon
@ -187,9 +172,10 @@
:flex 1}}
[rn/view
[rn/view {:style style/top-section-container}
[activity-title title replying?]
(when-not replying?
[activity-timestamp timestamp])
[rn/view {:style style/title-container}
[activity-title title replying?]
(when-not replying?
[activity-timestamp timestamp])]
(when (and unread? (not replying?))
[activity-unread-dot])]
(when context

View File

@ -10,6 +10,8 @@
(def ^:private themes
{:container {:dark {:background-color colors/white-opa-70}
:light {:background-color colors/neutral-80-opa-90}}
:title {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:text {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:icon {:dark {:color colors/neutral-100}
@ -51,7 +53,7 @@
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left middle right container-style override-theme]}]
[{:keys [left title text right container-style override-theme]}]
[rn/view {:style (merge {:padding-left 12 :padding-right 12} container-style)}
[rn/view
{:style (merge-theme-style :container
@ -66,16 +68,25 @@
override-theme)}
[rn/view {:style {:padding 2}} left]
[rn/view {:style {:padding 4 :flex 1}}
[text/text
{:size :paragraph-2
:weight :medium
:style (merge-theme-style :text {} override-theme)
:accessibility-label :toast-content}
middle]]
(when title
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (merge-theme-style :title {} override-theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (merge-theme-style :text {} override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
(defn toast
[{:keys [icon icon-color text action undo-duration undo-on-press container-style override-theme]}]
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme]}]
[toast-container
{:left (when icon
[icon/icon icon
@ -84,7 +95,8 @@
(get-in themes
[:icon (or override-theme (theme/get-theme))
:color]))}])
:middle text
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)

View File

@ -12,7 +12,7 @@
(def small-container-style
(merge default-container-style
{:padding-horizontal 8
:padding-vertical 3}))
:padding-vertical 1}))
(def large-container-style
(merge default-container-style
@ -56,8 +56,8 @@
[size theme label]
[base-tag
{:size size
:background-color colors/success-50-opa-10
:icon :verified
:background-color colors/success-50-opa-10
:border-color colors/success-50-opa-20
:label label
:text-color (if (= theme :light)
@ -77,18 +77,14 @@
colors/danger-60)}])
(defn- pending
[size theme label]
[size _ label]
[base-tag
{:size size
:icon :pending
:label label
:background-color (if (= theme :light)
colors/neutral-10
colors/neutral-80)
:border-color (if (= theme :light)
colors/neutral-20
colors/neutral-70)
:text-color colors/neutral-50}])
:background-color colors/white-opa-5
:border-color colors/white-opa-5
:text-color colors/white-opa-70}])
(defn status-tag
[{:keys [status size override-theme label]}]

View File

@ -8,19 +8,6 @@
[status-im2.navigation.events :as navigation]
[taoensso.timbre :as log]))
(rf/defn load-contacts
{:events [::contacts-loaded]}
[{:keys [db] :as cofx} all-contacts]
(let [contacts-list (map #(vector (:public-key %)
(if (empty? (:address %))
(dissoc % :address)
%))
all-contacts)
contacts (into {} contacts-list)]
{:db (cond-> (-> db
(update :contacts/contacts #(merge contacts %))
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts))))}))
(defn build-contact
[{{:keys [multiaccount]
:contacts/keys [contacts]}
@ -66,7 +53,7 @@
(rf/defn add-contact
"Add a contact and set pending to false"
{:events [:contact.ui/add-to-contact-pressed]}
{:events [:contact.ui/add-contact-pressed]}
[{:keys [db] :as cofx} public-key nickname ens-name]
(when (not= (get-in db [:multiaccount :public-key]) public-key)
(contacts-store/add
@ -87,26 +74,10 @@
(assoc-in [:contacts/contacts public-key :contact-request-state]
constants/contact-request-state-none))
:json-rpc/call [{:method "wakuext_retractContactRequest"
:params [{:contactId public-key}]
:params [{:id public-key}]
:on-success #(log/debug "contact removed successfully")}]
:dispatch [:chat/offload-messages constants/timeline-chat-id]})
(rf/defn accept-contact-request
{:events [:contact-requests.ui/accept-request]}
[{:keys [db]} id]
{:json-rpc/call [{:method "wakuext_acceptContactRequest"
:params [{:id id}]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
(rf/defn decline-contact-request
{:events [:contact-requests.ui/decline-request]}
[{:keys [db]} id]
{:json-rpc/call [{:method "wakuext_dismissContactRequest"
:params [{:id id}]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
(rf/defn initialize-contacts
[cofx]
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))

View File

@ -4,7 +4,6 @@
[re-frame.core :as re-frame]
[status-im.async-storage.core :as async-storage]
[status-im.communities.core :as communities]
[status-im.contact.core :as contact]
[status-im.data-store.chats :as data-store.chats]
[status-im.data-store.invitations :as data-store.invitations]
[status-im.data-store.settings :as data-store.settings]
@ -41,6 +40,7 @@
[status-im2.common.json-rpc.events :as json-rpc]
[status-im2.contexts.activity-center.events :as activity-center]
[status-im2.contexts.chat.messages.link-preview.events :as link-preview]
[status-im2.contexts.contacts.events :as contacts]
[status-im2.navigation.events :as navigation]
[status-im2.common.log :as logging]
[taoensso.timbre :as log]
@ -468,7 +468,7 @@
(transport/start-messenger)
(initialize-transactions-management-enabled)
(check-network-version network-id)
(contact/initialize-contacts)
(contacts/initialize-contacts)
(initialize-browser)
(mobile-network/on-network-status-change)
(get-group-chat-invitations)

View File

@ -67,13 +67,13 @@
(models.message/receive-many cofx response-js)
(seq activity-notifications)
(do
(let [notifications (->> activity-notifications
types/js->clj
(map data-store.activities/<-rpc))]
(js-delete response-js "activityCenterNotifications")
(rf/merge cofx
(->> activity-notifications
types/js->clj
(map data-store.activities/<-rpc)
activity-center/notifications-reconcile)
(activity-center/notifications-reconcile notifications)
(activity-center/show-toasts notifications)
(process-next response-js sync-handler)))
(seq installations)

View File

@ -35,7 +35,7 @@
:disabled blocked?
:accessibility-label :add-to-contacts-button
:action (when-not blocked?
#(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key
#(re-frame/dispatch [:contact.ui/add-contact-pressed public-key
nil ens-name]))}])
[{:label (i18n/label (if (or muted? blocked?) :t/unmute :t/mute))
:icon :main-icons/notification

View File

@ -3,8 +3,12 @@
[status-im.data-store.chats :as data-store.chats]
[status-im2.contexts.activity-center.notification-types :as types]
[status-im2.contexts.chat.events :as chat.events]
[status-im2.common.toasts.events :as toasts]
status-im2.contexts.activity-center.notification.contact-requests.events
[taoensso.timbre :as log]
[utils.re-frame :as rf]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[status-im2.constants :as constants]))
(def defaults
@ -93,6 +97,38 @@
new-notifications)
:dispatch [:activity-center.notifications/fetch-unread-count]}))
(rf/defn show-toasts
{:events [:activity-center.notifications/show-toasts]}
[{:keys [db]} new-notifications]
(let [my-public-key (get-in db [:multiaccount :public-key])]
(reduce (fn [cofx {:keys [author type accepted dismissed message name] :as x}]
(cond
(and (not= author my-public-key)
(= type types/contact-request)
(not accepted)
(not dismissed))
(toasts/upsert cofx
{:icon :placeholder
:icon-color colors/primary-50-opa-40
:title (i18n/label :t/contact-request-sent-toast
{:name name})
:text (get-in message [:content :text])})
(and (= author my-public-key) ;; we show it for user who sent the request
(= type types/contact-request)
accepted
(not dismissed))
(toasts/upsert cofx
{:icon :placeholder
:icon-color colors/primary-50-opa-40
:title (i18n/label :t/contact-request-accepted-toast
{:name (:alias message)})})
:else
cofx))
{:db db}
new-notifications)))
(rf/defn notifications-reconcile-from-response
{:events [:activity-center/reconcile-notifications-from-response]}
[cofx response]

View File

@ -14,38 +14,48 @@
community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])]
[quo/activity-log
(merge
{:title (i18n/label :t/join-request)
:icon :i/add-user
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
(i18n/label :t/wants-to-join)
[quo/context-tag
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text}
{:uri community-image} community-name]]
:status (case membership-status
constants/activity-center-membership-status-accepted
{:type :positive :label (i18n/label :t/accepted)}
constants/activity-center-membership-status-declined
{:type :negative :label (i18n/label :t/declined)}
nil)}
(case membership-status
constants/activity-center-membership-status-pending
{:button-1 {:label (i18n/label :t/decline)
:accessibility-label :decline-join-request
:type :danger
:on-press (fn []
(rf/dispatch [:communities.ui/decline-request-to-join-pressed
community-id id]))}
:button-2 {:label (i18n/label :t/accept)
:accessibility-label :accept-join-request
:type :positive
:on-press (fn []
(rf/dispatch [:communities.ui/accept-request-to-join-pressed
community-id id]))}}
nil))]))
{:title (i18n/label :t/join-request)
:icon :i/add-user
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
(i18n/label :t/wants-to-join)
[quo/context-tag
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text}
{:uri community-image} community-name]]
:items (case membership-status
constants/activity-center-membership-status-accepted
[{:type :status
:subtype :positive
:key :status-accepted
:label (i18n/label :t/accepted)}]
constants/activity-center-membership-status-declined
[{:type :status
:subtype :negative
:key :status-declined
:label (i18n/label :t/declined)}]
constants/activity-center-membership-status-pending
[{:type :button
:subtype :danger
:key :button-decline
:label (i18n/label :t/decline)
:accessibility-label :decline-join-request
:on-press (fn []
(rf/dispatch [:communities.ui/decline-request-to-join-pressed
community-id id]))}
{:type :button
:subtype :positive
:key :button-accept
:label (i18n/label :t/accept)
:accessibility-label :accept-join-request
:on-press (fn []
(rf/dispatch [:communities.ui/accept-request-to-join-pressed
community-id id]))}]
nil)}]))

View File

@ -6,8 +6,8 @@
[utils.re-frame :as rf]))
(defn user-avatar-tag
[user]
(let [contact (rf/sub [:contacts/contact-by-identity user])]
[user-id]
(let [contact (rf/sub [:contacts/contact-by-identity user-id])]
[quo/user-avatar-tag
{:color :purple
:override-theme :dark

View File

@ -1,59 +0,0 @@
(ns status-im2.contexts.activity-center.notification.contact-request.view
(:require [quo2.core :as quo]
[react-native.core :as rn]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[{:keys [id author message last-message] :as notification}]
(let [message (or message last-message)
pressable (case (:contact-request-state message)
constants/contact-request-message-state-accepted
;; NOTE(2022-09-21): We need to dispatch to
;; `:chat.ui/start-chat` instead of
;; `:chat/navigate-to-chat`, otherwise the chat screen
;; looks completely broken if it has never been opened
;; before for the accepted contact.
[rn/touchable-opacity
{:on-press (fn []
(rf/dispatch [:hide-popover])
(rf/dispatch [:chat.ui/start-chat author]))}]
[:<>])]
(conj
pressable
[rn/view
[quo/activity-log
(merge
{:title (i18n/label :t/contact-request)
:icon :main-icons2/add-user
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
:context [[common/user-avatar-tag author]
(i18n/label :t/contact-request-sent)]
:message {:body (get-in message [:content :text])}
:status (case (:contact-request-state message)
constants/contact-request-message-state-accepted
{:type :positive :label (i18n/label :t/accepted)}
constants/contact-request-message-state-declined
{:type :negative :label (i18n/label :t/declined)}
nil)}
(case (:contact-request-state message)
constants/contact-request-message-state-pending
{:button-1 {:label (i18n/label :t/decline)
:accessibility-label :decline-contact-request
:type :danger
:on-press (fn []
(rf/dispatch [:contact-requests.ui/decline-request id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}
:button-2 {:label (i18n/label :t/accept)
:accessibility-label :accept-contact-request
:type :positive
:on-press (fn []
(rf/dispatch [:contact-requests.ui/accept-request id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}}
nil))]])))

View File

@ -0,0 +1,26 @@
(ns status-im2.contexts.activity-center.notification.contact-requests.events
(:require [utils.re-frame :as rf]))
(rf/defn accept-contact-request
{:events [:activity-center.contact-requests/accept-request]}
[{:keys [db]} id]
{:json-rpc/call [{:method "wakuext_acceptContactRequest"
:params [{:id id}]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})
(rf/defn decline-contact-request
{:events [:activity-center.contact-requests/decline-request]}
[{:keys [db]} id]
{:json-rpc/call [{:method "wakuext_declineContactRequest"
:params [{:id id}]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})
(rf/defn cancel-outgoing-contact-request
{:events [:activity-center.contact-requests/cancel-outgoing-request]}
[{:keys [db]} id]
{:json-rpc/call [{:method "wakuext_cancelOutgoingContactRequest"
:params [{:id id}]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})

View File

@ -0,0 +1,119 @@
(ns status-im2.contexts.activity-center.notification.contact-requests.view
(:require [quo2.core :as quo]
[react-native.core :as rn]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn outgoing-contact-request-view
[{:keys [id chat-id message last-message] :as notification}]
(let [{:keys [contact-request-state] :as message} (or message last-message)]
(if (= contact-request-state constants/contact-request-message-state-accepted)
[quo/activity-log
{:title (i18n/label :t/contact-request-was-accepted)
:icon :i/add-user
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
:context [[common/user-avatar-tag chat-id]
(i18n/label :t/contact-request-is-now-a-contact)]}
:message {:body (get-in message [:content :text])}
:items []]
[quo/activity-log
{:title (i18n/label :t/contact-request)
:icon :i/add-user
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
:context [(i18n/label :t/contact-request-outgoing)
[common/user-avatar-tag chat-id]]
:message {:body (get-in message [:content :text])}
:items (case contact-request-state
constants/contact-request-state-mutual
[{:type :button
:subtype :danger
:key :button-cancel
:label (i18n/label :t/cancel)
:accessibility-label :cancel-contact-request
:on-press (fn []
(rf/dispatch
[:activity-center.contact-requests/cancel-outgoing-request
(:from message)])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}
{:type :status
:subtype :pending
:key :status-pending
:label (i18n/label :t/pending)}]
constants/contact-request-message-state-declined
[{:type :status
:subtype :pending
:key :status-pending
:label (i18n/label :t/pending)}]
nil)}])))
(defn incoming-contact-request-view
[{:keys [id author message last-message] :as notification}]
(let [message (or message last-message)]
[quo/activity-log
{:title (i18n/label :t/contact-request)
:icon :i/add-user
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
:context [[common/user-avatar-tag author]
(i18n/label :t/contact-request-sent)]
:message {:body (get-in message [:content :text])}
:items
(case (:contact-request-state message)
constants/contact-request-message-state-accepted
[{:type :status
:subtype :positive
:key :status-accepted
:label (i18n/label :t/accepted)}]
constants/contact-request-message-state-declined
[{:type :status
:subtype :negative
:key :status-declined
:label (i18n/label :t/declined)}]
constants/contact-request-state-mutual
[{:type :button
:subtype :danger
:key :button-decline
:label (i18n/label :t/decline)
:accessibility-label :decline-contact-request
:on-press (fn []
(rf/dispatch [:activity-center.contact-requests/decline-request id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}
{:type :button
:subtype :positive
:key :button-accept
:label (i18n/label :t/accept)
:accessibility-label :accept-contact-request
:on-press (fn []
(rf/dispatch [:activity-center.contact-requests/accept-request id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}]
nil)}]))
(defn view
[{:keys [author message last-message] :as notification}]
(let [{:keys [public-key]} (rf/sub [:multiaccount/contact])
{:keys [contact-request-state]} (or message last-message)]
(cond
(= public-key author)
[outgoing-contact-request-view notification]
(= contact-request-state constants/contact-request-message-state-accepted)
[rn/touchable-opacity
{:on-press (fn []
(rf/dispatch [:hide-popover])
(rf/dispatch [:chat.ui/start-chat {:public-key author}]))}
[incoming-contact-request-view notification]]
:else
[incoming-contact-request-view notification])))

View File

@ -50,6 +50,13 @@
(= contact-verification-status constants/contact-verification-status-declined)
{:type :negative :label (i18n/label :t/declined)})))
(def ^:private max-reply-length
280)
(defn- valid-reply?
[reply]
(<= (count reply) max-reply-length))
(defn view
[_ _]
(let [reply (atom "")]
@ -62,57 +69,72 @@
(= contact-verification-status constants/contact-verification-status-declined))
[quo/activity-log
(merge
{:title (i18n/label :t/identity-verification-request)
:icon :i/friend
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
{:title (i18n/label :t/identity-verification-request)
:icon :i/friend
:timestamp (datetime/timestamp->relative (:timestamp notification))
:unread? (not (:read notification))
:on-update-reply #(reset! reply %)
:replying? replying?
:context (context-tags challenger? notification)
:message (activity-message challenger? notification)
:status (activity-status challenger? contact-verification-status)}
(if challenger?
(when (= contact-verification-status constants/contact-verification-status-accepted)
{:button-1 {:label (i18n/label :t/untrustworthy)
:accessibility-label :mark-contact-verification-as-untrustworthy
:type :danger
:on-press (fn []
(rf/dispatch
[:activity-center.contact-verification/mark-as-untrustworthy
id])
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}
:button-2 {:label (i18n/label :t/accept)
:accessibility-label :mark-contact-verification-as-trusted
:type :positive
:on-press (fn []
(rf/dispatch
[:activity-center.contact-verification/mark-as-trusted id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}})
(when (= contact-verification-status constants/contact-verification-status-pending)
{:button-1 {:label (i18n/label :t/decline)
:accessibility-label :decline-contact-verification
:type :danger
:on-press (fn []
(hide-bottom-sheet-and-dispatch
[:activity-center.contact-verification/decline id])
(rf/dispatch
[:activity-center.notifications/mark-as-read id]))}
:button-2 (if replying?
{:label (i18n/label :t/send-reply)
:accessibility-label :reply-to-contact-verification
:type :primary
:on-press (fn []
(hide-bottom-sheet-and-dispatch
[:activity-center.contact-verification/reply id
@reply])
(rf/dispatch
[:activity-center.notifications/mark-as-read id]))}
{:label (i18n/label :t/message-reply)
:accessibility-label :send-reply-to-contact-verification
:type :primary
:on-press (fn []
(rf/dispatch [:bottom-sheet/show-sheet
{:content view}
{:notification notification
:replying? true}]))})})))])))))
:replying? replying?
:max-reply-length max-reply-length
:valid-reply? valid-reply?
:context (context-tags challenger? notification)
:message (activity-message challenger? notification)
:status (activity-status challenger? contact-verification-status)
:items
(if challenger?
(when (= contact-verification-status constants/contact-verification-status-accepted)
[{:type :button
:subtype :danger
:key :button-mark-as-untrustworthy
:label (i18n/label :t/untrustworthy)
:accessibility-label :mark-contact-verification-as-untrustworthy
:on-press (fn []
(rf/dispatch
[:activity-center.contact-verification/mark-as-untrustworthy
id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}
{:type :button
:subtype :positive
:key :button-accept
:label (i18n/label :t/accept)
:accessibility-label :mark-contact-verification-as-trusted
:on-press (fn []
(rf/dispatch
[:activity-center.contact-verification/mark-as-trusted id])
(rf/dispatch [:activity-center.notifications/mark-as-read
id]))}])
(when (= contact-verification-status constants/contact-verification-status-pending)
[{:type :button
:subtype :danger
:key :button-decline
:label (i18n/label :t/decline)
:accessibility-label :decline-contact-verification
:on-press (fn []
(hide-bottom-sheet-and-dispatch
[:activity-center.contact-verification/decline id])
(rf/dispatch
[:activity-center.notifications/mark-as-read id]))}
(if replying?
{:type :button
:subtype :primary
:key :button-reply
:label (i18n/label :t/send-reply)
:accessibility-label :reply-to-contact-verification
:disable-when #(not (valid-reply? %))
:on-press (fn []
(hide-bottom-sheet-and-dispatch
[:activity-center.contact-verification/reply id
@reply])
(rf/dispatch
[:activity-center.notifications/mark-as-read id]))}
{:type :button
:subtype :primary
:key :button-send-reply
:label (i18n/label :t/message-reply)
:accessibility-label :send-reply-to-contact-verification
:on-press (fn []
(rf/dispatch [:bottom-sheet/show-sheet
{:content view}
{:notification notification
:replying? true}]))})]))})])))))

View File

@ -20,22 +20,26 @@
[{:keys [id accepted author read timestamp chat-name chat-id]}]
[pressable {:accepted accepted :chat-id chat-id}
[quo/activity-log
(merge
{:title (i18n/label :t/added-to-group-chat)
:icon :i/add-user
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
(i18n/label :t/added-you-to)
[quo/group-avatar-tag chat-name
{:size :small
:color :purple}]]}
(when-not accepted
{:button-2 {:label (i18n/label :t/accept)
:accessibility-label :accept-group-chat-invitation
:type :positive
:on-press #(rf/dispatch [:activity-center.notifications/accept id])}
:button-1 {:label (i18n/label :t/decline)
:accessibility-label :decline-group-chat-invitation
:type :danger
:on-press #(rf/dispatch [:activity-center.notifications/dismiss id])}}))]])
{:title (i18n/label :t/added-to-group-chat)
:icon :i/add-user
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
(i18n/label :t/added-you-to)
[quo/group-avatar-tag chat-name
{:size :small
:color :purple}]]
:items (when-not accepted
[{:type :button
:subtype :positive
:key :button-accept
:label (i18n/label :t/accept)
:accessibility-label :accept-group-chat-invitation
:on-press #(rf/dispatch [:activity-center.notifications/accept id])}
{:type :button
:subtype :danger
:key :button-decline
:label (i18n/label :t/decline)
:accessibility-label :decline-group-chat-invitation
:on-press #(rf/dispatch [:activity-center.notifications/dismiss
id])}])}]])

View File

@ -6,7 +6,7 @@
[react-native.safe-area :as safe-area]
[status-im2.contexts.activity-center.notification-types :as types]
[status-im2.contexts.activity-center.notification.admin.view :as admin]
[status-im2.contexts.activity-center.notification.contact-request.view :as contact-request]
[status-im2.contexts.activity-center.notification.contact-requests.view :as contact-requests]
[status-im2.contexts.activity-center.notification.contact-verification.view :as
contact-verification]
[status-im2.contexts.activity-center.notification.membership.view :as membership]
@ -173,15 +173,15 @@
(= type types/contact-verification)
[contact-verification/view notification {}]
(= type types/contact-request)
[contact-request/view notification]
(= type types/mention)
[mentions/view notification]
(= type types/reply)
[reply/view notification]
(= type types/contact-request)
[contact-requests/view notification]
(= type types/admin)
[admin/view notification]

View File

@ -0,0 +1,22 @@
(ns status-im2.contexts.contacts.events
(:require
[utils.re-frame :as rf]
[status-im.contact.db :as contact.db]
[status-im.data-store.contacts :as contacts-store]))
(rf/defn load-contacts
{:events [:contacts/contacts-loaded]}
[{:keys [db] :as cofx} all-contacts]
(let [contacts-list (map #(vector (:public-key %)
(if (empty? (:address %))
(dissoc % :address)
%))
all-contacts)
contacts (into {} contacts-list)]
{:db (cond-> (-> db
(update :contacts/contacts #(merge contacts %))
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts))))}))
(rf/defn initialize-contacts
[cofx]
(contacts-store/fetch-contacts-rpc cofx #(rf/dispatch [:contacts/contacts-loaded %])))

View File

@ -1,9 +1,9 @@
{
"_comment": "THIS SHOULD NOT BE EDITED BY HAND.",
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.131.10",
"commit-sha1": "8ff91ba0024f5ecf05d29904288537b236329f51",
"src-sha256": "1m3an4fhzhh0vq8bb24xfjwdysfdd9qrz08a3gfz3ddahkh41jad"
"_comment": "THIS SHOULD NOT BE EDITED BY HAND.",
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.131.11",
"commit-sha1": "27730057d0914b0c53c3e87e1442def7edc76998",
"src-sha256": "1c3q6nbki2fcs23jarkk673kr65frdfqbb3hsxp05mh8ybv1wgjw"
}

View File

@ -1825,12 +1825,17 @@
"new-ui": "New UI",
"send-contact-request-message": "To start a chat you need to become contacts",
"contact-request": "Contact request",
"contact-request-was-accepted": "Contact request accepted",
"contact-request-is-now-a-contact": "is now a contact",
"contact-requests": "Contact requests",
"say-hi": "Say hi",
"opened": "Opened",
"accepted": "Accepted",
"declined": "Declined",
"contact-request-sent": "sent contact request",
"contact-request-sent-toast": "{{name}} sent you a contact request",
"contact-request-accepted-toast": "{{name}} accepted your contact request",
"contact-request-outgoing": "Youre trying to connect with",
"contact-request-header": "👋 Contact requests",
"contact-request-declined": "Declined ⓧ",
"contact-request-accepted": "Accepted ✓",