🗑 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:
parent
81f081e47d
commit
8ec46a0d78
|
@ -134,6 +134,16 @@
|
||||||
(update-in [:chat/inputs current-chat-id :metadata]
|
(update-in [:chat/inputs current-chat-id :metadata]
|
||||||
dissoc :sending-image))}))
|
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
|
(fx/defn cancel-message-reply
|
||||||
"Cancels stage message reply"
|
"Cancels stage message reply"
|
||||||
{:events [:chat.ui/cancel-message-reply]}
|
{:events [:chat.ui/cancel-message-reply]}
|
||||||
|
|
|
@ -194,3 +194,34 @@
|
||||||
(fx/defn send-messages
|
(fx/defn send-messages
|
||||||
[cofx messages]
|
[cofx messages]
|
||||||
(protocol/send-chat-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]))
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
"wakuext_post" {}
|
"wakuext_post" {}
|
||||||
"wakuext_requestAllHistoricMessages" {}
|
"wakuext_requestAllHistoricMessages" {}
|
||||||
"wakuext_editMessage" {}
|
"wakuext_editMessage" {}
|
||||||
|
"wakuext_deleteMessageAndSend" {}
|
||||||
"wakuext_fillGaps" {}
|
"wakuext_fillGaps" {}
|
||||||
"wakuext_syncChatFromSyncedFrom" {}
|
"wakuext_syncChatFromSyncedFrom" {}
|
||||||
"wakuext_createPublicChat" {}
|
"wakuext_createPublicChat" {}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
^js removed-chats (.-removedChats response-js)
|
^js removed-chats (.-removedChats response-js)
|
||||||
^js activity-notifications (.-activityCenterNotifications response-js)
|
^js activity-notifications (.-activityCenterNotifications response-js)
|
||||||
^js pin-messages (.-pinMessages response-js)
|
^js pin-messages (.-pinMessages response-js)
|
||||||
|
^js removed-messages (.-removedMessages response-js)
|
||||||
sync-handler (when-not process-async process-response)]
|
sync-handler (when-not process-async process-response)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
|
@ -122,7 +123,14 @@
|
||||||
(js-delete response-js "invitations")
|
(js-delete response-js "invitations")
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(process-next response-js sync-handler)
|
(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
|
(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"
|
"group messages by current chat, profile updates, transactions and update unviewed counters in db for not curent chats"
|
||||||
|
|
|
@ -323,7 +323,9 @@
|
||||||
(when (not= (/ width k) (first @dimensions))
|
(when (not= (/ width k) (first @dimensions))
|
||||||
(reset! dimensions [(/ width k) image-max-height]))))))
|
(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])
|
(let [dimensions (reagent/atom [image-max-width image-max-height])
|
||||||
visible (reagent/atom false)
|
visible (reagent/atom false)
|
||||||
uri (:image content)]
|
uri (:image content)]
|
||||||
|
@ -384,16 +386,25 @@
|
||||||
(concat
|
(concat
|
||||||
(when (and outgoing edit-enabled)
|
(when (and outgoing edit-enabled)
|
||||||
[{:on-press #(re-frame/dispatch [:chat.ui/edit-message message])
|
[{: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?
|
(when show-input?
|
||||||
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
[{: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
|
[{:on-press #(react/copy-to-clipboard
|
||||||
(components.reply/get-quoted-text-with-mentions
|
(components.reply/get-quoted-text-with-mentions
|
||||||
(get content :parsed-text)))
|
(get content :parsed-text)))
|
||||||
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
:label (i18n/label :t/sharing-copy-to-clipboard)
|
||||||
(when message-pin-enabled [{:on-press #(pin-message message)
|
:id :copy}]
|
||||||
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))
|
(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]} _]
|
(defn collapsible-text-message [{:keys [mentioned]} _]
|
||||||
(let [collapsed? (reagent/atom false)
|
(let [collapsed? (reagent/atom false)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.ui.screens.chat.message.reactions-picker
|
(ns status-im.ui.screens.chat.message.reactions-picker
|
||||||
(:require [cljs-bean.core :as bean]
|
(:require [cljs-bean.core :as bean]
|
||||||
[status-im.ui.screens.chat.message.styles :as styles]
|
[status-im.ui.screens.chat.message.styles :as styles]
|
||||||
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[quo.react-native :as rn]
|
[quo.react-native :as rn]
|
||||||
|
@ -18,6 +19,14 @@
|
||||||
(def translate-x 27)
|
(def translate-x 27)
|
||||||
(def translate-y -24)
|
(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]}]
|
(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/container-style {:outgoing outgoing :timeline timeline})}
|
||||||
[rn/view {:style (styles/reactions-picker-row)}
|
[rn/view {:style (styles/reactions-picker-row)}
|
||||||
|
@ -32,15 +41,19 @@
|
||||||
:style {:height 32
|
:style {:height 32
|
||||||
:width 32}}]]]))]
|
:width 32}}]]]))]
|
||||||
(when (seq actions)
|
(when (seq actions)
|
||||||
[rn/view {:style (styles/quick-actions-row)}
|
[rn/view {:style (styles/quick-actions-container)}
|
||||||
(for [action actions
|
(for [action actions
|
||||||
:let [{:keys [label on-press]} (bean/bean action)]]
|
:let [{:keys [id label on-press]} (bean/bean action)]]
|
||||||
^{:key label}
|
^{:key id}
|
||||||
[rn/touchable-opacity {:on-press (fn []
|
[rn/touchable-opacity {:on-press (fn []
|
||||||
(on-close)
|
(on-close)
|
||||||
(js/setTimeout on-press animation-duration))}
|
(js/setTimeout on-press animation-duration))}
|
||||||
[quo/button {:type :secondary}
|
[rn/view {:style (styles/quick-actions-row)}
|
||||||
label]])])])
|
[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
|
(def modal
|
||||||
(reagent/adapt-react-class
|
(reagent/adapt-react-class
|
||||||
|
|
|
@ -35,9 +35,17 @@
|
||||||
:padding-vertical 8
|
:padding-vertical 8
|
||||||
:padding-horizontal 8})
|
:padding-horizontal 8})
|
||||||
|
|
||||||
|
(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 []
|
(defn quick-actions-row []
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:justify-content :space-evenly
|
:padding-horizontal 16
|
||||||
|
:padding-vertical 12
|
||||||
|
:justify-content :space-between
|
||||||
:border-top-width 1
|
:border-top-width 1
|
||||||
:border-top-color (:ui-01 @colors/theme)})
|
:border-top-color (:ui-01 @colors/theme)})
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.83.5",
|
"version": "v0.83.9",
|
||||||
"commit-sha1": "89251e841655082076ef304791b9ee3145f337c2",
|
"commit-sha1": "7dfeda15110af8ae315f41d19db39476a8e28d62",
|
||||||
"src-sha256": "0f0mw5bv4rwi6i9q4xa7shrjd8r4qwq5ky7lm6jjszyrqwhhf74j"
|
"src-sha256": "12v2k8679kl8gca6ihpn954rblpfdsi95kcaxpm39dahlg5ax2v9"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue