From 76bf8d365c9eeb763bab4a0a832c4a6da4933225 Mon Sep 17 00:00:00 2001 From: Lungu Cristian Date: Wed, 3 Apr 2024 15:12:43 +0300 Subject: [PATCH] Allow to undo muting the chat/channel from toast (#19074) * feat: added undo action to mute chat toast * fix: removed trailing spaces from toast text * test: integration test for mute-chat undo * fix: added space before newline to toast messages text * feat: add undo to community mute toast * fix: integration tests * fix: integration tests --------- Co-authored-by: Volodymyr <52490791+VolodLytvynenko@users.noreply.github.com> --- src/status_im/constants.cljs | 2 + src/status_im/contexts/chat/events.cljs | 37 +++++++++++--- .../actions/community_options/events.cljs | 49 +++++++++++++++---- src/tests/integration_test/chat_test.cljs | 16 ++++++ translations/en.json | 24 ++++----- 5 files changed, 100 insertions(+), 28 deletions(-) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index b5d189f960..c3cd62c0f2 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -52,6 +52,8 @@ (def ^:const mute-till-unmuted 5) (def ^:const un-muted 0) +(def ^:const mute-undo-time-limit-ms 4000) + (def ^:const activity-center-mark-all-as-read-undo-time-limit-ms 4000) (def ^:const activity-center-max-unread-count 99) diff --git a/src/status_im/contexts/chat/events.cljs b/src/status_im/contexts/chat/events.cljs index b16dff8b7f..6f8d6814b3 100644 --- a/src/status_im/contexts/chat/events.cljs +++ b/src/status_im/contexts/chat/events.cljs @@ -275,9 +275,9 @@ (rf/defn unmute-chat-community {:events [:chat/unmute-chat-community]} - [{:keys [db]} chat-id muted?] + [{:keys [db]} chat-id] (let [{:keys [community-id]} (get-in db [:chats chat-id])] - {:db (assoc-in db [:communities community-id :muted] muted?)})) + {:db (assoc-in db [:communities community-id :muted] false)})) (rf/defn mute-chat-failed {:events [:chat/mute-failed]} @@ -290,7 +290,7 @@ [{:keys [db]} chat-id muted-till mute-type muted? chat-type] (log/debug "muted chat successfully" chat-id " for" muted-till) (when-not muted? - (rf/dispatch [:chat/unmute-chat-community chat-id muted?])) + (rf/dispatch [:chat/unmute-chat-community chat-id])) (let [time-string (fn [duration-kw unmute-time] (i18n/label duration-kw {:duration unmute-time})) not-community-chat? #(contains? #{constants/public-chat-type @@ -332,9 +332,13 @@ :t/channel-unmuted-successfully))))] {:db (assoc-in db [:chats chat-id :muted-till] muted-till) :dispatch [:toasts/upsert - {:type :positive - :text (mute-duration-text (when (some? muted-till) - (str (format-mute-till muted-till))))}]})) + (cond-> {:type :positive + :id :mute-chat-toast + :text (mute-duration-text (when (some? muted-till) + (str (format-mute-till muted-till))))} + muted? (assoc :duration constants/mute-undo-time-limit-ms + :undo-duration (/ constants/mute-undo-time-limit-ms 1000) + :undo-on-press #(rf/dispatch [:chat.ui/undo-mute chat-id])))]})) (rf/defn mute-chat {:events [:chat.ui/mute]} @@ -349,6 +353,27 @@ :on-success #(rf/dispatch [:chat/mute-successfully chat-id % mute-type muted? chat-type])}]})) +(rf/reg-event-fx + :chat.ui/undo-mute + (fn [_ [chat-id]] + {:fx [[:json-rpc/call + [{:method "wakuext_unmuteChat" + :params [chat-id] + :on-error #(rf/dispatch [:chat/mute-failed chat-id false %]) + :on-success #(rf/dispatch [:chat/undo-mute-success chat-id])}]]]})) + +(rf/reg-event-fx + :chat/undo-mute-success + (fn [{:keys [db]} [chat-id]] + {:db (update-in db + [:chats chat-id] + (fn [chat] + (-> chat + (dissoc :muted-till) + (assoc :muted false)))) + :fx [[:dispatch [:toasts/close :mute-chat-toast]] + [:dispatch [:chat/unmute-chat-community chat-id]]]})) + (rf/defn show-clear-history-confirmation {:events [:chat.ui/show-clear-history-confirmation]} [_ chat-id] diff --git a/src/status_im/contexts/communities/actions/community_options/events.cljs b/src/status_im/contexts/communities/actions/community_options/events.cljs index 223d4b1fe1..9c2fbe05c3 100644 --- a/src/status_im/contexts/communities/actions/community_options/events.cljs +++ b/src/status_im/contexts/communities/actions/community_options/events.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.communities.actions.community-options.events (:require [status-im.common.muting.helpers :as muting.helpers] + [status-im.constants :as constants] [taoensso.timbre :as log] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -12,7 +13,8 @@ db (keys (get-in db [:communities community-id :chats])))})) -(rf/reg-event-fx :community/mute-community-failed +(rf/reg-event-fx + :community/mute-community-failed (fn [{:keys [db]} [community-id muted? error]] (log/error "mute community failed" community-id error) {:db (assoc-in db [:communities community-id :muted] (not muted?)) @@ -22,15 +24,42 @@ (fn [{:keys [db]} [community-id muted? muted-till]] (let [time-string (fn [mute-title mute-duration] (i18n/label mute-title {:duration mute-duration}))] - {:db (assoc-in db [:communities community-id :muted-till] muted-till) - :dispatch-n [[:community/update-community-chats-mute-status community-id muted? muted-till] - [:toasts/upsert - {:type :positive - :text (if muted? - (when (some? muted-till) - (time-string :t/muted-until - (muting.helpers/format-mute-till muted-till))) - (i18n/label :t/community-unmuted))}]]}))) + {:db (assoc-in db [:communities community-id :muted-till] muted-till) + :fx [[:dispatch [:community/update-community-chats-mute-status community-id muted? muted-till]] + [:dispatch + [:toasts/upsert + (cond-> {:type :positive + :id :mute-community-toast + :text (if muted? + (when (some? muted-till) + (time-string :t/muted-until + (muting.helpers/format-mute-till muted-till))) + (i18n/label :t/community-unmuted))} + muted? (assoc :duration constants/mute-undo-time-limit-ms + :undo-duration (/ constants/mute-undo-time-limit-ms 1000) + :undo-on-press #(rf/dispatch [:community/undo-mute + community-id])))]]]}))) + +(rf/reg-event-fx + :community/undo-mute + (fn [_ [community-id]] + {:fx [[:json-rpc/call + [{:method "wakuext_unMuteCommunityChats" + :params [community-id] + :on-error #(rf/dispatch [:community/mute-community-failed community-id false %]) + :on-success #(rf/dispatch [:community/undo-mute-success community-id])}]]]})) + +(rf/reg-event-fx + :community/undo-mute-success + (fn [{:keys [db]} [community-id]] + {:db (update-in db + [:communities community-id] + (fn [community-id] + (-> community-id + (dissoc :muted-till) + (assoc :muted false)))) + :fx [[:dispatch [:toasts/close :mute-community-toast]] + [:dispatch [:community/update-community-chats-mute-status community-id false nil]]]})) (rf/reg-event-fx :community/set-muted (fn [{:keys [db]} [community-id muted? muted-type]] diff --git a/src/tests/integration_test/chat_test.cljs b/src/tests/integration_test/chat_test.cljs index 639f00498f..f203f3204a 100644 --- a/src/tests/integration_test/chat_test.cljs +++ b/src/tests/integration_test/chat_test.cljs @@ -56,6 +56,22 @@ (h/wait-for [:chat/mute-successfully]) (is (not @(rf/subscribe [:chats/muted chat-id]))))))) +(deftest undo-mute-chat-test + (h/test-async ::undo-mute-chat + (fn [] + (promesa/do + (rf/dispatch-sync [:chat.ui/start-chat chat-id]) + (h/wait-for [:chat/one-to-one-chat-created]) + (rf/dispatch-sync [:chat/navigate-to-chat chat-id]) + + (rf/dispatch-sync [:chat.ui/mute chat-id true constants/mute-till-unmuted]) + (h/wait-for [:chat/mute-successfully :toasts/upsert]) + (is @(rf/subscribe [:chats/muted chat-id])) + + (rf/dispatch-sync [:chat.ui/undo-mute chat-id]) + (h/wait-for [:chat/undo-mute-success :toasts/close]) + (is (not @(rf/subscribe [:chats/muted chat-id]))))))) + (deftest add-contact-test (h/test-async ::add-contact (fn [] diff --git a/translations/en.json b/translations/en.json index 668fc6588b..3883e777d1 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2336,19 +2336,19 @@ "oct": "Oct", "nov": "Nov", "dec": "Dec", - "channel-muted-for-15-minutes": "Channel muted for 15 minutes\n (until {{duration}}) ", - "channel-muted-for-1-hour": "Channel muted for 1 hour\n (until {{duration}}) ", - "channel-muted-for-8-hours": "Channel muted for 8 hours\n (until {{duration}}) ", - "channel-muted-for-1-week": "Channel muted for 1 week \n (until {{duration}}) ", - "channel-muted-till-unmuted": "Channel muted till unmuted\n (until {{duration}}) ", - "chat-muted-for-15-minutes": "Chat muted for 15 minutes\n (until {{duration}}) ", - "chat-muted-for-1-hour": "Chat muted for 1 hour\n (until {{duration}}) ", - "chat-muted-for-8-hours": "Chat muted for 8 hours\n (until {{duration}}) ", - "chat-muted-for-1-week": "Chat muted for 1 week\n (until {{duration}}) ", - "chat-muted-till-unmuted": "Chat muted till unmuted\n (until {{duration}}) ", + "channel-muted-for-15-minutes": "Channel muted for 15 minutes \n(until {{duration}})", + "channel-muted-for-1-hour": "Channel muted for 1 hour \n(until {{duration}})", + "channel-muted-for-8-hours": "Channel muted for 8 hours \n(until {{duration}})", + "channel-muted-for-1-week": "Channel muted for 1 week \n(until {{duration}})", + "channel-muted-till-unmuted": "Channel muted till unmuted \n(until {{duration}})", + "chat-muted-for-15-minutes": "Chat muted for 15 minutes \n(until {{duration}})", + "chat-muted-for-1-hour": "Chat muted for 1 hour \n(until {{duration}})", + "chat-muted-for-8-hours": "Chat muted for 8 hours \n(until {{duration}})", + "chat-muted-for-1-week": "Chat muted for 1 week \n(until {{duration}})", + "chat-muted-till-unmuted": "Chat muted till unmuted \n(until {{duration}})", "until": "until", - "chat-unmuted-successfully": "Chat unmuted successfully! ", - "channel-unmuted-successfully": "Channel unmuted successfully! ", + "chat-unmuted-successfully": "Chat unmuted successfully!", + "channel-unmuted-successfully": "Channel unmuted successfully!", "photo-saved": "Photo saved to your device", "community-unmuted": "Community unmuted", "all-time": "All time",