mirror of
https://github.com/status-im/status-react.git
synced 2025-01-09 10:42:53 +00:00
Swipe gestures for Activity Center notifications with CTA (#15284)
Implements swipe actions for notifications with call to action (e.g. pending contact requests, unverified identity verifications, etc). Fixes https://github.com/status-im/status-mobile/issues/15118 According to the Design team, the goal is to deliver a consistent experience to users, so whenever the user sees a notification with buttons, the same actions can be taken via the swipe buttons. Note: swipe buttons are using placeholder icons while the Design team works out which ones to use Additionally, a bunch of fixes: - Fix: outgoing pending contact requests were not being removed from the UI when cancelled. - Fix: Membership tab not showing unread indicator. - Fix: dismissed membership notification not marked as read. - Fix: dismissed membership notification was displaying decline/accept buttons. Regression came from changes in status-go related to soft deletion of notifications. - Fix: incorrect check for the pending state of a contact request. - Fixed lots of bugs for identity verification notifications, as it was completely broken. Unfortunately, somebody made lots of changes without actually testing the flows. - Add basic error handling and log if accepting, declining or canceling contact requests fail. The demo shows an identity verification with swipe actions to reply or decline. [identity-verification-swipe-to-reply.webm](https://user-images.githubusercontent.com/46027/223565755-b2ca3f68-12e2-4e1e-9e52-edd52cfcc971.webm) Out of scope: The old quo input is still in use in the identity verification notification. This will eventually be solved by issue https://github.com/status-im/status-mobile/issues/14364 ### Steps to test Notifications with one or more buttons (actions) are affected by this change, because now the user can also swipe left/right to act on them. - Membership notifications: private group chat. The following PR explains how to generate them https://github.com/status-im/status-mobile/pull/14785 - Contact requests, and community gated requests to join (Admin tab). - Identity verifications. I believe the only way to test identity verification flows at the moment is to use the Desktop app, since initiating the challenge is not implemented in Mobile yet. - Mentions and replies don't have new swipe buttons because they don't have call to action buttons throughout their lifecycle. Steps to test identity verification flows: #### Identity verification flow 1 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` declines and the status `Declined` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe delete the notification. - `A` should not receive any notification after `A` declined. #### Identity verification flow 2 - `A` and `B` are mutual contacts. - `A` sends a verification request to `B`. - `A` should not see any notification yet. - `B` should receive an identity verification notification. `B` can either decline or reply. - `B` press `Reply` and a bottom sheet is displayed with a text input. - `B` sends the reply/answer message and the status `Replied` is shown instead of buttons. - `B` can now either swipe to toggle read/unread or swipe to delete the notification. - `A` should receive a notification with the reply from `B`. - `A` can either mark the answer as untrustworthy or accept it (trust it) via the normal buttons, as well as via the swipe left/right buttons. - If `A` accepts the answer, then the status `Confirmed` is shown instead of buttons. On the other hand, if `A` marks as untrustworthy, then the status `Untrustworthy` is shown instead of buttons. - `B` should receive no further notifications due to `A`s actions. - `A` can now either swipe to toggle read/unread or swipe delete the notification.
This commit is contained in:
parent
e98ce54830
commit
9473d3f40c
@ -37,7 +37,7 @@
|
|||||||
(when on-update-reply
|
(when on-update-reply
|
||||||
(on-update-reply %)))
|
(on-update-reply %)))
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
:auto-focus true
|
:auto-focus false
|
||||||
:accessibility-label :identity-verification-reply-text-input
|
:accessibility-label :identity-verification-reply-text-input
|
||||||
:placeholder (i18n/label :t/type-something)
|
:placeholder (i18n/label :t/type-something)
|
||||||
:return-key-type :none
|
:return-key-type :none
|
||||||
@ -129,7 +129,7 @@
|
|||||||
(-> button
|
(-> button
|
||||||
(assoc :size size)
|
(assoc :size size)
|
||||||
(assoc :type subtype)
|
(assoc :type subtype)
|
||||||
(assoc :disabled (and replying? (disable-when @reply-input)))
|
(assoc :disabled (and replying? disable-when (disable-when @reply-input)))
|
||||||
(update :style merge common-style {:margin-right 8}))
|
(update :style merge common-style {:margin-right 8}))
|
||||||
label]))
|
label]))
|
||||||
|
|
||||||
@ -142,7 +142,7 @@
|
|||||||
:blur? blur?}])
|
:blur? blur?}])
|
||||||
|
|
||||||
(defn- footer
|
(defn- footer
|
||||||
[_ _]
|
[_]
|
||||||
(let [reply-input (reagent/atom "")]
|
(let [reply-input (reagent/atom "")]
|
||||||
(fn [{:keys [replying? items] :as props}]
|
(fn [{:keys [replying? items] :as props}]
|
||||||
[:<>
|
[:<>
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
[status-im.wallet.core :as wallet]
|
[status-im.wallet.core :as wallet]
|
||||||
status-im.wallet.custom-tokens.core
|
status-im.wallet.custom-tokens.core
|
||||||
status-im2.contexts.activity-center.events
|
status-im2.contexts.activity-center.events
|
||||||
|
status-im2.contexts.activity-center.notification.contact-requests.events
|
||||||
status-im2.contexts.shell.events
|
status-im2.contexts.shell.events
|
||||||
status-im.chat.models.gaps
|
status-im.chat.models.gaps
|
||||||
[status-im2.navigation.events :as navigation]))
|
[status-im2.navigation.events :as navigation]))
|
||||||
|
@ -177,7 +177,7 @@
|
|||||||
(reset! expanded? true))
|
(reset! expanded? true))
|
||||||
(and @keyboard-was-shown? (not keyboard-shown))
|
(and @keyboard-was-shown? (not keyboard-shown))
|
||||||
(reset! expanded? false))))
|
(reset! expanded? false))))
|
||||||
[@show-bottom-sheet? @keyboard-was-shown?])
|
[@show-bottom-sheet? @keyboard-was-shown? keyboard-shown])
|
||||||
(react/effect! #(do
|
(react/effect! #(do
|
||||||
(when-not @gesture-running?
|
(when-not @gesture-running?
|
||||||
(cond
|
(cond
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
[status-im2.common.toasts.events :as toasts]
|
[status-im2.common.toasts.events :as toasts]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
[status-im2.contexts.activity-center.notification-types :as types]
|
[status-im2.contexts.activity-center.notification-types :as types]
|
||||||
status-im2.contexts.activity-center.notification.contact-requests.events
|
|
||||||
[status-im2.contexts.chat.events :as chat.events]
|
[status-im2.contexts.chat.events :as chat.events]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.collection :as collection]
|
[utils.collection :as collection]
|
||||||
@ -43,6 +42,12 @@
|
|||||||
(log/warn (str "Failed to " action)
|
(log/warn (str "Failed to " action)
|
||||||
{:notification-id notification-id :error error}))
|
{:notification-id notification-id :error error}))
|
||||||
|
|
||||||
|
(defn get-notification
|
||||||
|
[db notification-id]
|
||||||
|
(->> (get-in db [:activity-center :notifications])
|
||||||
|
(filter #(= notification-id (:id %)))
|
||||||
|
first))
|
||||||
|
|
||||||
;;;; Notification reconciliation
|
;;;; Notification reconciliation
|
||||||
|
|
||||||
(defn- update-notifications
|
(defn- update-notifications
|
||||||
@ -94,12 +99,6 @@
|
|||||||
|
|
||||||
;;;; Status changes (read/dismissed/deleted)
|
;;;; Status changes (read/dismissed/deleted)
|
||||||
|
|
||||||
(defn- get-notification
|
|
||||||
[db notification-id]
|
|
||||||
(->> (get-in db [:activity-center :notifications])
|
|
||||||
(filter #(= notification-id (:id %)))
|
|
||||||
first))
|
|
||||||
|
|
||||||
(rf/defn mark-as-read
|
(rf/defn mark-as-read
|
||||||
{:events [:activity-center.notifications/mark-as-read]}
|
{:events [:activity-center.notifications/mark-as-read]}
|
||||||
[{:keys [db]} notification-id]
|
[{:keys [db]} notification-id]
|
||||||
@ -235,7 +234,7 @@
|
|||||||
{:events [:activity-center.notifications/dismiss-success]}
|
{:events [:activity-center.notifications/dismiss-success]}
|
||||||
[{:keys [db] :as cofx} notification-id]
|
[{:keys [db] :as cofx} notification-id]
|
||||||
(let [notification (get-notification db notification-id)]
|
(let [notification (get-notification db notification-id)]
|
||||||
(notifications-reconcile cofx [(assoc notification :dismissed true)])))
|
(notifications-reconcile cofx [(assoc notification :read true :dismissed true)])))
|
||||||
|
|
||||||
(rf/defn delete-notification
|
(rf/defn delete-notification
|
||||||
{:events [:activity-center.notifications/delete]}
|
{:events [:activity-center.notifications/delete]}
|
||||||
|
@ -137,15 +137,16 @@
|
|||||||
:action :notification/accept})))
|
:action :notification/accept})))
|
||||||
|
|
||||||
(deftest notification-dismissal-test
|
(deftest notification-dismissal-test
|
||||||
(testing "dismisses notification, but keep it in the app db"
|
(testing "dismisses & mark notification as read, and keep it in the app db"
|
||||||
(h/run-test-sync
|
(h/run-test-sync
|
||||||
(setup)
|
(setup)
|
||||||
(let [notif-1 {:id "0x1" :type types/private-group-chat}
|
(let [notif-1 {:id "0x1" :type types/private-group-chat}
|
||||||
notif-2 {:id "0x2" :type types/admin}
|
notif-2 {:id "0x2" :type types/admin}
|
||||||
dismissed-notif-1 (assoc notif-1 :dismissed true)]
|
dismissed-notif-1 (assoc notif-1 :dismissed true :read true)]
|
||||||
(h/stub-fx-with-callbacks :json-rpc/call :on-success (constantly notif-2))
|
(h/stub-fx-with-callbacks :json-rpc/call :on-success (constantly notif-2))
|
||||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||||
[notif-2 notif-1]])
|
{:filter {:type types/no-type :status :all}
|
||||||
|
:notifications [notif-2 notif-1]}])
|
||||||
|
|
||||||
(rf/dispatch [:activity-center.notifications/dismiss (:id notif-1)])
|
(rf/dispatch [:activity-center.notifications/dismiss (:id notif-1)])
|
||||||
|
|
||||||
@ -520,7 +521,7 @@
|
|||||||
:type types/mention}]
|
:type types/mention}]
|
||||||
(get-in (h/db) [:activity-center :notifications]))))))
|
(get-in (h/db) [:activity-center :notifications]))))))
|
||||||
|
|
||||||
(testing "resets loading flag after an error"
|
(testing "resets loading state after error"
|
||||||
(h/run-test-sync
|
(h/run-test-sync
|
||||||
(setup)
|
(setup)
|
||||||
(let [spy-queue (atom [])]
|
(let [spy-queue (atom [])]
|
||||||
|
@ -2,79 +2,111 @@
|
|||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
[status-im2.contexts.activity-center.notification.common.style :as style]
|
[status-im2.contexts.activity-center.notification.common.style :as common-style]
|
||||||
[status-im2.contexts.activity-center.notification.common.view :as common]
|
[status-im2.contexts.activity-center.notification.common.view :as common]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn swipeable
|
(defn- swipe-button-accept
|
||||||
[{:keys [height active-swipeable notification]} child]
|
[{:keys [style]} _]
|
||||||
(if (#{constants/activity-center-membership-status-accepted
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-success-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/accept)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-decline
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/decline)}])
|
||||||
|
|
||||||
|
(defn- swipeable
|
||||||
|
[{:keys [active-swipeable notification extra-fn]} child]
|
||||||
|
(let [{:keys [community-id id membership-status]} notification]
|
||||||
|
(cond
|
||||||
|
(#{constants/activity-center-membership-status-accepted
|
||||||
constants/activity-center-membership-status-declined}
|
constants/activity-center-membership-status-declined}
|
||||||
(:membership-status notification))
|
membership-status)
|
||||||
[common/swipeable
|
[common/swipeable
|
||||||
{:left-button common/left-swipe-button
|
{:left-button common/swipe-button-read-or-unread
|
||||||
:left-on-press common/left-swipe-on-press
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
:right-button common/right-swipe-button
|
:right-button common/swipe-button-delete
|
||||||
:right-on-press common/right-swipe-on-press
|
:right-on-press common/swipe-on-press-delete
|
||||||
:active-swipeable active-swipeable
|
:active-swipeable active-swipeable
|
||||||
:extra-fn (fn [] {:height @height :notification notification})}
|
:extra-fn extra-fn}
|
||||||
child]
|
child]
|
||||||
child))
|
|
||||||
|
(= membership-status constants/activity-center-membership-status-pending)
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button swipe-button-accept
|
||||||
|
:left-on-press #(rf/dispatch [:communities.ui/accept-request-to-join-pressed community-id id])
|
||||||
|
:right-button swipe-button-decline
|
||||||
|
:right-on-press #(rf/dispatch [:communities.ui/decline-request-to-join-pressed community-id
|
||||||
|
id])
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
|
||||||
|
:else
|
||||||
|
child)))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [author community-id id membership-status read timestamp]}
|
[{:keys [notification set-swipeable-height] :as props}]
|
||||||
set-swipeable-height]
|
(let [{:keys [author community-id id membership-status
|
||||||
(let [community (rf/sub [:communities/community community-id])
|
read timestamp]} notification
|
||||||
community-name (:name community)
|
community (rf/sub [:communities/community community-id])
|
||||||
community-image (get-in community [:images :thumbnail :uri])]
|
community-name (:name community)
|
||||||
[quo/activity-log
|
community-image (get-in community [:images :thumbnail :uri])]
|
||||||
{:title (i18n/label :t/join-request)
|
[swipeable props
|
||||||
:icon :i/add-user
|
[quo/activity-log
|
||||||
:timestamp (datetime/timestamp->relative timestamp)
|
{:title (i18n/label :t/join-request)
|
||||||
:unread? (not read)
|
:icon :i/add-user
|
||||||
:on-layout set-swipeable-height
|
:timestamp (datetime/timestamp->relative timestamp)
|
||||||
:context [[common/user-avatar-tag author]
|
:unread? (not read)
|
||||||
(i18n/label :t/wants-to-join)
|
:on-layout set-swipeable-height
|
||||||
[quo/context-tag
|
:context [[common/user-avatar-tag author]
|
||||||
{:size :small
|
(i18n/label :t/wants-to-join)
|
||||||
:override-theme :dark
|
[quo/context-tag
|
||||||
:color colors/primary-50
|
{:size :small
|
||||||
:style style/user-avatar-tag
|
:override-theme :dark
|
||||||
:text-style style/user-avatar-tag-text}
|
:color colors/primary-50
|
||||||
{:uri community-image} community-name]]
|
:style common-style/user-avatar-tag
|
||||||
:items (case membership-status
|
:text-style common-style/user-avatar-tag-text}
|
||||||
constants/activity-center-membership-status-accepted
|
{:uri community-image} community-name]]
|
||||||
[{:type :status
|
:items (case membership-status
|
||||||
:subtype :positive
|
constants/activity-center-membership-status-accepted
|
||||||
:key :status-accepted
|
[{:type :status
|
||||||
:blur? true
|
:subtype :positive
|
||||||
:label (i18n/label :t/accepted)}]
|
:key :status-accepted
|
||||||
|
:blur? true
|
||||||
|
:label (i18n/label :t/accepted)}]
|
||||||
|
|
||||||
constants/activity-center-membership-status-declined
|
constants/activity-center-membership-status-declined
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :negative
|
:subtype :negative
|
||||||
:key :status-declined
|
:key :status-declined
|
||||||
:blur? true
|
:blur? true
|
||||||
:label (i18n/label :t/declined)}]
|
:label (i18n/label :t/declined)}]
|
||||||
|
|
||||||
constants/activity-center-membership-status-pending
|
constants/activity-center-membership-status-pending
|
||||||
[{:type :button
|
[{:type :button
|
||||||
:subtype :danger
|
:subtype :danger
|
||||||
:key :button-decline
|
:key :button-decline
|
||||||
:label (i18n/label :t/decline)
|
:label (i18n/label :t/decline)
|
||||||
:accessibility-label :decline-join-request
|
:accessibility-label :decline-join-request
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:communities.ui/decline-request-to-join-pressed
|
(rf/dispatch
|
||||||
community-id id]))}
|
[:communities.ui/decline-request-to-join-pressed
|
||||||
{:type :button
|
community-id id]))}
|
||||||
:subtype :positive
|
{:type :button
|
||||||
:key :button-accept
|
:subtype :positive
|
||||||
:label (i18n/label :t/accept)
|
:key :button-accept
|
||||||
:accessibility-label :accept-join-request
|
:label (i18n/label :t/accept)
|
||||||
:on-press (fn []
|
:accessibility-label :accept-join-request
|
||||||
(rf/dispatch [:communities.ui/accept-request-to-join-pressed
|
:on-press (fn []
|
||||||
community-id id]))}]
|
(rf/dispatch [:communities.ui/accept-request-to-join-pressed
|
||||||
|
community-id id]))}]
|
||||||
|
|
||||||
nil)}]))
|
nil)}]]))
|
||||||
|
@ -30,23 +30,29 @@
|
|||||||
:outputRange [0 swipe-action-width]
|
:outputRange [0 swipe-action-width]
|
||||||
:extrapolate :clamp}))
|
:extrapolate :clamp}))
|
||||||
|
|
||||||
(defn left-swipe-container
|
(def swipe-base
|
||||||
[style-props]
|
{:align-items :center
|
||||||
(merge {:background-color colors/primary-60
|
:justify-content :center
|
||||||
:align-items :center
|
:border-radius swipe-button-border-radius
|
||||||
:justify-content :center
|
:width swipe-action-width})
|
||||||
:border-radius swipe-button-border-radius
|
|
||||||
:width swipe-action-width}
|
|
||||||
style-props))
|
|
||||||
|
|
||||||
(defn right-swipe-container
|
(defn swipe-success-container
|
||||||
[style-props]
|
[style]
|
||||||
(merge {:background-color colors/danger-60
|
(merge swipe-base
|
||||||
:align-items :center
|
{:background-color colors/success-60}
|
||||||
:justify-content :center
|
style))
|
||||||
:border-radius swipe-button-border-radius
|
|
||||||
:width swipe-action-width}
|
(defn swipe-danger-container
|
||||||
style-props))
|
[style]
|
||||||
|
(merge swipe-base
|
||||||
|
{:background-color colors/danger-60}
|
||||||
|
style))
|
||||||
|
|
||||||
|
(defn swipe-primary-container
|
||||||
|
[style]
|
||||||
|
(merge swipe-base
|
||||||
|
{:background-color colors/primary-60}
|
||||||
|
style))
|
||||||
|
|
||||||
(def swipe-text
|
(def swipe-text
|
||||||
{:margin-top 5
|
{:margin-top 5
|
||||||
|
@ -54,39 +54,42 @@
|
|||||||
(.close ^js @active-swipeable))
|
(.close ^js @active-swipeable))
|
||||||
(reset! active-swipeable @swipeable)))
|
(reset! active-swipeable @swipeable)))
|
||||||
|
|
||||||
(defn left-swipe-button
|
(defn swipe-button-container
|
||||||
[{:keys [style]} {:keys [notification]}]
|
[{:keys [style icon text]} _]
|
||||||
[rn/animated-view
|
[rn/animated-view
|
||||||
{:accessibility-label :notification-left-swipe
|
{:accessibility-label :notification-swipe
|
||||||
:style (style/left-swipe-container style)}
|
:style style}
|
||||||
[rn/view {:style style/swipe-text-wrapper}
|
[rn/view {:style style/swipe-text-wrapper}
|
||||||
[quo/icon
|
[quo/icon icon
|
||||||
(if (:read notification)
|
|
||||||
:i/notifications
|
|
||||||
:i/check)
|
|
||||||
{:color colors/white}]
|
{:color colors/white}]
|
||||||
[quo/text {:style style/swipe-text}
|
[quo/text {:style style/swipe-text}
|
||||||
(if (:read notification)
|
text]]])
|
||||||
(i18n/label :t/unread)
|
|
||||||
(i18n/label :t/read))]]])
|
|
||||||
|
|
||||||
(defn right-swipe-button
|
(defn swipe-button-read-or-unread
|
||||||
|
[{:keys [style]} {:keys [notification]}]
|
||||||
|
[swipe-button-container
|
||||||
|
{:style (style/swipe-primary-container style)
|
||||||
|
:icon (if (:read notification)
|
||||||
|
:i/notifications
|
||||||
|
:i/check)
|
||||||
|
:text (if (:read notification)
|
||||||
|
(i18n/label :t/unread)
|
||||||
|
(i18n/label :t/read))}])
|
||||||
|
|
||||||
|
(defn swipe-button-delete
|
||||||
[{:keys [style]}]
|
[{:keys [style]}]
|
||||||
[rn/animated-view
|
[swipe-button-container
|
||||||
{:accessibility-label :notification-right-swipe
|
{:style (style/swipe-danger-container style)
|
||||||
:style (style/right-swipe-container style)}
|
:icon :i/delete
|
||||||
[rn/view {:style style/swipe-text-wrapper}
|
:text (i18n/label :t/delete)}])
|
||||||
[quo/icon :i/delete {:color colors/white}]
|
|
||||||
[quo/text {:style style/swipe-text}
|
|
||||||
(i18n/label :t/delete)]]])
|
|
||||||
|
|
||||||
(defn left-swipe-on-press
|
(defn swipe-on-press-toggle-read
|
||||||
[{:keys [notification]}]
|
[{:keys [notification]}]
|
||||||
(if (:read notification)
|
(if (:read notification)
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-unread (:id notification)])
|
(rf/dispatch [:activity-center.notifications/mark-as-unread (:id notification)])
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notification)])))
|
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notification)])))
|
||||||
|
|
||||||
(defn right-swipe-on-press
|
(defn swipe-on-press-delete
|
||||||
[{:keys [notification]}]
|
[{:keys [notification]}]
|
||||||
(rf/dispatch [:activity-center.notifications/delete (:id notification)]))
|
(rf/dispatch [:activity-center.notifications/delete (:id notification)]))
|
||||||
|
|
||||||
@ -102,15 +105,15 @@
|
|||||||
& children]
|
& children]
|
||||||
(into
|
(into
|
||||||
[gesture/swipeable
|
[gesture/swipeable
|
||||||
{:ref #(reset! swipeable-ref %)
|
(merge
|
||||||
:accessibility-label :notification-swipeable
|
{:ref #(reset! swipeable-ref %)
|
||||||
:friction 2
|
:accessibility-label :notification-swipeable
|
||||||
:left-threshold style/swipe-action-width
|
:friction 2
|
||||||
:right-threshold style/swipe-action-width
|
:on-swipeable-will-open (close-active-swipeable active-swipeable swipeable-ref)}
|
||||||
:overshoot-left false
|
(when left-button
|
||||||
:overshoot-right false
|
{:overshoot-left false
|
||||||
:on-swipeable-will-open (close-active-swipeable active-swipeable swipeable-ref)
|
:left-threshold style/swipe-action-width
|
||||||
:render-left-actions (render-swipe-action
|
:render-left-actions (render-swipe-action
|
||||||
{:active-swipeable active-swipeable
|
{:active-swipeable active-swipeable
|
||||||
:extra-fn extra-fn
|
:extra-fn extra-fn
|
||||||
:interpolation-opacity style/left-swipe-opacity-interpolation-js
|
:interpolation-opacity style/left-swipe-opacity-interpolation-js
|
||||||
@ -118,14 +121,17 @@
|
|||||||
style/left-swipe-translate-x-interpolation-js
|
style/left-swipe-translate-x-interpolation-js
|
||||||
:on-press left-on-press
|
:on-press left-on-press
|
||||||
:swipe-button left-button
|
:swipe-button left-button
|
||||||
:swipeable-ref swipeable-ref})
|
:swipeable-ref swipeable-ref})})
|
||||||
:render-right-actions (render-swipe-action
|
(when right-button
|
||||||
{:active-swipeable active-swipeable
|
{:overshoot-right false
|
||||||
:extra-fn extra-fn
|
:right-threshold style/swipe-action-width
|
||||||
:interpolation-opacity style/right-swipe-opacity-interpolation-js
|
:render-right-actions (render-swipe-action
|
||||||
:interpolation-translate-x
|
{:active-swipeable active-swipeable
|
||||||
style/right-swipe-translate-x-interpolation-js
|
:extra-fn extra-fn
|
||||||
:on-press right-on-press
|
:interpolation-opacity style/right-swipe-opacity-interpolation-js
|
||||||
:swipe-button right-button
|
:interpolation-translate-x
|
||||||
:swipeable-ref swipeable-ref})}]
|
style/right-swipe-translate-x-interpolation-js
|
||||||
|
:on-press right-on-press
|
||||||
|
:swipe-button right-button
|
||||||
|
:swipeable-ref swipeable-ref})}))]
|
||||||
children))))
|
children))))
|
||||||
|
@ -1,26 +1,69 @@
|
|||||||
(ns status-im2.contexts.activity-center.notification.contact-requests.events
|
(ns status-im2.contexts.activity-center.notification.contact-requests.events
|
||||||
(:require [utils.re-frame :as rf]))
|
(:require [status-im2.contexts.activity-center.events :as ac-events]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(rf/defn accept-contact-request
|
(rf/defn accept-contact-request
|
||||||
{:events [:activity-center.contact-requests/accept-request]}
|
{:events [:activity-center.contact-requests/accept]}
|
||||||
[{:keys [db]} id]
|
[_ contact-id]
|
||||||
{:json-rpc/call [{:method "wakuext_acceptContactRequest"
|
{:json-rpc/call
|
||||||
:params [{:id id}]
|
[{:method "wakuext_acceptContactRequest"
|
||||||
:js-response true
|
:params [{:id contact-id}]
|
||||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})
|
:js-response true
|
||||||
|
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||||
|
:on-error #(rf/dispatch [:activity-center.contact-requests/accept-error contact-id %])}]})
|
||||||
|
|
||||||
|
(rf/defn accept-contact-request-error
|
||||||
|
{:events [:activity-center.contact-requests/accept-error]}
|
||||||
|
[_ contact-id error]
|
||||||
|
(log/error "Failed to accept contact-request"
|
||||||
|
{:error error
|
||||||
|
:event :activity-center.contact-requests/accept
|
||||||
|
:contact-id contact-id})
|
||||||
|
nil)
|
||||||
|
|
||||||
(rf/defn decline-contact-request
|
(rf/defn decline-contact-request
|
||||||
{:events [:activity-center.contact-requests/decline-request]}
|
{:events [:activity-center.contact-requests/decline]}
|
||||||
[{:keys [db]} id]
|
[_ contact-id]
|
||||||
{:json-rpc/call [{:method "wakuext_declineContactRequest"
|
{:json-rpc/call
|
||||||
:params [{:id id}]
|
[{:method "wakuext_declineContactRequest"
|
||||||
:js-response true
|
:params [{:id contact-id}]
|
||||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})
|
:js-response true
|
||||||
|
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||||
|
:on-error #(rf/dispatch [:activity-center.contact-requests/decline-error contact-id %])}]})
|
||||||
|
|
||||||
|
(rf/defn decline-contact-request-error
|
||||||
|
{:events [:activity-center.contact-requests/decline-error]}
|
||||||
|
[_ contact-id error]
|
||||||
|
(log/error "Failed to decline contact-request"
|
||||||
|
{:error error
|
||||||
|
:event :activity-center.contact-requests/decline
|
||||||
|
:contact-id contact-id})
|
||||||
|
nil)
|
||||||
|
|
||||||
(rf/defn cancel-outgoing-contact-request
|
(rf/defn cancel-outgoing-contact-request
|
||||||
{:events [:activity-center.contact-requests/cancel-outgoing-request]}
|
{:events [:activity-center.contact-requests/cancel-outgoing]}
|
||||||
[{:keys [db]} id]
|
[{:keys [db]} {:keys [contact-id notification-id]}]
|
||||||
{:json-rpc/call [{:method "wakuext_cancelOutgoingContactRequest"
|
(when-let [notification (ac-events/get-notification db notification-id)]
|
||||||
:params [{:id id}]
|
{:json-rpc/call
|
||||||
:js-response true
|
[{:method "wakuext_cancelOutgoingContactRequest"
|
||||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]})
|
:params [{:id contact-id}]
|
||||||
|
:on-success #(rf/dispatch [:activity-center.contact-requests/cancel-outgoing-success
|
||||||
|
notification])
|
||||||
|
:on-error #(rf/dispatch [:activity-center.contact-requests/cancel-outgoing-error contact-id
|
||||||
|
%])}]}))
|
||||||
|
|
||||||
|
(rf/defn cancel-outgoing-contact-request-success
|
||||||
|
{:events [:activity-center.contact-requests/cancel-outgoing-success]}
|
||||||
|
[_ notification]
|
||||||
|
{:dispatch [:activity-center.notifications/reconcile
|
||||||
|
[(assoc notification :deleted true)]]})
|
||||||
|
|
||||||
|
(rf/defn cancel-outgoing-contact-request-error
|
||||||
|
{:events [:activity-center.contact-requests/cancel-outgoing-error]}
|
||||||
|
[_ contact-id error]
|
||||||
|
(log/error "Failed to cancel outgoing contact-request"
|
||||||
|
{:error error
|
||||||
|
:event :activity-center.contact-requests/cancel-outgoing
|
||||||
|
:contact-id contact-id})
|
||||||
|
nil)
|
||||||
|
@ -2,31 +2,81 @@
|
|||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
|
[status-im2.contexts.activity-center.notification.common.style :as common-style]
|
||||||
[status-im2.contexts.activity-center.notification.common.view :as common]
|
[status-im2.contexts.activity-center.notification.common.view :as common]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn swipeable
|
(defn- swipe-button-accept
|
||||||
[{:keys [height active-swipeable notification]} child]
|
[{:keys [style]} _]
|
||||||
(let [message (or (:message notification) (:last-message notification))]
|
[common/swipe-button-container
|
||||||
(if (#{constants/contact-request-message-state-accepted
|
{:style (common-style/swipe-success-container style)
|
||||||
constants/contact-request-message-state-declined}
|
:icon :i/placeholder
|
||||||
(:contact-request-state message))
|
:text (i18n/label :t/accept)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-decline
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/decline)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-cancel-pending
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/cancel)}])
|
||||||
|
|
||||||
|
(defn- swipeable
|
||||||
|
[{:keys [active-swipeable extra-fn notification]} child]
|
||||||
|
(let [{:keys [id author message last-message]} notification
|
||||||
|
{:keys [contact-request-state]} (or (:message notification)
|
||||||
|
(:last-message notification))
|
||||||
|
{:keys [public-key]} (rf/sub [:multiaccount/contact])
|
||||||
|
message (or message last-message)]
|
||||||
|
(cond
|
||||||
|
(#{constants/contact-request-message-state-accepted
|
||||||
|
constants/contact-request-message-state-declined}
|
||||||
|
contact-request-state)
|
||||||
[common/swipeable
|
[common/swipeable
|
||||||
{:left-button common/left-swipe-button
|
{:left-button common/swipe-button-read-or-unread
|
||||||
:left-on-press common/left-swipe-on-press
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
:right-button common/right-swipe-button
|
:right-button common/swipe-button-delete
|
||||||
:right-on-press common/right-swipe-on-press
|
:right-on-press common/swipe-on-press-delete
|
||||||
:active-swipeable active-swipeable
|
:active-swipeable active-swipeable
|
||||||
:extra-fn (fn [] {:height @height :notification notification})}
|
:extra-fn extra-fn}
|
||||||
child]
|
child]
|
||||||
|
|
||||||
|
(= contact-request-state constants/contact-request-message-state-pending)
|
||||||
|
(if (= public-key author)
|
||||||
|
[common/swipeable
|
||||||
|
{:right-button swipe-button-cancel-pending
|
||||||
|
:right-on-press (fn []
|
||||||
|
(rf/dispatch
|
||||||
|
[:activity-center.contact-requests/cancel-outgoing
|
||||||
|
{:contact-id (:from message)
|
||||||
|
:notification-id id}]))
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button swipe-button-accept
|
||||||
|
:left-on-press #(rf/dispatch [:activity-center.contact-requests/accept id])
|
||||||
|
:right-button swipe-button-decline
|
||||||
|
:right-on-press #(rf/dispatch [:activity-center.contact-requests/decline id])
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child])
|
||||||
|
|
||||||
|
:else
|
||||||
child)))
|
child)))
|
||||||
|
|
||||||
(defn outgoing-contact-request-view
|
(defn- outgoing-contact-request-view
|
||||||
[{:keys [id chat-id message last-message] :as notification}
|
[{:keys [notification set-swipeable-height]}]
|
||||||
set-swipeable-height]
|
(let [{:keys [id chat-id message last-message]} notification
|
||||||
(let [{:keys [contact-request-state] :as message} (or message last-message)]
|
{:keys [contact-request-state] :as message} (or message last-message)]
|
||||||
(if (= contact-request-state constants/contact-request-message-state-accepted)
|
(if (= contact-request-state constants/contact-request-message-state-accepted)
|
||||||
[quo/activity-log
|
[quo/activity-log
|
||||||
{:title (i18n/label :t/contact-request-was-accepted)
|
{:title (i18n/label :t/contact-request-was-accepted)
|
||||||
@ -48,7 +98,7 @@
|
|||||||
[common/user-avatar-tag chat-id]]
|
[common/user-avatar-tag chat-id]]
|
||||||
:message {:body (get-in message [:content :text])}
|
:message {:body (get-in message [:content :text])}
|
||||||
:items (case contact-request-state
|
:items (case contact-request-state
|
||||||
constants/contact-request-state-mutual
|
constants/contact-request-message-state-pending
|
||||||
[{:type :button
|
[{:type :button
|
||||||
:subtype :danger
|
:subtype :danger
|
||||||
:key :button-cancel
|
:key :button-cancel
|
||||||
@ -56,10 +106,9 @@
|
|||||||
:accessibility-label :cancel-contact-request
|
:accessibility-label :cancel-contact-request
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch
|
(rf/dispatch
|
||||||
[:activity-center.contact-requests/cancel-outgoing-request
|
[:activity-center.contact-requests/cancel-outgoing
|
||||||
(:from message)])
|
{:contact-id (:from message)
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read
|
:notification-id id}]))}
|
||||||
id]))}
|
|
||||||
{:type :status
|
{:type :status
|
||||||
:subtype :pending
|
:subtype :pending
|
||||||
:key :status-pending
|
:key :status-pending
|
||||||
@ -75,10 +124,10 @@
|
|||||||
|
|
||||||
nil)}])))
|
nil)}])))
|
||||||
|
|
||||||
(defn incoming-contact-request-view
|
(defn- incoming-contact-request-view
|
||||||
[{:keys [id author message last-message] :as notification}
|
[{:keys [notification set-swipeable-height]}]
|
||||||
set-swipeable-height]
|
(let [{:keys [id author message last-message]} notification
|
||||||
(let [message (or message last-message)]
|
message (or message last-message)]
|
||||||
[quo/activity-log
|
[quo/activity-log
|
||||||
{:title (i18n/label :t/contact-request)
|
{:title (i18n/label :t/contact-request)
|
||||||
:on-layout set-swipeable-height
|
:on-layout set-swipeable-height
|
||||||
@ -110,36 +159,31 @@
|
|||||||
:key :button-decline
|
:key :button-decline
|
||||||
:label (i18n/label :t/decline)
|
:label (i18n/label :t/decline)
|
||||||
:accessibility-label :decline-contact-request
|
:accessibility-label :decline-contact-request
|
||||||
:on-press (fn []
|
:on-press #(rf/dispatch [:activity-center.contact-requests/decline id])}
|
||||||
(rf/dispatch [:activity-center.contact-requests/decline-request id])
|
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read
|
|
||||||
id]))}
|
|
||||||
{:type :button
|
{:type :button
|
||||||
:subtype :positive
|
:subtype :positive
|
||||||
:key :button-accept
|
:key :button-accept
|
||||||
:label (i18n/label :t/accept)
|
:label (i18n/label :t/accept)
|
||||||
:accessibility-label :accept-contact-request
|
:accessibility-label :accept-contact-request
|
||||||
:on-press (fn []
|
:on-press #(rf/dispatch [:activity-center.contact-requests/accept id])}]
|
||||||
(rf/dispatch [:activity-center.contact-requests/accept-request id])
|
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read
|
|
||||||
id]))}]
|
|
||||||
nil)}]))
|
nil)}]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [author message last-message] :as notification}
|
[{:keys [notification] :as props}]
|
||||||
set-swipeable-height]
|
(let [{:keys [author message last-message]} notification
|
||||||
(let [{:keys [public-key]} (rf/sub [:multiaccount/contact])
|
{:keys [public-key]} (rf/sub [:multiaccount/contact])
|
||||||
{:keys [contact-request-state]} (or message last-message)]
|
{:keys [contact-request-state]} (or message last-message)]
|
||||||
(cond
|
[swipeable props
|
||||||
(= public-key author)
|
(cond
|
||||||
[outgoing-contact-request-view notification set-swipeable-height]
|
(= public-key author)
|
||||||
|
[outgoing-contact-request-view props]
|
||||||
|
|
||||||
(= contact-request-state constants/contact-request-message-state-accepted)
|
(= contact-request-state constants/contact-request-message-state-accepted)
|
||||||
[gesture/touchable-without-feedback
|
[gesture/touchable-without-feedback
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:hide-popover])
|
(rf/dispatch [:hide-popover])
|
||||||
(rf/dispatch [:chat.ui/start-chat author]))}
|
(rf/dispatch [:chat.ui/start-chat author]))}
|
||||||
[incoming-contact-request-view notification set-swipeable-height]]
|
[incoming-contact-request-view props]]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[incoming-contact-request-view notification set-swipeable-height])))
|
[incoming-contact-request-view props])]))
|
||||||
|
@ -1,16 +1,40 @@
|
|||||||
(ns status-im2.contexts.activity-center.notification.contact-verification.view
|
(ns status-im2.contexts.activity-center.notification.contact-verification.view
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
[utils.datetime :as datetime]
|
[status-im2.contexts.activity-center.notification.common.style :as common-style]
|
||||||
[status-im2.contexts.activity-center.notification.common.view :as common]
|
[status-im2.contexts.activity-center.notification.common.view :as common]
|
||||||
|
[utils.datetime :as datetime]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- hide-bottom-sheet-and-dispatch
|
(defn- swipe-button-decline
|
||||||
[event]
|
[{:keys [style]} _]
|
||||||
(rf/dispatch [:bottom-sheet/hide])
|
[common/swipe-button-container
|
||||||
(rf/dispatch event))
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/decline)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-reply
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-primary-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/message-reply)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-untrustworthy
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/untrustworthy)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-trust
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-success-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/accept)}])
|
||||||
|
|
||||||
(defn- context-tags
|
(defn- context-tags
|
||||||
[challenger? {:keys [author contact-verification-status]}]
|
[challenger? {:keys [author contact-verification-status]}]
|
||||||
@ -38,18 +62,6 @@
|
|||||||
(= contact-verification-status constants/contact-verification-status-declined))
|
(= contact-verification-status constants/contact-verification-status-declined))
|
||||||
{:body (get-in message [:content :text])})))
|
{:body (get-in message [:content :text])})))
|
||||||
|
|
||||||
(defn- activity-status
|
|
||||||
[challenger? contact-verification-status]
|
|
||||||
(if challenger?
|
|
||||||
(cond (= contact-verification-status constants/contact-verification-status-trusted)
|
|
||||||
{:type :positive :label (i18n/label :t/status-confirmed)}
|
|
||||||
(= contact-verification-status constants/contact-verification-status-untrustworthy)
|
|
||||||
{:type :negative :label (i18n/label :t/untrustworthy)})
|
|
||||||
(cond (= contact-verification-status constants/contact-verification-status-accepted)
|
|
||||||
{:type :positive :label (i18n/label :t/replied)}
|
|
||||||
(= contact-verification-status constants/contact-verification-status-declined)
|
|
||||||
{:type :negative :label (i18n/label :t/declined)})))
|
|
||||||
|
|
||||||
(def ^:private max-reply-length
|
(def ^:private max-reply-length
|
||||||
280)
|
280)
|
||||||
|
|
||||||
@ -57,84 +69,181 @@
|
|||||||
[reply]
|
[reply]
|
||||||
(<= (count reply) max-reply-length))
|
(<= (count reply) max-reply-length))
|
||||||
|
|
||||||
|
(def ^:private invalid-reply?
|
||||||
|
(comp not valid-reply?))
|
||||||
|
|
||||||
|
(declare view)
|
||||||
|
|
||||||
|
(defn- decline-challenge
|
||||||
|
[id]
|
||||||
|
(rf/dispatch [:bottom-sheet/hide])
|
||||||
|
(rf/dispatch [:activity-center.contact-verification/decline id])
|
||||||
|
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||||
|
|
||||||
|
(defn- prepare-challenge-reply
|
||||||
|
[props]
|
||||||
|
(rf/dispatch [:bottom-sheet/show-sheet
|
||||||
|
{:content view
|
||||||
|
:override-theme :dark}
|
||||||
|
(assoc props :replying? true)]))
|
||||||
|
|
||||||
|
(defn- send-challenge-reply
|
||||||
|
[id reply]
|
||||||
|
(rf/dispatch [:bottom-sheet/hide])
|
||||||
|
(rf/dispatch [:activity-center.contact-verification/reply id reply])
|
||||||
|
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||||
|
|
||||||
|
(defn- mark-challenge-untrustworthy
|
||||||
|
[id]
|
||||||
|
(rf/dispatch [:activity-center.contact-verification/mark-as-untrustworthy id])
|
||||||
|
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||||
|
|
||||||
|
(defn- mark-challenge-trusted
|
||||||
|
[id]
|
||||||
|
(rf/dispatch [:activity-center.contact-verification/mark-as-trusted id])
|
||||||
|
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||||
|
|
||||||
|
(defn- swipeable
|
||||||
|
[{:keys [active-swipeable extra-fn notification replying?] :as props} child]
|
||||||
|
(let [{:keys [id message
|
||||||
|
contact-verification-status]} notification
|
||||||
|
challenger? (:outgoing message)]
|
||||||
|
(cond
|
||||||
|
replying?
|
||||||
|
child
|
||||||
|
|
||||||
|
(and (not challenger?)
|
||||||
|
(= contact-verification-status constants/contact-verification-status-pending))
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button swipe-button-reply
|
||||||
|
:left-on-press #(prepare-challenge-reply props)
|
||||||
|
:right-button swipe-button-decline
|
||||||
|
:right-on-press #(decline-challenge id)
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
|
||||||
|
(and challenger?
|
||||||
|
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button swipe-button-trust
|
||||||
|
:left-on-press #(mark-challenge-trusted id)
|
||||||
|
:right-button swipe-button-untrustworthy
|
||||||
|
:right-on-press #(mark-challenge-untrustworthy id)
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
|
||||||
|
(#{constants/contact-verification-status-accepted
|
||||||
|
constants/contact-verification-status-declined
|
||||||
|
constants/contact-verification-status-trusted}
|
||||||
|
contact-verification-status)
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button common/swipe-button-read-or-unread
|
||||||
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
|
:right-button common/swipe-button-delete
|
||||||
|
:right-on-press common/swipe-on-press-delete
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
|
||||||
|
:else
|
||||||
|
child)))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[_ _]
|
[_]
|
||||||
(let [reply (atom "")]
|
(let [reply (atom "")]
|
||||||
(fn [{:keys [id message contact-verification-status] :as notification} {:keys [replying?]}]
|
(fn [{:keys [notification set-swipeable-height replying?] :as props}]
|
||||||
(let [challenger? (:outgoing message)]
|
(let [{:keys [id message
|
||||||
|
contact-verification-status]} notification
|
||||||
|
challenger? (:outgoing message)]
|
||||||
;; TODO(@ilmotta): Declined challenges should only be displayed for the
|
;; TODO(@ilmotta): Declined challenges should only be displayed for the
|
||||||
;; challengee, not the challenger.
|
;; challengee, not the challenger.
|
||||||
;; https://github.com/status-im/status-mobile/issues/14354
|
;; https://github.com/status-im/status-mobile/issues/14354
|
||||||
(when-not (and challenger?
|
(when-not
|
||||||
(= contact-verification-status constants/contact-verification-status-declined))
|
(and challenger?
|
||||||
[quo/activity-log
|
(= contact-verification-status constants/contact-verification-status-declined))
|
||||||
(merge
|
[swipeable props
|
||||||
{:title (i18n/label :t/identity-verification-request)
|
[quo/activity-log
|
||||||
:icon :i/friend
|
(merge
|
||||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
(when-not replying?
|
||||||
:unread? (not (:read notification))
|
{:on-layout set-swipeable-height})
|
||||||
:on-update-reply #(reset! reply %)
|
{:title (i18n/label :t/identity-verification-request)
|
||||||
:replying? replying?
|
:icon :i/friend
|
||||||
:max-reply-length max-reply-length
|
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||||
:valid-reply? valid-reply?
|
:unread? (not (:read notification))
|
||||||
:context (context-tags challenger? notification)
|
:on-update-reply #(reset! reply %)
|
||||||
:message (activity-message challenger? notification)
|
:replying? replying?
|
||||||
:status (activity-status challenger? contact-verification-status)
|
:max-reply-length max-reply-length
|
||||||
:items
|
:valid-reply? valid-reply?
|
||||||
(if challenger?
|
:context (context-tags challenger? notification)
|
||||||
(when (= contact-verification-status constants/contact-verification-status-accepted)
|
:message (activity-message challenger? notification)
|
||||||
|
:items
|
||||||
|
(cond-> []
|
||||||
|
(and challenger?
|
||||||
|
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||||
|
(concat
|
||||||
[{:type :button
|
[{:type :button
|
||||||
:subtype :danger
|
:subtype :danger
|
||||||
:key :button-mark-as-untrustworthy
|
:key :button-mark-as-untrustworthy
|
||||||
:label (i18n/label :t/untrustworthy)
|
:label (i18n/label :t/untrustworthy)
|
||||||
:accessibility-label :mark-contact-verification-as-untrustworthy
|
:accessibility-label :mark-contact-verification-as-untrustworthy
|
||||||
:on-press (fn []
|
:on-press #(mark-challenge-untrustworthy id)}
|
||||||
(rf/dispatch
|
|
||||||
[:activity-center.contact-verification/mark-as-untrustworthy
|
|
||||||
id])
|
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read
|
|
||||||
id]))}
|
|
||||||
{:type :button
|
{:type :button
|
||||||
:subtype :positive
|
:subtype :positive
|
||||||
:key :button-accept
|
:key :button-accept
|
||||||
:label (i18n/label :t/accept)
|
:label (i18n/label :t/accept)
|
||||||
:accessibility-label :mark-contact-verification-as-trusted
|
:accessibility-label :mark-contact-verification-as-trusted
|
||||||
:on-press (fn []
|
:on-press #(mark-challenge-trusted id)}])
|
||||||
(rf/dispatch
|
|
||||||
[:activity-center.contact-verification/mark-as-trusted id])
|
(and challenger?
|
||||||
(rf/dispatch [:activity-center.notifications/mark-as-read
|
(= contact-verification-status constants/contact-verification-status-trusted))
|
||||||
id]))}])
|
(concat [{:type :status
|
||||||
(when (= contact-verification-status constants/contact-verification-status-pending)
|
:subtype :positive
|
||||||
|
:key :status-trusted
|
||||||
|
:label (i18n/label :t/status-confirmed)}])
|
||||||
|
|
||||||
|
(and challenger?
|
||||||
|
(= contact-verification-status constants/contact-verification-status-untrustworthy))
|
||||||
|
(concat [{:type :status
|
||||||
|
:subtype :negative
|
||||||
|
:key :status-untrustworthy
|
||||||
|
:label (i18n/label :t/untrustworthy)}])
|
||||||
|
|
||||||
|
(and (not challenger?)
|
||||||
|
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||||
|
(concat [{:type :status
|
||||||
|
:subtype :positive
|
||||||
|
:key :status-accepted
|
||||||
|
:label (i18n/label :t/replied)}])
|
||||||
|
|
||||||
|
(and (not challenger?)
|
||||||
|
(= contact-verification-status constants/contact-verification-status-declined))
|
||||||
|
(concat [{:type :status
|
||||||
|
:subtype :negative
|
||||||
|
:key :status-declined
|
||||||
|
:label (i18n/label :t/declined)}])
|
||||||
|
|
||||||
|
(and (not challenger?)
|
||||||
|
(= contact-verification-status constants/contact-verification-status-pending))
|
||||||
|
(concat
|
||||||
[{:type :button
|
[{:type :button
|
||||||
:subtype :danger
|
:subtype :danger
|
||||||
:key :button-decline
|
:key :button-decline
|
||||||
:label (i18n/label :t/decline)
|
:label (i18n/label :t/decline)
|
||||||
:accessibility-label :decline-contact-verification
|
:accessibility-label :decline-contact-verification
|
||||||
:on-press (fn []
|
:on-press #(decline-challenge id)}
|
||||||
(hide-bottom-sheet-and-dispatch
|
|
||||||
[:activity-center.contact-verification/decline id])
|
|
||||||
(rf/dispatch
|
|
||||||
[:activity-center.notifications/mark-as-read id]))}
|
|
||||||
(if replying?
|
(if replying?
|
||||||
{:type :button
|
{:type :button
|
||||||
:subtype :primary
|
:subtype :primary
|
||||||
:key :button-reply
|
:key :button-reply
|
||||||
:label (i18n/label :t/send-reply)
|
:label (i18n/label :t/send-reply)
|
||||||
:accessibility-label :reply-to-contact-verification
|
:accessibility-label :reply-to-contact-verification
|
||||||
:disable-when #(not (valid-reply? %))
|
:disable-when invalid-reply?
|
||||||
:on-press (fn []
|
:on-press #(send-challenge-reply id @reply)}
|
||||||
(hide-bottom-sheet-and-dispatch
|
|
||||||
[:activity-center.contact-verification/reply id
|
|
||||||
@reply])
|
|
||||||
(rf/dispatch
|
|
||||||
[:activity-center.notifications/mark-as-read id]))}
|
|
||||||
{:type :button
|
{:type :button
|
||||||
:subtype :primary
|
:subtype :primary
|
||||||
:key :button-send-reply
|
:key :button-send-reply
|
||||||
:label (i18n/label :t/message-reply)
|
:label (i18n/label :t/message-reply)
|
||||||
:accessibility-label :send-reply-to-contact-verification
|
:accessibility-label :send-reply-to-contact-verification
|
||||||
:on-press (fn []
|
:on-press #(prepare-challenge-reply props)})]))})]])))))
|
||||||
(rf/dispatch [:bottom-sheet/show-sheet
|
|
||||||
{:content view}
|
|
||||||
{:notification notification
|
|
||||||
:replying? true}]))})]))})])))))
|
|
||||||
|
@ -1,45 +1,84 @@
|
|||||||
(ns status-im2.contexts.activity-center.notification.membership.view
|
(ns status-im2.contexts.activity-center.notification.membership.view
|
||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.gesture :as gesture]
|
||||||
|
[status-im2.contexts.activity-center.notification.common.style :as common-style]
|
||||||
[status-im2.contexts.activity-center.notification.common.view :as common]
|
[status-im2.contexts.activity-center.notification.common.view :as common]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn pressable
|
(defn- pressable
|
||||||
[{:keys [accepted chat-id]} & children]
|
[{:keys [accepted chat-id]} child]
|
||||||
(if accepted
|
(if accepted
|
||||||
(into [rn/touchable-opacity
|
[gesture/touchable-without-feedback
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:hide-popover])
|
(rf/dispatch [:hide-popover])
|
||||||
(rf/dispatch [:chat/navigate-to-chat chat-id]))}]
|
(rf/dispatch [:chat/navigate-to-chat chat-id]))}
|
||||||
children)
|
child]
|
||||||
(into [:<>] children)))
|
child))
|
||||||
|
|
||||||
|
(defn- swipe-button-accept
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-success-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/accept)}])
|
||||||
|
|
||||||
|
(defn- swipe-button-decline
|
||||||
|
[{:keys [style]} _]
|
||||||
|
[common/swipe-button-container
|
||||||
|
{:style (common-style/swipe-danger-container style)
|
||||||
|
:icon :i/placeholder
|
||||||
|
:text (i18n/label :t/decline)}])
|
||||||
|
|
||||||
|
(defn- swipeable
|
||||||
|
[{:keys [active-swipeable notification extra-fn]} child]
|
||||||
|
(let [{:keys [accepted dismissed id]} notification]
|
||||||
|
(if (or accepted dismissed)
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button common/swipe-button-read-or-unread
|
||||||
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
|
:right-button common/swipe-button-delete
|
||||||
|
:right-on-press common/swipe-on-press-delete
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child]
|
||||||
|
[common/swipeable
|
||||||
|
{:left-button swipe-button-accept
|
||||||
|
:left-on-press #(rf/dispatch [:activity-center.notifications/accept id])
|
||||||
|
:right-button swipe-button-decline
|
||||||
|
:right-on-press #(rf/dispatch [:activity-center.notifications/dismiss id])
|
||||||
|
:active-swipeable active-swipeable
|
||||||
|
:extra-fn extra-fn}
|
||||||
|
child])))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [id accepted author read timestamp chat-name chat-id]}]
|
[{:keys [notification set-swipeable-height] :as props}]
|
||||||
[pressable {:accepted accepted :chat-id chat-id}
|
(let [{:keys [id accepted dismissed author read timestamp chat-name chat-id]} notification]
|
||||||
[quo/activity-log
|
[swipeable props
|
||||||
{:title (i18n/label :t/added-to-group-chat)
|
[pressable {:accepted accepted :chat-id chat-id}
|
||||||
:icon :i/add-user
|
[quo/activity-log
|
||||||
:timestamp (datetime/timestamp->relative timestamp)
|
{:title (i18n/label :t/added-to-group-chat)
|
||||||
:unread? (not read)
|
:on-layout set-swipeable-height
|
||||||
:context [[common/user-avatar-tag author]
|
:icon :i/add-user
|
||||||
(i18n/label :t/added-you-to)
|
:timestamp (datetime/timestamp->relative timestamp)
|
||||||
[quo/group-avatar-tag chat-name
|
:unread? (not read)
|
||||||
{:size :small
|
:context [[common/user-avatar-tag author]
|
||||||
:color :purple}]]
|
(i18n/label :t/added-you-to)
|
||||||
:items (when-not accepted
|
[quo/group-avatar-tag chat-name
|
||||||
[{:type :button
|
{:size :small
|
||||||
:subtype :positive
|
:color :purple}]]
|
||||||
:key :button-accept
|
:items (when-not (or accepted dismissed)
|
||||||
:label (i18n/label :t/accept)
|
[{:type :button
|
||||||
:accessibility-label :accept-group-chat-invitation
|
:subtype :positive
|
||||||
:on-press #(rf/dispatch [:activity-center.notifications/accept id])}
|
:key :button-accept
|
||||||
{:type :button
|
:label (i18n/label :t/accept)
|
||||||
:subtype :danger
|
:accessibility-label :accept-group-chat-invitation
|
||||||
:key :button-decline
|
:on-press #(rf/dispatch [:activity-center.notifications/accept id])}
|
||||||
:label (i18n/label :t/decline)
|
{:type :button
|
||||||
:accessibility-label :decline-group-chat-invitation
|
:subtype :danger
|
||||||
:on-press #(rf/dispatch [:activity-center.notifications/dismiss
|
:key :button-decline
|
||||||
id])}])}]])
|
:label (i18n/label :t/decline)
|
||||||
|
:accessibility-label :decline-group-chat-invitation
|
||||||
|
:on-press #(rf/dispatch [:activity-center.notifications/dismiss
|
||||||
|
id])}])}]]]))
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(def tag-params
|
(def ^:private tag-params
|
||||||
{:size :small
|
{:size :small
|
||||||
:override-theme :dark
|
:override-theme :dark
|
||||||
:color colors/primary-50
|
:color colors/primary-50
|
||||||
:style style/tag
|
:style style/tag
|
||||||
:text-style style/tag-text})
|
:text-style style/tag-text})
|
||||||
|
|
||||||
(defn message-body
|
(defn- message-body
|
||||||
[message]
|
[message]
|
||||||
(let [parsed-text (get-in message [:content :parsed-text])
|
(let [parsed-text (get-in message [:content :parsed-text])
|
||||||
parsed-text-children (:children (first parsed-text))]
|
parsed-text-children (:children (first parsed-text))]
|
||||||
@ -35,37 +35,39 @@
|
|||||||
literal))
|
literal))
|
||||||
parsed-text-children))))
|
parsed-text-children))))
|
||||||
|
|
||||||
(defn swipeable
|
(defn- swipeable
|
||||||
[{:keys [height active-swipeable notification]} child]
|
[{:keys [active-swipeable extra-fn]} child]
|
||||||
[common/swipeable
|
[common/swipeable
|
||||||
{:left-button common/left-swipe-button
|
{:left-button common/swipe-button-read-or-unread
|
||||||
:left-on-press common/left-swipe-on-press
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
:right-button common/right-swipe-button
|
:right-button common/swipe-button-delete
|
||||||
:right-on-press common/right-swipe-on-press
|
:right-on-press common/swipe-on-press-delete
|
||||||
:active-swipeable active-swipeable
|
:active-swipeable active-swipeable
|
||||||
:extra-fn (fn [] {:height @height :notification notification})}
|
:extra-fn extra-fn}
|
||||||
child])
|
child])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [author chat-name community-id chat-id message read timestamp]}
|
[{:keys [notification set-swipeable-height] :as props}]
|
||||||
set-swipeable-height]
|
(let [{:keys [author chat-name community-id chat-id
|
||||||
(let [community-chat? (not (string/blank? community-id))
|
message read timestamp]} notification
|
||||||
community (rf/sub [:communities/community community-id])
|
community-chat? (not (string/blank? community-id))
|
||||||
community-name (:name community)
|
community (rf/sub [:communities/community community-id])
|
||||||
community-image (get-in community [:images :thumbnail :uri])]
|
community-name (:name community)
|
||||||
[gesture/touchable-without-feedback
|
community-image (get-in community [:images :thumbnail :uri])]
|
||||||
{:on-press (fn []
|
[swipeable props
|
||||||
(rf/dispatch [:hide-popover])
|
[gesture/touchable-without-feedback
|
||||||
(rf/dispatch [:chat/navigate-to-chat chat-id]))}
|
{:on-press (fn []
|
||||||
[quo/activity-log
|
(rf/dispatch [:hide-popover])
|
||||||
{:title (i18n/label :t/mention)
|
(rf/dispatch [:chat/navigate-to-chat chat-id]))}
|
||||||
:on-layout set-swipeable-height
|
[quo/activity-log
|
||||||
:icon :i/mention
|
{:title (i18n/label :t/mention)
|
||||||
:timestamp (datetime/timestamp->relative timestamp)
|
:on-layout set-swipeable-height
|
||||||
:unread? (not read)
|
:icon :i/mention
|
||||||
:context [[common/user-avatar-tag author]
|
:timestamp (datetime/timestamp->relative timestamp)
|
||||||
[quo/text {:style style/tag-text} (string/lower-case (i18n/label :t/on))]
|
:unread? (not read)
|
||||||
(if community-chat?
|
:context [[common/user-avatar-tag author]
|
||||||
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
|
[quo/text {:style style/tag-text} (string/lower-case (i18n/label :t/on))]
|
||||||
[quo/group-avatar-tag chat-name tag-params])]
|
(if community-chat?
|
||||||
:message {:body (message-body message)}}]]))
|
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
|
||||||
|
[quo/group-avatar-tag chat-name tag-params])]
|
||||||
|
:message {:body (message-body message)}}]]]))
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(def tag-params
|
(def ^:private tag-params
|
||||||
{:size :small
|
{:size :small
|
||||||
:override-theme :dark
|
:override-theme :dark
|
||||||
:color colors/primary-50
|
:color colors/primary-50
|
||||||
@ -20,7 +20,7 @@
|
|||||||
:text-style style/tag-text})
|
:text-style style/tag-text})
|
||||||
|
|
||||||
;; NOTE: Replies support text, image and stickers only.
|
;; NOTE: Replies support text, image and stickers only.
|
||||||
(defn get-message-content
|
(defn- get-message-content
|
||||||
[{:keys [content-type] :as message}]
|
[{:keys [content-type] :as message}]
|
||||||
(case content-type
|
(case content-type
|
||||||
constants/content-type-text (get-in message [:content :text])
|
constants/content-type-text (get-in message [:content :text])
|
||||||
@ -37,38 +37,40 @@
|
|||||||
|
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn swipeable
|
(defn- swipeable
|
||||||
[{:keys [height active-swipeable notification]} child]
|
[{:keys [active-swipeable extra-fn]} child]
|
||||||
[common/swipeable
|
[common/swipeable
|
||||||
{:left-button common/left-swipe-button
|
{:left-button common/swipe-button-read-or-unread
|
||||||
:left-on-press common/left-swipe-on-press
|
:left-on-press common/swipe-on-press-toggle-read
|
||||||
:right-button common/right-swipe-button
|
:right-button common/swipe-button-delete
|
||||||
:right-on-press common/right-swipe-on-press
|
:right-on-press common/swipe-on-press-delete
|
||||||
:active-swipeable active-swipeable
|
:active-swipeable active-swipeable
|
||||||
:extra-fn (fn [] {:height @height :notification notification})}
|
:extra-fn extra-fn}
|
||||||
child])
|
child])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [author chat-name community-id chat-id message read timestamp]}
|
[{:keys [notification set-swipeable-height] :as props}]
|
||||||
set-swipeable-height]
|
(let [{:keys [author chat-name community-id chat-id
|
||||||
(let [community-chat? (not (string/blank? community-id))
|
message read timestamp]} notification
|
||||||
community (rf/sub [:communities/community community-id])
|
community-chat? (not (string/blank? community-id))
|
||||||
community-name (:name community)
|
community (rf/sub [:communities/community community-id])
|
||||||
community-image (get-in community [:images :thumbnail :uri])]
|
community-name (:name community)
|
||||||
[gesture/touchable-without-feedback
|
community-image (get-in community [:images :thumbnail :uri])]
|
||||||
{:on-press (fn []
|
[swipeable props
|
||||||
(rf/dispatch [:hide-popover])
|
[gesture/touchable-without-feedback
|
||||||
(rf/dispatch [:chat/navigate-to-chat chat-id]))}
|
{:on-press (fn []
|
||||||
[quo/activity-log
|
(rf/dispatch [:hide-popover])
|
||||||
{:title (i18n/label :t/message-reply)
|
(rf/dispatch [:chat/navigate-to-chat chat-id]))}
|
||||||
:on-layout set-swipeable-height
|
[quo/activity-log
|
||||||
:icon :i/reply
|
{:title (i18n/label :t/message-reply)
|
||||||
:timestamp (datetime/timestamp->relative timestamp)
|
:on-layout set-swipeable-height
|
||||||
:unread? (not read)
|
:icon :i/reply
|
||||||
:context [[common/user-avatar-tag author]
|
:timestamp (datetime/timestamp->relative timestamp)
|
||||||
[quo/text {:style style/lowercase-text} (i18n/label :t/on)]
|
:unread? (not read)
|
||||||
(if community-chat?
|
:context [[common/user-avatar-tag author]
|
||||||
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
|
[quo/text {:style style/lowercase-text} (i18n/label :t/on)]
|
||||||
[quo/group-avatar-tag chat-name tag-params])]
|
(if community-chat?
|
||||||
:message {:body-number-of-lines 1
|
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
|
||||||
:body (get-message-content message)}}]]))
|
[quo/group-avatar-tag chat-name tag-params])]
|
||||||
|
:message {:body-number-of-lines 1
|
||||||
|
:body (get-message-content message)}}]]]))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
(ns status-im2.contexts.activity-center.view
|
(ns status-im2.contexts.activity-center.view
|
||||||
(:require [oops.core :as oops]
|
(:require [clojure.set :as set]
|
||||||
|
[oops.core :as oops]
|
||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
@ -127,7 +128,7 @@
|
|||||||
:label (i18n/label :t/membership)
|
:label (i18n/label :t/membership)
|
||||||
:accessibility-label :tab-membership
|
:accessibility-label :tab-membership
|
||||||
:notification-dot? (when-not is-mark-all-as-read-undoable?
|
:notification-dot? (when-not is-mark-all-as-read-undoable?
|
||||||
(contains? types-with-unread types/membership))}
|
(set/subset? types/membership types-with-unread))}
|
||||||
{:id types/system
|
{:id types/system
|
||||||
:label (i18n/label :t/system)
|
:label (i18n/label :t/system)
|
||||||
:accessibility-label :tab-system
|
:accessibility-label :tab-system
|
||||||
@ -172,32 +173,30 @@
|
|||||||
(let [height (atom 0)
|
(let [height (atom 0)
|
||||||
set-swipeable-height #(reset! height (oops/oget % "nativeEvent.layout.height"))]
|
set-swipeable-height #(reset! height (oops/oget % "nativeEvent.layout.height"))]
|
||||||
(fn [{:keys [type] :as notification} index _ active-swipeable]
|
(fn [{:keys [type] :as notification} index _ active-swipeable]
|
||||||
(let [swipeable-args {:height height
|
(let [props {:height height
|
||||||
:active-swipeable active-swipeable
|
:active-swipeable active-swipeable
|
||||||
:notification notification}]
|
:set-swipeable-height set-swipeable-height
|
||||||
|
:notification notification
|
||||||
|
:extra-fn (fn [] {:height @height :notification notification})}]
|
||||||
[rn/view {:style (style/notification-container index)}
|
[rn/view {:style (style/notification-container index)}
|
||||||
(cond
|
(cond
|
||||||
(= type types/contact-verification)
|
(= type types/contact-verification)
|
||||||
[contact-verification/view notification {}]
|
[contact-verification/view props]
|
||||||
|
|
||||||
(= type types/contact-request)
|
(= type types/contact-request)
|
||||||
[contact-requests/swipeable swipeable-args
|
[contact-requests/view props]
|
||||||
[contact-requests/view notification set-swipeable-height]]
|
|
||||||
|
|
||||||
(= type types/mention)
|
(= type types/mention)
|
||||||
[mentions/swipeable swipeable-args
|
[mentions/view props]
|
||||||
[mentions/view notification set-swipeable-height]]
|
|
||||||
|
|
||||||
(= type types/reply)
|
(= type types/reply)
|
||||||
[reply/swipeable swipeable-args
|
[reply/view props]
|
||||||
[reply/view notification set-swipeable-height]]
|
|
||||||
|
|
||||||
(= type types/admin)
|
(= type types/admin)
|
||||||
[admin/swipeable swipeable-args
|
[admin/view props]
|
||||||
[admin/view notification set-swipeable-height]]
|
|
||||||
|
|
||||||
(some types/membership [type])
|
(some types/membership [type])
|
||||||
[membership/view notification]
|
[membership/view props]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
nil)]))))
|
nil)]))))
|
||||||
|
@ -286,7 +286,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
|||||||
|
|
||||||
self.home_1.just_fyi("Mark it as read and check filter")
|
self.home_1.just_fyi("Mark it as read and check filter")
|
||||||
reply_element.swipe_right_on_element()
|
reply_element.swipe_right_on_element()
|
||||||
self.home_1.activity_left_swipe_button.click()
|
self.home_1.activity_notification_swipe_button.click()
|
||||||
if reply_element.is_element_displayed(2):
|
if reply_element.is_element_displayed(2):
|
||||||
self.errors.append("Message is not marked as read!")
|
self.errors.append("Message is not marked as read!")
|
||||||
self.home_1.activity_unread_filter_button.click()
|
self.home_1.activity_unread_filter_button.click()
|
||||||
@ -295,7 +295,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
|||||||
|
|
||||||
self.home_1.just_fyi("Mark it as unread and check filter via right swipe")
|
self.home_1.just_fyi("Mark it as unread and check filter via right swipe")
|
||||||
reply_element.swipe_right_on_element()
|
reply_element.swipe_right_on_element()
|
||||||
self.home_1.activity_left_swipe_button.click()
|
self.home_1.activity_notification_swipe_button.click()
|
||||||
if not reply_element.unread_indicator.is_element_displayed():
|
if not reply_element.unread_indicator.is_element_displayed():
|
||||||
self.errors.append("No unread dot is shown on activity center element after marking it as unread!")
|
self.errors.append("No unread dot is shown on activity center element after marking it as unread!")
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
|
|||||||
self.home_1.just_fyi("Delete it from unread via left swipe")
|
self.home_1.just_fyi("Delete it from unread via left swipe")
|
||||||
self.home_1.open_activity_center_button.click()
|
self.home_1.open_activity_center_button.click()
|
||||||
reply_element.swipe_left_on_element()
|
reply_element.swipe_left_on_element()
|
||||||
self.home_1.activity_right_swipe_button.click()
|
self.home_1.activity_notification_swipe_button.click()
|
||||||
if reply_element.is_element_displayed():
|
if reply_element.is_element_displayed():
|
||||||
self.errors.append("Reply is still shown after removing from activity centre!")
|
self.errors.append("Reply is still shown after removing from activity centre!")
|
||||||
|
|
||||||
|
@ -254,8 +254,7 @@ class HomeView(BaseView):
|
|||||||
# Activity centre
|
# Activity centre
|
||||||
self.mention_activity_tab_button = ActivityTabButton(self.driver, accessibility_id="tab-mention")
|
self.mention_activity_tab_button = ActivityTabButton(self.driver, accessibility_id="tab-mention")
|
||||||
self.reply_activity_tab_button = ActivityTabButton(self.driver, accessibility_id="tab-reply")
|
self.reply_activity_tab_button = ActivityTabButton(self.driver, accessibility_id="tab-reply")
|
||||||
self.activity_right_swipe_button = Button(self.driver, accessibility_id="notification-right-swipe")
|
self.activity_notification_swipe_button = Button(self.driver, accessibility_id="notification-swipe")
|
||||||
self.activity_left_swipe_button = Button(self.driver, accessibility_id="notification-left-swipe")
|
|
||||||
self.activity_unread_filter_button = Button(self.driver, accessibility_id="selector-filter")
|
self.activity_unread_filter_button = Button(self.driver, accessibility_id="selector-filter")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user