🗑 Delete message UI

️ Add flag to hide message in UI, there are some bugs in rebuild list process
Don't rebuild, just update the UI state
Update delete to soft delete. Some traces of delete already exist in the app

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Shivek Khurana 2021-07-28 14:14:26 +05:30 committed by Andrea Maria Piana
parent 81f081e47d
commit 8ec46a0d78
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
8 changed files with 112 additions and 30 deletions

View File

@ -134,6 +134,16 @@
(update-in [:chat/inputs current-chat-id :metadata]
dissoc :sending-image))}))
(fx/defn soft-delete-message
"Does't delete from db, this is a soft delete"
{:events [:chat.ui/soft-delete-message]}
[{:keys [db] :as cofx} {:keys [message-id chat-id]}]
{::json-rpc/call [{:method "wakuext_deleteMessageAndSend"
:params [message-id]
:js-response true
:on-error #(log/error "failed to delete message message " %)
:on-success #(re-frame/dispatch [::chat.message/handle-removed-messages [message-id]])}]})
(fx/defn cancel-message-reply
"Cancels stage message reply"
{:events [:chat.ui/cancel-message-reply]}

View File

@ -31,7 +31,7 @@
(defn hide-message
"Hide chat message, rebuild message-list"
[{:keys [db]} chat-id message-id]
;;TODO this is too expensive, probably we could mark message somehow and just hide it in the UI
;; 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))
(fx/defn add-senders-to-chat-users
@ -194,3 +194,34 @@
(fx/defn send-messages
[cofx messages]
(protocol/send-chat-messages cofx messages))
(defn flip-args [f]
(fn [x y] (f y x)))
(defn message-ids->message-id-chat-id-map
"Determine the chat ids of a seq of message-ids"
[db message-ids]
(->> db
:messages ; get messages map
seq ; convert it to seq
(map second) ; get values of messages map -> message-id : message-obj
(into {}) ; convert message-id : message-obj seq to map
((flip-args select-keys) message-ids) ; select the message objects of the ids in question
vals ; keep only the values of required messages
(map #(select-keys % [:chat-id :message-id])))) ; return the chat-id and message-id of required messages
(fx/defn handle-removed-messages
{:events [::handle-removed-messages]}
[{:keys [db]} removed-messages]
(let [mcids (message-ids->message-id-chat-id-map db removed-messages)]
{:db (reduce (fn [acc current]
(update-in acc [:messages (:chat-id current)] dissoc (:message-id current)))
db mcids)}))
(comment
(handle-removed-messages
{:db {:messages {:c1 {:m1 {:chat-id :c1 :message-id :m1}
:m2 {:chat-id :c1 :message-id :m2}}
:c2 {:m3 {:chat-id :c2 :message-id :m3}
:m4 {:chat-id :c2 :message-id :m4}}}}}
[:m1 :m3]))

View File

@ -39,6 +39,7 @@
"wakuext_post" {}
"wakuext_requestAllHistoricMessages" {}
"wakuext_editMessage" {}
"wakuext_deleteMessageAndSend" {}
"wakuext_fillGaps" {}
"wakuext_syncChatFromSyncedFrom" {}
"wakuext_createPublicChat" {}

View File

@ -30,18 +30,19 @@
(fx/defn process-response
{:events [:process-response]}
[{:keys [db] :as cofx} ^js response-js process-async]
(let [^js communities (.-communities response-js)
(let [^js communities (.-communities response-js)
^js requests-to-join-community (.-requestsToJoinCommunity response-js)
^js chats (.-chats response-js)
^js contacts (.-contacts response-js)
^js installations (.-installations response-js)
^js messages (.-messages response-js)
^js emoji-reactions (.-emojiReactions response-js)
^js invitations (.-invitations response-js)
^js removed-chats (.-removedChats response-js)
^js activity-notifications (.-activityCenterNotifications response-js)
^js pin-messages (.-pinMessages response-js)
sync-handler (when-not process-async process-response)]
^js chats (.-chats response-js)
^js contacts (.-contacts response-js)
^js installations (.-installations response-js)
^js messages (.-messages response-js)
^js emoji-reactions (.-emojiReactions response-js)
^js invitations (.-invitations response-js)
^js removed-chats (.-removedChats response-js)
^js activity-notifications (.-activityCenterNotifications response-js)
^js pin-messages (.-pinMessages response-js)
^js removed-messages (.-removedMessages response-js)
sync-handler (when-not process-async process-response)]
(cond
@ -122,7 +123,14 @@
(js-delete response-js "invitations")
(fx/merge cofx
(process-next response-js sync-handler)
(models.group/handle-invitations (map data-store.invitations/<-rpc invitations)))))))
(models.group/handle-invitations (map data-store.invitations/<-rpc invitations))))
(seq removed-messages)
(let [removed-messages-clj (types/js->clj removed-messages)]
(js-delete response-js "removedMessages")
(fx/merge cofx
(process-next response-js sync-handler)
(models.message/handle-removed-messages removed-messages-clj))))))
(defn group-by-and-update-unviewed-counts
"group messages by current chat, profile updates, transactions and update unviewed counters in db for not curent chats"

View File

@ -323,7 +323,9 @@
(when (not= (/ width k) (first @dimensions))
(reset! dimensions [(/ width k) image-max-height]))))))
(defn message-content-image [{:keys [content outgoing in-popover?] :as message} {:keys [on-long-press]}]
(defn message-content-image
[{:keys [content outgoing in-popover?] :as message}
{:keys [on-long-press]}]
(let [dimensions (reagent/atom [image-max-width image-max-height])
visible (reagent/atom false)
uri (:image content)]
@ -384,16 +386,25 @@
(concat
(when (and outgoing edit-enabled)
[{:on-press #(re-frame/dispatch [:chat.ui/edit-message message])
:label (i18n/label :t/edit)}])
:label (i18n/label :t/edit)
:id :edit}])
(when show-input?
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
:label (i18n/label :t/message-reply)}])
:label (i18n/label :t/message-reply)
:id :reply}])
[{:on-press #(react/copy-to-clipboard
(components.reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/sharing-copy-to-clipboard)}]
(when message-pin-enabled [{:on-press #(pin-message message)
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))
:label (i18n/label :t/sharing-copy-to-clipboard)
:id :copy}]
(when message-pin-enabled
[{:on-press #(pin-message message)
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))
:id (if pinned :unpin :pin)}])
(when outgoing
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
:label (i18n/label :t/delete)
:id :delete}]))))
(defn collapsible-text-message [{:keys [mentioned]} _]
(let [collapsed? (reagent/atom false)

View File

@ -1,6 +1,7 @@
(ns status-im.ui.screens.chat.message.reactions-picker
(:require [cljs-bean.core :as bean]
[status-im.ui.screens.chat.message.styles :as styles]
[status-im.ui.components.icons.icons :as icons]
[status-im.constants :as constants]
[reagent.core :as reagent]
[quo.react-native :as rn]
@ -18,6 +19,14 @@
(def translate-x 27)
(def translate-y -24)
(def id-icon
{"edit" :main-icons/edit
"pin" :main-icons/pin
"unpin" :main-icons/pin
"copy" :main-icons/copy
"reply" :main-icons/reply
"delete" :main-icons/delete})
(defn picker [{:keys [outgoing actions own-reactions on-close send-emoji timeline]}]
[rn/view {:style (styles/container-style {:outgoing outgoing :timeline timeline})}
[rn/view {:style (styles/reactions-picker-row)}
@ -26,21 +35,25 @@
:let [active (own-reactions id)]]
^{:key id}
[rn/touchable-opacity {:accessibility-label (str "pick-emoji-" id)
:on-press #(send-emoji id)}
:on-press #(send-emoji id)}
[rn/view {:style (styles/reaction-button active)}
[rn/image {:source resource
:style {:height 32
:width 32}}]]]))]
(when (seq actions)
[rn/view {:style (styles/quick-actions-row)}
[rn/view {:style (styles/quick-actions-container)}
(for [action actions
:let [{:keys [label on-press]} (bean/bean action)]]
^{:key label}
:let [{:keys [id label on-press]} (bean/bean action)]]
^{:key id}
[rn/touchable-opacity {:on-press (fn []
(on-close)
(js/setTimeout on-press animation-duration))}
[quo/button {:type :secondary}
label]])])])
[rn/view {:style (styles/quick-actions-row)}
[quo/text {:color (if (= id "delete") :negative :link)
:weight :medium} label]
;; fallback to warning icon if id to icon mapping is not defined
[icons/icon (get id-icon id :main-icons/warning)
{:color (if (= id "delete") :red :blue)}]]])])])
(def modal
(reagent/adapt-react-class

View File

@ -35,12 +35,20 @@
:padding-vertical 8
:padding-horizontal 8})
(defn quick-actions-row []
{:flex-direction :row
(defn quick-actions-container []
{:flex-direction :column
:justify-content :space-evenly
:border-top-width 1
:border-top-color (:ui-01 @colors/theme)})
(defn quick-actions-row []
{:flex-direction :row
:padding-horizontal 16
:padding-vertical 12
:justify-content :space-between
:border-top-width 1
:border-top-color (:ui-01 @colors/theme)})
(defn reaction-style [{:keys [outgoing own]}]
(merge {:border-top-left-radius 10
:border-top-right-radius 10

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im",
"repo": "status-go",
"version": "v0.83.5",
"commit-sha1": "89251e841655082076ef304791b9ee3145f337c2",
"src-sha256": "0f0mw5bv4rwi6i9q4xa7shrjd8r4qwq5ky7lm6jjszyrqwhhf74j"
"version": "v0.83.9",
"commit-sha1": "7dfeda15110af8ae315f41d19db39476a8e28d62",
"src-sha256": "12v2k8679kl8gca6ihpn954rblpfdsi95kcaxpm39dahlg5ax2v9"
}