diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index c0e1bfb5ee..c308076119 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -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]} diff --git a/src/status_im/chat/models/message.cljs b/src/status_im/chat/models/message.cljs index 1142eeca72..951d225541 100644 --- a/src/status_im/chat/models/message.cljs +++ b/src/status_im/chat/models/message.cljs @@ -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])) diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index 2f6b1b7dc7..f3f6ec0833 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -39,6 +39,7 @@ "wakuext_post" {} "wakuext_requestAllHistoricMessages" {} "wakuext_editMessage" {} + "wakuext_deleteMessageAndSend" {} "wakuext_fillGaps" {} "wakuext_syncChatFromSyncedFrom" {} "wakuext_createPublicChat" {} diff --git a/src/status_im/transport/message/core.cljs b/src/status_im/transport/message/core.cljs index 1cbed3e725..d3843f5b73 100644 --- a/src/status_im/transport/message/core.cljs +++ b/src/status_im/transport/message/core.cljs @@ -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" diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index 6399f5eb2d..ad2484b213 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -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) diff --git a/src/status_im/ui/screens/chat/message/reactions_picker.cljs b/src/status_im/ui/screens/chat/message/reactions_picker.cljs index 81d76f82b8..cd65ba050b 100644 --- a/src/status_im/ui/screens/chat/message/reactions_picker.cljs +++ b/src/status_im/ui/screens/chat/message/reactions_picker.cljs @@ -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 diff --git a/src/status_im/ui/screens/chat/message/styles.cljs b/src/status_im/ui/screens/chat/message/styles.cljs index 4e07241f11..a71071b55e 100644 --- a/src/status_im/ui/screens/chat/message/styles.cljs +++ b/src/status_im/ui/screens/chat/message/styles.cljs @@ -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 diff --git a/status-go-version.json b/status-go-version.json index b7130fd3d9..55427caeb4 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' 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" }