Fix pinned messages & replies
e8ceed11...213dc463
Both replies and pinned messages relied on subscribing their data from messages.
This worked only as long as we loaded the message in the database, so it would break say if another user replied to a message that wasn't in the current user view.
It also changes the way pinned messages are handled, before the notification was actually sent over the wire, but that's unnecessary, since it can be generated locally on both parts.
This is a bit of a breaking change with the previous version, since if you pin a message with this version, older version will not see a system message. this can be easily fixed by restoring the previous behavior of sending the message, but not sure it's worth it.
It also adds the ability to Delete message for everyone that have Deleted for me (discussed with John) and the ability of unpin messages that have been deleted for me.
This commit is contained in:
parent
fd7797322f
commit
2438af4e00
|
@ -239,10 +239,7 @@
|
|||
:on-error #(log/error "failed to edit message " %)
|
||||
:on-success (fn [result]
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response
|
||||
result])
|
||||
(when pinned-message
|
||||
(re-frame/dispatch [:pin-message/load-pin-messages
|
||||
chat-id])))}]}
|
||||
result]))}]}
|
||||
(cancel-message-edit))))
|
||||
|
||||
(rf/defn send-current-message
|
||||
|
|
|
@ -32,16 +32,30 @@
|
|||
;; TODO this is too expensive, probably we could mark message somehow and just hide it in the UI
|
||||
(message-list/rebuild-message-list {:db (update-in db [:messages chat-id] dissoc message-id)} chat-id))
|
||||
|
||||
(defn add-pinned-message
|
||||
[acc chat-id message-id message]
|
||||
(let [{:keys [pinned-by pinned-at] :as pinned-message}
|
||||
(get-in acc [:db :pin-messages chat-id message-id])]
|
||||
(if pinned-message
|
||||
(assoc-in acc
|
||||
[:db :pin-messages chat-id message-id]
|
||||
(assoc
|
||||
message
|
||||
:pinned-by pinned-by
|
||||
:pinned-at pinned-at))
|
||||
acc)))
|
||||
|
||||
(defn add-message
|
||||
[{:keys [db] :as acc} message-js chat-id message-id cursor-clock-value]
|
||||
(let [{:keys [replace from clock-value] :as message}
|
||||
(data-store.messages/<-rpc (types/js->clj message-js))]
|
||||
(data-store.messages/<-rpc (types/js->clj message-js))
|
||||
acc-with-pinned-message (add-pinned-message acc chat-id message-id message)]
|
||||
(if (message-loaded? db chat-id message-id)
|
||||
;; If the message is already loaded, it means it's an update, that
|
||||
;; happens when a message that was missing a reply had the reply
|
||||
;; coming through, in which case we just insert the new message
|
||||
(assoc-in acc [:db :messages chat-id message-id] message)
|
||||
(cond-> acc
|
||||
(assoc-in acc-with-pinned-message [:db :messages chat-id message-id] message)
|
||||
(cond-> acc-with-pinned-message
|
||||
;;add new message to db
|
||||
:always
|
||||
(update-in [:db :messages chat-id] assoc message-id message)
|
||||
|
|
|
@ -46,7 +46,10 @@
|
|||
|
||||
(update :quoted-message
|
||||
set/rename-keys
|
||||
{:parsedText :parsed-text :communityId :community-id})
|
||||
{:parsedText :parsed-text
|
||||
:deleted :deleted?
|
||||
:deletedForMe :deleted-for-me?
|
||||
:communityId :community-id})
|
||||
(update :outgoing-status keyword)
|
||||
(update :command-parameters
|
||||
set/rename-keys
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
(rf/defn send-pin-message
|
||||
[cofx pin-message]
|
||||
{:json-rpc/call [{:method "wakuext_sendPinMessage"
|
||||
:params [(messages/->rpc pin-message)]
|
||||
:on-success #(log/debug "successfully pinned message" pin-message)
|
||||
:on-error #(log/error "failed to pin message" % pin-message)}]})
|
||||
{:json-rpc/call [{:method "wakuext_sendPinMessage"
|
||||
:params [(messages/->rpc pin-message)]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to pin message" %)}]})
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[status-im.data-store.activities :as data-store.activities]
|
||||
[status-im.data-store.chats :as data-store.chats]
|
||||
[status-im.data-store.invitations :as data-store.invitations]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.data-store.reactions :as data-store.reactions]
|
||||
[status-im.group-chats.core :as models.group]
|
||||
[status-im.multiaccounts.login.core :as multiaccounts.login]
|
||||
|
@ -44,7 +43,7 @@
|
|||
^js removed-chats (.-removedChats response-js)
|
||||
^js activity-notifications (.-activityCenterNotifications response-js)
|
||||
^js activity-center-state (.-activityCenterState response-js)
|
||||
^js pin-messages (.-pinMessages response-js)
|
||||
^js pin-messages-js (.-pinMessages response-js)
|
||||
^js removed-messages (.-removedMessages response-js)
|
||||
^js visibility-status-updates (.-statusUpdates response-js)
|
||||
^js current-visibility-status (.-currentStatus response-js)
|
||||
|
@ -109,12 +108,12 @@
|
|||
(process-next response-js sync-handler)
|
||||
(browser/handle-bookmarks bookmarks-clj)))
|
||||
|
||||
(seq pin-messages)
|
||||
(let [pin-messages (types/js->clj pin-messages)]
|
||||
(seq pin-messages-js)
|
||||
(do
|
||||
(js-delete response-js "pinMessages")
|
||||
(rf/merge cofx
|
||||
(process-next response-js sync-handler)
|
||||
(messages.pin/receive-signal (map data-store.messages/<-rpc pin-messages))))
|
||||
(messages.pin/receive-signal pin-messages-js)))
|
||||
|
||||
(seq removed-chats)
|
||||
(let [removed-chats-clj (types/js->clj removed-chats)]
|
||||
|
|
|
@ -258,8 +258,9 @@
|
|||
(merge
|
||||
(when in-popover? {:number-of-lines 2})
|
||||
(cond
|
||||
(= content-type constants/content-type-system-text) (system-text-style)
|
||||
:else (default-text-style))))
|
||||
(= content-type constants/content-type-system-text) (system-text-style)
|
||||
(= content-type constants/content-type-system-pinned-message) (system-text-style)
|
||||
:else (default-text-style))))
|
||||
|
||||
(defn emph-text-style
|
||||
[]
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[status-im2.constants :as constants]
|
||||
[status-im.ethereum.stateofus :as stateofus]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im2.contexts.chat.messages.avatar.view :as avatar]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.ui2.screens.chat.components.reply.style :as style]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
@ -65,9 +65,9 @@
|
|||
(i18n/label :t/message-deleted)]])
|
||||
|
||||
(defn reply-from
|
||||
[{:keys [from identicon contact-name current-public-key]}]
|
||||
[{:keys [from contact-name current-public-key]}]
|
||||
[rn/view {:style style/reply-from}
|
||||
[photos/member-photo from identicon 16]
|
||||
[avatar/avatar from :xxxs]
|
||||
[quo2.text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
|
||||
(defn system-text?
|
||||
[content-type]
|
||||
(= content-type constants/content-type-system-text))
|
||||
(or
|
||||
(= content-type constants/content-type-system-text)
|
||||
(= content-type constants/content-type-system-pinned-message)))
|
||||
|
||||
(defn mention-element
|
||||
[from]
|
||||
|
@ -142,11 +144,9 @@
|
|||
(:parsed-text content))))
|
||||
|
||||
(defn quoted-message
|
||||
[{:keys [message-id chat-id]} pin?]
|
||||
(let [quoted-message (get @(re-frame/subscribe [:chats/chat-messages chat-id])
|
||||
message-id)]
|
||||
[rn/view {:style (when-not pin? (style/quoted-message-container))}
|
||||
[components.reply/reply-message quoted-message false pin?]]))
|
||||
[quoted-message pin?]
|
||||
[rn/view {:style (when-not pin? (style/quoted-message-container))}
|
||||
[components.reply/reply-message quoted-message false pin?]])
|
||||
|
||||
(defn message-not-sent-text
|
||||
[chat-id message-id]
|
||||
|
|
|
@ -13,9 +13,13 @@
|
|||
(def ^:const content-type-community 9)
|
||||
(def ^:const content-type-gap 10)
|
||||
(def ^:const content-type-contact-request 11) ;; TODO: temp, will be removed
|
||||
(def ^:const content-type-gif 12)
|
||||
(def ^:const content-type-link 13)
|
||||
(def ^:const content-type-album 14)
|
||||
(def ^:const content-type-system-pinned-message 14)
|
||||
|
||||
;; Not implemented in status-go, only used for testing/ui work
|
||||
(def ^:const content-type-gif 100)
|
||||
(def ^:const content-type-link 101)
|
||||
(def ^:const content-type-album 102)
|
||||
|
||||
|
||||
(def ^:const contact-request-state-none 0)
|
||||
(def ^:const contact-request-state-mutual 1)
|
||||
|
|
|
@ -23,11 +23,17 @@
|
|||
(defn- get-message-content
|
||||
[{:keys [content-type] :as message}]
|
||||
(case content-type
|
||||
constants/content-type-text (get-in message [:content :text])
|
||||
constants/content-type-text [quo/text {:style style/tag-text}
|
||||
(get-in message [:content :text])]
|
||||
|
||||
constants/content-type-image [old-message/message-content-image message]
|
||||
constants/content-type-image [old-message/message-content-image message]
|
||||
|
||||
constants/content-type-sticker [old-message/sticker message]
|
||||
constants/content-type-sticker [old-message/sticker message]
|
||||
|
||||
constants/content-type-system-pinned-message
|
||||
[not-implemented/not-implemented
|
||||
[quo/text {:style style/tag-text}
|
||||
(get-in message [:content :text])]]
|
||||
|
||||
;; NOTE: The following type (system-text) doesn't have a design yet.
|
||||
;; https://github.com/status-im/status-mobile/issues/14915
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
;; TODO (flexsurfer) probably we don't want reactions here
|
||||
(if (or deleted? deleted-for-me?)
|
||||
[content.deleted/deleted-message message context]
|
||||
[message/message-with-reactions message context false]))
|
||||
[message/message-with-reactions message context]))
|
||||
|
||||
(defn pinned-messages
|
||||
[chat-id]
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
(ns status-im2.contexts.chat.messages.avatar.view
|
||||
(:require [utils.re-frame :as rf]
|
||||
[react-native.core :as rn]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(defn avatar
|
||||
[public-key size]
|
||||
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity public-key]))
|
||||
contact (rf/sub [:contacts/contact-by-address public-key])
|
||||
photo-path (when (seq (:images contact)) (rf/sub [:chats/photo-path public-key]))
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
||||
[rn/touchable-without-feedback {:on-press #(rf/dispatch [:chat.ui/show-profile public-key])}
|
||||
[rn/view {:padding-top 2}
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? true
|
||||
:online? online?
|
||||
:size size}]]]))
|
|
@ -26,10 +26,10 @@
|
|||
(i18n/label :t/deleted-this-message)]])
|
||||
|
||||
(defn- compute-on-long-press-fn
|
||||
[{:keys [deleted? pinned deleted-for-me?] :as message}
|
||||
{:keys [message-pin-enabled] :as context}]
|
||||
[{:keys [deleted?] :as message}
|
||||
context]
|
||||
;; only show drawer for user who has the permission to unpin messages
|
||||
(when (and pinned (or deleted? deleted-for-me?) message-pin-enabled)
|
||||
(when-not deleted?
|
||||
(fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
(ns status-im2.contexts.chat.messages.content.pin.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def system-message-default-size 36)
|
||||
(def system-message-radius (/ system-message-default-size 2))
|
||||
|
||||
(def pin-indicator-container
|
||||
{:margin-top 4
|
||||
:margin-left 54
|
||||
|
@ -16,3 +19,22 @@
|
|||
(defn pinned-message-text
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(def system-message-container
|
||||
{:flex-direction :row :margin-vertical 8})
|
||||
|
||||
(def system-message-inner-container
|
||||
{:width system-message-default-size
|
||||
:height system-message-default-size
|
||||
:margin-right system-message-radius
|
||||
:border-radius system-message-default-size
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color colors/primary-50-opa-10})
|
||||
|
||||
(def system-message-author-container
|
||||
{:flex-direction :row :align-items :center})
|
||||
|
||||
(def system-message-timestamp-container
|
||||
{:padding-left 5
|
||||
:margin-top 2})
|
||||
|
|
|
@ -24,42 +24,33 @@
|
|||
author-name]]))
|
||||
|
||||
(defn system-message
|
||||
[{:keys [from in-popover? timestamp-str chat-id] :as message}]
|
||||
(let [response-to (:response-to (:content message))
|
||||
default-size 36]
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]))
|
||||
:active-opacity 1
|
||||
:style (merge {:flex-direction :row :margin-vertical 8}
|
||||
(old-style/message-wrapper message))}
|
||||
[rn/view
|
||||
{:style {:width default-size
|
||||
:height default-size
|
||||
:margin-right 16
|
||||
:border-radius default-size
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color colors/primary-50-opa-10}
|
||||
:accessibility-label :content-type-pin-icon}
|
||||
[quo/icon :i/pin {:color colors/primary-50 :size 16}]]
|
||||
[rn/view
|
||||
[rn/view {:style {:flex-direction :row :align-items :center}}
|
||||
[rn/touchable-opacity
|
||||
{:style old-style/message-author-touchable
|
||||
:disabled in-popover?
|
||||
:on-press #(rf/dispatch [:chat.ui/show-profile from])}
|
||||
[old-message/message-author-name from {} 20]]
|
||||
[quo/text
|
||||
{:size :label
|
||||
:style (style/pinned-message-text)}
|
||||
(str " " (i18n/label :t/pinned-a-message))]
|
||||
[rn/text
|
||||
{:style (merge
|
||||
{:padding-left 5
|
||||
:margin-top 2}
|
||||
(old-style/message-timestamp-text))
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]]
|
||||
[old-message/quoted-message {:message-id response-to :chat-id chat-id} true]]]))
|
||||
[{:keys [from in-popover? quoted-message timestamp-str chat-id] :as message}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]))
|
||||
:active-opacity 1
|
||||
:style (merge style/system-message-container
|
||||
(old-style/message-wrapper message))}
|
||||
[rn/view
|
||||
{:style style/system-message-inner-container
|
||||
:accessibility-label :content-type-pin-icon}
|
||||
[quo/icon :i/pin {:color colors/primary-50 :size 16}]]
|
||||
[rn/view
|
||||
[rn/view {:style style/system-message-author-container}
|
||||
[rn/touchable-opacity
|
||||
{:style old-style/message-author-touchable
|
||||
:disabled in-popover?
|
||||
:on-press #(rf/dispatch [:chat.ui/show-profile from])}
|
||||
[old-message/message-author-name from {} 20]]
|
||||
[quo/text
|
||||
{:size :label
|
||||
:style (style/pinned-message-text)}
|
||||
(str " " (i18n/label :t/pinned-a-message))]
|
||||
[rn/text
|
||||
{:style (merge
|
||||
style/system-message-timestamp-container
|
||||
(old-style/message-timestamp-text))
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]]
|
||||
[old-message/quoted-message quoted-message true]]])
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[status-im2.contexts.chat.messages.content.status.view :as status]
|
||||
[status-im2.contexts.chat.messages.content.system.text.view :as system.text]
|
||||
[status-im2.contexts.chat.messages.content.album.view :as album]
|
||||
[status-im2.contexts.chat.messages.avatar.view :as avatar]
|
||||
[status-im2.contexts.chat.messages.content.image.view :as image]
|
||||
[quo2.core :as quo]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -23,35 +24,24 @@
|
|||
|
||||
(def delivery-state-showing-time-ms 3000)
|
||||
|
||||
(defn avatar
|
||||
[{:keys [content last-in-group? pinned quoted-message from]}]
|
||||
(defn avatar-container
|
||||
[{:keys [content last-in-group? pinned-by quoted-message from]}]
|
||||
(if (or (and (seq (:response-to content))
|
||||
quoted-message)
|
||||
last-in-group?
|
||||
pinned)
|
||||
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
|
||||
contact (rf/sub [:contacts/contact-by-address from])
|
||||
photo-path (when-not (empty? (:images contact)) (rf/sub [:chats/photo-path from]))
|
||||
online? (rf/sub [:visibility-status-updates/online? from])]
|
||||
[rn/touchable-without-feedback {:on-press #(rf/dispatch [:chat.ui/show-profile from])}
|
||||
[rn/view {:padding-top 2 :width 32}
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? true
|
||||
:online? online?
|
||||
:size :small}]]])
|
||||
pinned-by)
|
||||
[avatar/avatar from :small]
|
||||
[rn/view {:padding-top 2 :width 32}]))
|
||||
|
||||
(defn author
|
||||
[{:keys [response-to
|
||||
compressed-key
|
||||
last-in-group?
|
||||
pinned
|
||||
pinned-by
|
||||
quoted-message
|
||||
from
|
||||
timestamp]}]
|
||||
(when (or (and (seq response-to) quoted-message) last-in-group? pinned)
|
||||
(when (or (and (seq response-to) quoted-message) last-in-group? pinned-by)
|
||||
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
|
||||
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
|
||||
[quo/author
|
||||
|
@ -65,17 +55,18 @@
|
|||
(defn system-message-content
|
||||
[{:keys [content-type quoted-message] :as message-data}]
|
||||
(if quoted-message
|
||||
[not-implemented/not-implemented [pin/system-message message-data]]
|
||||
[pin/system-message message-data]
|
||||
(case content-type
|
||||
|
||||
constants/content-type-system-text [not-implemented/not-implemented
|
||||
[system.text/text-content message-data]]
|
||||
constants/content-type-system-text [system.text/text-content message-data]
|
||||
|
||||
constants/content-type-community [not-implemented/not-implemented
|
||||
[old-message/community message-data]]
|
||||
constants/content-type-system-pinned-message [system.text/text-content message-data]
|
||||
|
||||
constants/content-type-contact-request [not-implemented/not-implemented
|
||||
[old-message/system-contact-request message-data]])))
|
||||
constants/content-type-community [not-implemented/not-implemented
|
||||
[old-message/community message-data]]
|
||||
|
||||
constants/content-type-contact-request [not-implemented/not-implemented
|
||||
[old-message/system-contact-request message-data]])))
|
||||
|
||||
(defn on-long-press
|
||||
[message-data context]
|
||||
|
@ -87,7 +78,7 @@
|
|||
[]
|
||||
(let [show-delivery-state? (reagent/atom false)]
|
||||
(fn [{:keys [content-type quoted-message content outgoing outgoing-status] :as message-data}
|
||||
{:keys [chat-id] :as context}
|
||||
context
|
||||
keyboard-shown]
|
||||
(let [first-image (first (:album message-data))
|
||||
outgoing-status (if (= content-type constants/content-type-album)
|
||||
|
@ -117,11 +108,11 @@
|
|||
:on-long-press #(on-long-press message-data context)}
|
||||
[rn/view {:style {:padding-vertical 8}}
|
||||
(when (and (seq response-to) quoted-message)
|
||||
[old-message/quoted-message {:message-id response-to :chat-id chat-id}])
|
||||
[old-message/quoted-message quoted-message])
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 12
|
||||
:flex-direction :row}}
|
||||
[avatar message-data]
|
||||
[avatar-container message-data]
|
||||
[rn/view
|
||||
{:style {:margin-left 8
|
||||
:flex 1}}
|
||||
|
@ -159,6 +150,7 @@
|
|||
(when pinned-by
|
||||
[pin/pinned-by-view pinned-by])
|
||||
(if (#{constants/content-type-system-text constants/content-type-community
|
||||
constants/content-type-system-pinned-message
|
||||
constants/content-type-contact-request}
|
||||
content-type)
|
||||
[system-message-content message-data]
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
(assoc message-data :pinned message-not-pinned?)]))))
|
||||
|
||||
(defn get-actions
|
||||
[{:keys [outgoing content pinned outgoing-status deleted? deleted-for-me? content-type]
|
||||
[{:keys [outgoing content pinned-by outgoing-status deleted? deleted-for-me? content-type]
|
||||
:as message-data}
|
||||
{:keys [able-to-send-message? community? can-delete-message-for-everyone?
|
||||
message-pin-enabled group-chat group-admin?]}]
|
||||
|
@ -54,15 +54,17 @@
|
|||
:icon :i/copy
|
||||
:id :copy}])
|
||||
;; pinning images are temporarily disabled
|
||||
(when (and message-pin-enabled (not= content-type constants/content-type-image))
|
||||
(when (and message-pin-enabled
|
||||
(not (or deleted? deleted-for-me?))
|
||||
(not= content-type constants/content-type-image))
|
||||
[{:type :main
|
||||
:on-press #(pin-message message-data)
|
||||
:label (i18n/label (if pinned
|
||||
:label (i18n/label (if pinned-by
|
||||
(if community? :t/unpin-from-channel :t/unpin-from-chat)
|
||||
(if community? :t/pin-to-channel :t/pin-to-chat)))
|
||||
:icon :i/pin
|
||||
:id (if pinned :unpin :pin)}])
|
||||
(when-not (or pinned deleted? deleted-for-me?)
|
||||
:id (if pinned-by :unpin :pin)}])
|
||||
(when-not (or deleted? deleted-for-me?)
|
||||
[{:type :danger
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
|
@ -74,12 +76,11 @@
|
|||
:icon :i/delete
|
||||
:id :delete-for-me}])
|
||||
(when (cond
|
||||
deleted? false
|
||||
deleted-for-me? false
|
||||
outgoing true
|
||||
community? can-delete-message-for-everyone?
|
||||
group-chat group-admin?
|
||||
:else false)
|
||||
deleted? false
|
||||
outgoing true
|
||||
community? can-delete-message-for-everyone?
|
||||
group-chat group-admin?
|
||||
:else false)
|
||||
[{:type :danger
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
|
|
|
@ -27,12 +27,10 @@
|
|||
|
||||
(defn banner
|
||||
[chat-id]
|
||||
(let [pinned-messages (rf/sub [:chats/pinned-sorted-list chat-id])
|
||||
latest-pinned-message-id (-> pinned-messages last :message-id)
|
||||
latest-pinned-message (get (rf/sub [:chats/chat-messages chat-id]) latest-pinned-message-id)
|
||||
latest-pin-text (get-in latest-pinned-message [:content :parsed-text])
|
||||
{:keys [deleted? deleted-for-me?]} latest-pinned-message
|
||||
pins-count (count pinned-messages)
|
||||
(let [pinned-message (rf/sub [:chats/last-pinned-message chat-id])
|
||||
latest-pin-text (get-in pinned-message [:content :parsed-text])
|
||||
{:keys [deleted? deleted-for-me?]} pinned-message
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])
|
||||
|
||||
latest-pin-text
|
||||
(cond deleted? (i18n/label :t/message-deleted-for-everyone)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [quo2.foundations.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.pin-messages :as data-store.pin-messages]
|
||||
[status-im.transport.message.protocol :as protocol]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im2.common.toasts.events :as toasts]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.messages.list.events :as message-list]
|
||||
|
@ -33,34 +33,48 @@
|
|||
(assoc-in [:pagination-info chat-id :all-pin-loaded?]
|
||||
(empty? cursor)))}))
|
||||
|
||||
(defn remove-pinned-message
|
||||
[db pinned-message]
|
||||
(update-in db
|
||||
[:pin-messages (aget pinned-message "localChatId")]
|
||||
dissoc
|
||||
(aget pinned-message "message_id")))
|
||||
|
||||
(defn add-pinned-message
|
||||
[db pinned-message]
|
||||
(let [message (aget pinned-message "pinnedMessage")]
|
||||
(if (and message
|
||||
(aget message "message"))
|
||||
(assoc-in db
|
||||
[:pin-messages
|
||||
(aget pinned-message "localChatId")
|
||||
(aget pinned-message "message_id")]
|
||||
(-> (aget message "message")
|
||||
(js->clj :keywordize-keys true)
|
||||
data-store.messages/<-rpc
|
||||
(assoc :pinned-by (aget message "pinnedBy")
|
||||
:pinned-at (aget message "pinnedAt"))))
|
||||
db)))
|
||||
|
||||
(rf/defn receive-signal
|
||||
[{:keys [db]} pin-messages]
|
||||
(let [{:keys [chat-id]} (first pin-messages)]
|
||||
(when (= chat-id (db :current-chat-id))
|
||||
(let [{:keys [chat-id]} (first pin-messages)
|
||||
already-loaded-pin-messages (get-in db [:pin-messages chat-id] {})
|
||||
already-loaded-messages (get-in db [:messages chat-id] {})
|
||||
all-messages (reduce (fn [acc {:keys [message_id pinned from]}]
|
||||
;; Add to or remove from pinned message list, and
|
||||
;; normalizing pinned-by property
|
||||
(let [current-message (get already-loaded-messages
|
||||
message_id)
|
||||
current-message-pin (merge current-message
|
||||
{:pinned pinned
|
||||
:pinned-by from})]
|
||||
(cond-> acc
|
||||
(nil? pinned)
|
||||
(dissoc message_id)
|
||||
|
||||
(and (some? pinned) (some? current-message))
|
||||
(assoc message_id current-message-pin))))
|
||||
already-loaded-pin-messages
|
||||
pin-messages)]
|
||||
{:db (-> db
|
||||
(assoc-in [:pin-messages chat-id] all-messages)
|
||||
(assoc-in [:pin-message-lists chat-id]
|
||||
(message-list/add-many nil (vals all-messages))))}))))
|
||||
|
||||
(let [current-chat-id (db :current-chat-id)
|
||||
db (reduce (fn [db pin-message]
|
||||
(let [pinned? (aget pin-message "pinned")
|
||||
chat-id (aget pin-message "localChatId")]
|
||||
(cond
|
||||
(not= chat-id current-chat-id)
|
||||
db
|
||||
pinned?
|
||||
(add-pinned-message db pin-message)
|
||||
:else
|
||||
(remove-pinned-message db pin-message))))
|
||||
db
|
||||
pin-messages)]
|
||||
{:db
|
||||
(assoc-in db
|
||||
[:pin-message-lists current-chat-id]
|
||||
(message-list/add-many nil (vals (get-in db [:pin-messages current-chat-id]))))}))
|
||||
|
||||
(rf/defn send-pin-message-locally
|
||||
"Pin message, rebuild pinned messages list locally"
|
||||
|
@ -84,20 +98,11 @@
|
|||
"Pin message, rebuild pinned messages list"
|
||||
{:events [:pin-message/send-pin-message]}
|
||||
[{:keys [db] :as cofx} {:keys [chat-id message-id pinned remote-only?] :as pin-message}]
|
||||
(let [current-public-key (get-in db [:multiaccount :public-key])
|
||||
message (merge pin-message {:pinned-by current-public-key})
|
||||
preferred-name (get-in db [:multiaccount :preferred-name])]
|
||||
(rf/merge cofx
|
||||
(when-not remote-only? (send-pin-message-locally pin-message))
|
||||
(data-store.pin-messages/send-pin-message {:chat-id (pin-message :chat-id)
|
||||
:message_id (pin-message :message-id)
|
||||
:pinned (pin-message :pinned)})
|
||||
(when pinned
|
||||
(protocol/send-chat-messages [{:chat-id (pin-message :chat-id)
|
||||
:content-type constants/content-type-system-text
|
||||
:text "pinned a message"
|
||||
:response-to (pin-message :message-id)
|
||||
:ens-name preferred-name}])))))
|
||||
(rf/merge cofx
|
||||
(when-not remote-only? (send-pin-message-locally pin-message))
|
||||
(data-store.pin-messages/send-pin-message {:chat-id (pin-message :chat-id)
|
||||
:message_id (pin-message :message-id)
|
||||
:pinned (pin-message :pinned)})))
|
||||
|
||||
(rf/defn load-pin-messages
|
||||
{:events [:pin-message/load-pin-messages]}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
(ns status-im2.contexts.chat.messages.pin.events-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im2.contexts.chat.messages.pin.events :as events]))
|
||||
|
||||
(deftest receive-signal-test
|
||||
(let [chat-id "chat-id"
|
||||
message-id-1 "0x1"
|
||||
message-id-2 "0x2"
|
||||
message-id-3 "0x3"
|
||||
message-1 {:id message-id-1 :whisperTimestamp 1 :timestamp 1 :clock 2}
|
||||
message-3 {:id message-id-3 :whisperTimestamp 1 :timestamp 1 :clock 2}
|
||||
db {:current-chat-id chat-id
|
||||
:pin-messages {chat-id {message-id-1 {}
|
||||
message-id-2 {}}}}]
|
||||
(testing "receiving a pinned messages update"
|
||||
(let [pinned-messages-signal (clj->js [{:pinned true
|
||||
:localChatId chat-id
|
||||
:message_id message-id-1
|
||||
:pinnedMessage {:pinnedAt 1
|
||||
:pinnedBy "0x1"
|
||||
:message message-1}}
|
||||
{:pinned false
|
||||
:localChatId chat-id
|
||||
:message_id message-id-2}
|
||||
{:pinned true
|
||||
:localChatId chat-id
|
||||
:message_id message-id-3
|
||||
:pinnedMessage {:pinnedAt 1
|
||||
:pinnedBy "0x1"
|
||||
:message message-3}}])
|
||||
actual (events/receive-signal {:db db}
|
||||
pinned-messages-signal)
|
||||
]
|
||||
(is (not (get-in actual [:db :pin-messages chat-id message-id-2])))
|
||||
(is (get-in actual [:db :pin-messages chat-id message-id-1 :message-id]))
|
||||
(is (get-in actual [:db :pin-messages chat-id message-id-3 :message-id]))))))
|
|
@ -146,22 +146,9 @@
|
|||
|
||||
(re-frame/reg-sub
|
||||
:chats/pinned
|
||||
(fn [[_ chat-id] _]
|
||||
[(re-frame/subscribe [:messages/pin-messages])
|
||||
(re-frame/subscribe [:chats/chat-messages chat-id])])
|
||||
(fn [[pin-messages messages] [_ chat-id]]
|
||||
(let [pinned-messages (get pin-messages chat-id {})]
|
||||
(reduce-kv
|
||||
(fn [pinned-messages pinned-message-id pinned-message]
|
||||
(let [{:keys [deleted? deleted-for-me? deleted-by]} (get messages pinned-message-id)
|
||||
pinned-message (assoc pinned-message
|
||||
:deleted? deleted?
|
||||
:deleted-for-me? deleted-for-me?
|
||||
:deleted-by deleted-by
|
||||
:pinned true)]
|
||||
(assoc pinned-messages pinned-message-id pinned-message)))
|
||||
pinned-messages
|
||||
pinned-messages))))
|
||||
:<- [:messages/pin-messages]
|
||||
(fn [pinned-messages [_ chat-id] _]
|
||||
(get pinned-messages chat-id)))
|
||||
|
||||
;; local messages will not have a :pinned-at key until user navigates away and to
|
||||
;; chat screen. For this reason we want to retain order of local messages with :pinned-at nil
|
||||
|
@ -180,9 +167,22 @@
|
|||
(re-frame/subscribe [:chats/pinned chat-id]))
|
||||
(fn [pin-messages _]
|
||||
(let [pin-messages-vals (vals pin-messages)]
|
||||
|
||||
(sort-by :pinned-at sort-pinned pin-messages-vals))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/last-pinned-message
|
||||
(fn [[_ chat-id]]
|
||||
(re-frame/subscribe [:chats/pinned-sorted-list chat-id]))
|
||||
(fn [pin-messages _]
|
||||
(last pin-messages)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/pin-messages-count
|
||||
(fn [[_ chat-id]]
|
||||
(re-frame/subscribe [:chats/pinned chat-id]))
|
||||
(fn [pinned-messages _]
|
||||
(count pinned-messages)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/pin-modal
|
||||
:<- [:messages/pin-modal]
|
||||
|
|
|
@ -109,92 +109,52 @@
|
|||
(testing "It sorts three messages with pinned-at property"
|
||||
(swap! rf-db/app-db assoc :pin-messages pinned-messages-state)
|
||||
(is
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 1000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}]
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 1000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user}]
|
||||
(rf/sub [sub-name :0xChat]))))
|
||||
(testing "It sorts messages from backend with pinned-at property and 1 new local pinned message"
|
||||
(swap! rf-db/app-db assoc :pin-messages pinned-messages-state-with-1-new-local-message)
|
||||
(is
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}]
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user}]
|
||||
(rf/sub [sub-name :0xChat]))))
|
||||
(testing "It sorts messages from backend with pinned-at property and 2 new local pinned messages"
|
||||
(swap! rf-db/app-db assoc :pin-messages pinned-messages-state-with-2-new-local-messages)
|
||||
(is
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x4
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user
|
||||
:pinned true
|
||||
:deleted? nil
|
||||
:deleted-for-me? nil
|
||||
:deleted-by nil}]
|
||||
(= [{:chat-id :0xChat
|
||||
:message-id :0x1
|
||||
:pinned-at 2000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x2
|
||||
:pinned-at 3000
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x3
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user}
|
||||
{:chat-id :0xChat
|
||||
:message-id :0x4
|
||||
:pinned-at nil
|
||||
:pinned-by :test-user}]
|
||||
(rf/sub [sub-name :0xChat])))))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.146.4",
|
||||
"commit-sha1": "e8ceed11125dfd470c0e0caac0755313fb85cba6",
|
||||
"src-sha256": "1flwq5sfy1cfdl40fiip0q555rdcq5f5l2lpb4az8j5bwmwmi31x"
|
||||
"version": "v0.147.1",
|
||||
"commit-sha1": "213dc463bcc1ae449bc78b6cf7c598c4f68830c5",
|
||||
"src-sha256": "1q00agdsqc4p16l8d5cv88gwfnpnl7bb61mayc3520c82hw93q3r"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue