From 57526a45ad7509725edabc44e4d259ae111a933f Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Fri, 11 Nov 2022 17:02:39 +0400 Subject: [PATCH] Bottom sheet missing actions (#14332) * feat: bottom sheets --- .../components/drawers/action_drawers.cljs | 81 ++--- src/status_im/ui2/screens/chat/actions.cljs | 320 ++++++++++++++---- .../chat/components/contact_item/view.cljs | 31 +- .../components/message_home_item/view.cljs | 28 +- translations/en.json | 11 +- 5 files changed, 333 insertions(+), 138 deletions(-) diff --git a/src/quo2/components/drawers/action_drawers.cljs b/src/quo2/components/drawers/action_drawers.cljs index d05186ebee..427cf96fc9 100644 --- a/src/quo2/components/drawers/action_drawers.cljs +++ b/src/quo2/components/drawers/action_drawers.cljs @@ -1,8 +1,8 @@ (ns quo2.components.drawers.action-drawers - (:require [react-native.core :as rn] - [quo2.components.markdown.text :as text] - [quo2.components.icon :as icon] - [quo2.foundations.colors :as colors])) + (:require [react-native.core :as rn] + [quo2.components.markdown.text :as text] + [quo2.components.icon :as icon] + [quo2.foundations.colors :as colors])) (defn- get-icon-color [danger?] (if danger? @@ -14,47 +14,48 @@ sub-label right-icon danger? - on-press]}] - [rn/touchable-opacity {:on-press on-press} - [rn/view {:style - {:height (if sub-label 56 47) - :margin-horizontal 20 - :flex-direction :row}} - [rn/view {:style - {:height 20 - :margin-top :auto - :margin-bottom :auto - :margin-right 12 - :width 20}} - [icon/icon icon - {:color (get-icon-color danger?) - :size 20}]] - [rn/view - {:style - {:flex 1 - :justify-content :center}} - [text/text - {:size :paragraph-1 - :weight :medium - :style {:color - (when danger? - (colors/theme-colors colors/danger-50 colors/danger-60))}} - label] - (when sub-label - [text/text - {:size :paragraph-2 - :style {:color - (colors/theme-colors colors/neutral-50 colors/neutral-40)}} - sub-label])] - (when right-icon + on-press] :as action-props}] + (when action-props + [rn/touchable-opacity {:on-press on-press} + [rn/view {:style + {:height (if sub-label 56 47) + :margin-horizontal 20 + :flex-direction :row}} [rn/view {:style {:height 20 :margin-top :auto :margin-bottom :auto - :width 20}} - [icon/icon right-icon + :margin-right 12 + :width 20}} + [icon/icon icon {:color (get-icon-color danger?) - :size 20}]])]]) + :size 20}]] + [rn/view + {:style + {:flex 1 + :justify-content :center}} + [text/text + {:size :paragraph-1 + :weight :medium + :style {:color + (when danger? + (colors/theme-colors colors/danger-50 colors/danger-60))}} + label] + (when sub-label + [text/text + {:size :paragraph-2 + :style {:color + (colors/theme-colors colors/neutral-50 colors/neutral-40)}} + sub-label])] + (when right-icon + [rn/view {:style + {:height 20 + :margin-top :auto + :margin-bottom :auto + :width 20}} + [icon/icon right-icon + {:color (get-icon-color danger?) + :size 20}]])]])) (defn divider [] [rn/view {:style {:border-top-width 1 diff --git a/src/status_im/ui2/screens/chat/actions.cljs b/src/status_im/ui2/screens/chat/actions.cljs index 32cd26292d..b94ad9152c 100644 --- a/src/status_im/ui2/screens/chat/actions.cljs +++ b/src/status_im/ui2/screens/chat/actions.cljs @@ -4,38 +4,41 @@ [status-im.chat.models.pin-message :as models.pin-message] [status-im.i18n.i18n :as i18n] [status-im.constants :as constants] - [status-im.utils.handlers :refer [evt]] + [status-im.utils.re-frame :as rf] [quo2.components.drawers.action-drawers :as drawer])) -(defn- entry [icon label on-press danger?] +(defn- entry [{:keys [icon label on-press danger? sub-label chevron?]}] {:pre [(keyword? icon) (string? label) (fn? on-press) - (boolean? danger?)]} - {:icon icon - :label label - :on-press on-press - :danger? danger?}) + (boolean? danger?) + (boolean? chevron?)]} + {:icon icon + :label label + :on-press on-press + :danger? danger? + :sub-label sub-label + :right-icon (when chevron? :i/chevron-right)}) (defn hide-sheet-and-dispatch [event] - (>evt [:bottom-sheet/hide]) - (>evt event)) + (rf/dispatch [:bottom-sheet/hide]) + (rf/dispatch event)) (defn show-profile-action [chat-id] - (hide-sheet-and-dispatch [:chat.ui/show-profile chat-id]) - (>evt [::models.pin-message/load-pin-messages chat-id])) + (hide-sheet-and-dispatch [:chat.ui/show-profile chat-id]) + (rf/dispatch [::models.pin-message/load-pin-messages chat-id])) (defn mark-all-read-action [chat-id] - (hide-sheet-and-dispatch [:chat/mark-all-as-read chat-id])) + (hide-sheet-and-dispatch [:chat/mark-all-as-read chat-id])) (defn edit-nickname-action [chat-id] - (hide-sheet-and-dispatch [:chat.ui/edit-nickname chat-id])) + (hide-sheet-and-dispatch [:chat.ui/edit-nickname chat-id])) (defn mute-chat-action [chat-id] - (hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id true])) + (hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id true])) (defn unmute-chat-action [chat-id] - (hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id false])) + (hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id false])) (defn clear-history-action [chat-id] (hide-sheet-and-dispatch [:chat.ui/clear-history-pressed chat-id])) @@ -43,75 +46,256 @@ (defn delete-chat-action [chat-id] (hide-sheet-and-dispatch [:chat.ui/remove-chat-pressed chat-id])) -(defn mute-chat-entry [muted? chat-id] - (entry :i/muted - (i18n/label - (if muted? - :unmute-chat - :mute-chat)) - (if muted? - #(unmute-chat-action chat-id) - #(mute-chat-action chat-id)) - false)) +(defn leave-group-action [chat-id] + (hide-sheet-and-dispatch [:group-chats.ui/leave-chat-pressed chat-id])) + +(defn mute-chat-entry [chat-id] + (let [muted? (rf/sub [:chats/muted chat-id])] + (entry {:icon :i/muted + :label (i18n/label + (if muted? + :unmute-chat + :mute-chat)) + :on-press (if muted? + #(unmute-chat-action chat-id) + #(mute-chat-action chat-id)) + :danger? false + :sub-label nil + :chevron? true}))) (defn mark-as-read-entry [chat-id] - (entry :i/check - (i18n/label :mark-as-read) - #(mark-all-read-action chat-id) - false)) + (entry {:icon :i/correct + :label (i18n/label :t/mark-as-read) + :on-press #(mark-all-read-action chat-id) + :danger? false + :sub-label nil + :chevron? false})) (defn clear-history-entry [chat-id] - (entry :i/delete - (i18n/label :clear-history) - #(clear-history-action chat-id) - true)) + (entry {:icon :i/delete + :label (i18n/label :t/clear-history) + :on-press #(clear-history-action chat-id) + :danger? true + :sub-label nil + :chevron? false})) (defn delete-chat-entry [chat-id] - (entry :i/delete - (i18n/label :delete-chat) - #(delete-chat-action chat-id) - true)) + (entry {:icon :i/delete + :label (i18n/label :t/delete-chat) + :on-press #(delete-chat-action chat-id) + :danger? true + :sub-label nil + :chevron? false})) + +(defn leave-group-entry [chat-id] + (entry {:icon :i/log-out + :label (i18n/label :t/leave-group) + :on-press #(leave-group-action chat-id) + :danger? true + :sub-label nil + :chevron? false})) (defn view-profile-entry [chat-id] - (entry :i/friend - (i18n/label :view-profile) - #(show-profile-action chat-id) - false)) + (entry {:icon :i/friend + :label (i18n/label :t/view-profile) + :on-press #(show-profile-action chat-id) + :danger? false + :sub-label nil + :chevron? false})) (defn edit-nickname-entry [chat-id] - (entry :i/edit - (i18n/label :edit-nickname) - #(edit-nickname-action chat-id) - false)) + (entry {:icon :i/edit + :label (i18n/label :t/edit-nickname) + :on-press #(edit-nickname-action chat-id) + :danger? false + :sub-label nil + :chevron? false})) -(defn destructive-actions [chat-id] +(defn notifications-entry [] + (entry {:icon :i/notifications + :label (i18n/label :t/notifications) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? false + :sub-label "All messages" ; TODO: placeholder + :chevron? true})) + +(defn fetch-messages-entry [] + (entry {:icon :i/save + :label (i18n/label :t/fetch-messages) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? false + :sub-label nil + :chevron? true})) + +(defn pinned-messages-entry [] + (entry {:icon :i/pin + :label (i18n/label :t/pinned-messages) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? false + :sub-label nil + :chevron? true})) + +(defn remove-from-contacts-entry [contact] + (entry {:icon :i/remove-user + :label (i18n/label :t/remove-from-contacts) + :on-press #(hide-sheet-and-dispatch [:contact.ui/remove-contact-pressed contact]) + :danger? false + :sub-label nil + :chevron? false})) + +(defn rename-entry [] + (entry {:icon :i/edit + :label (i18n/label :t/rename) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? false + :sub-label nil + :chevron? false})) + +(defn show-qr-entry [] + (entry {:icon :i/qr-code + :label (i18n/label :t/show-qr) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? false + :sub-label nil + :chevron? false})) + +(defn share-profile-entry [] + (entry {:icon :i/share + :label (i18n/label :t/share-profile) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn share-group-entry [] + (entry {:icon :i/share + :label (i18n/label :t/share) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn mark-untrustworthy-entry [] + (entry {:icon :i/alert + :label (i18n/label :t/mark-untrustworthy) + :on-press #(js/alert "TODO: to be implemented, probably requires status-go impl. and design input") + :danger? true + :sub-label nil + :chevron? false})) + +(defn block-user-entry [] + (entry {:icon :i/block + :label (i18n/label :t/block-user) + :on-press #(js/alert "TODO: to be implemented, requires design input") + :danger? true + :sub-label nil + :chevron? false})) + +(defn group-details-entry [chat-id] + (entry {:icon :i/members + :label (i18n/label :t/group-details) + :on-press #(hide-sheet-and-dispatch [:show-group-chat-profile chat-id]) + :danger? false + :sub-label nil + :chevron? false})) + +(defn add-members-entry [] + (entry {:icon :i/add-user + :label (i18n/label :t/add-members) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn manage-members-entry [] + (entry {:icon :i/add-user + :label (i18n/label :t/manage-members) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn edit-group-entry [] + (entry {:icon :i/edit + :label (i18n/label :t/edit-name-and-image) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn group-privacy-entry [] + (entry {:icon :i/privacy + :label (i18n/label :t/change-group-privacy) + :on-press #(js/alert "TODO: to be implemented") + :danger? false + :sub-label nil + :chevron? false})) + +(defn destructive-actions [chat-id group-chat] [(clear-history-entry chat-id) - (delete-chat-entry chat-id)]) + (if group-chat + (leave-group-entry chat-id) + (delete-chat-entry chat-id))]) -(defn notification-actions [muted? chat-id] - [(mute-chat-entry muted? chat-id) - (mark-as-read-entry chat-id)]) +(defn notification-actions [{:keys [chat-id group-chat public?]} inside-chat?] + [(mark-as-read-entry chat-id) + (mute-chat-entry chat-id) + (notifications-entry) + (if inside-chat? + (fetch-messages-entry) + (pinned-messages-entry)) + (when (or (not group-chat) public?) + (show-qr-entry)) + (when-not group-chat + (share-profile-entry)) + (when public? + (share-group-entry))]) -(defn one-to-one-actions [muted? chat-id] +(defn group-actions [{:keys [chat-id admins]} inside-chat?] + (let [current-pk (rf/sub [:multiaccount/public-key]) + admin? (get admins current-pk)] + [(group-details-entry chat-id) + (when inside-chat? + (if admin? + (manage-members-entry) + (add-members-entry))) + (when (and admin? inside-chat?) (edit-group-entry)) + (when (and admin? inside-chat?) (group-privacy-entry))])) + +(defn one-to-one-actions [{:keys [chat-id group-chat] :as item} inside-chat?] [drawer/action-drawer [[(view-profile-entry chat-id) (edit-nickname-entry chat-id)] - (notification-actions muted? chat-id) - (destructive-actions chat-id)]]) + (notification-actions item inside-chat?) + (destructive-actions chat-id group-chat)]]) -(defn public-chat-actions [muted? chat-id] - [drawer/action-drawer [(notification-actions muted? chat-id) - (destructive-actions chat-id)]]) +(defn public-chat-actions [{:keys [chat-id group-chat] :as item} inside-chat?] + [drawer/action-drawer [[(group-details-entry chat-id) + (when inside-chat? + (add-members-entry))] + (notification-actions item inside-chat?) + (destructive-actions chat-id group-chat)]]) -(defn private-group-chat-actions [muted? chat-id] - [drawer/action-drawer [(notification-actions muted? chat-id) - (destructive-actions chat-id)]]) +(defn private-group-chat-actions [{:keys [chat-id group-chat] :as item} inside-chat?] + [drawer/action-drawer [(group-actions item inside-chat?) + (notification-actions item inside-chat?) + (destructive-actions chat-id group-chat)]]) + +(defn contact-actions [{:keys [public-key] :as contact}] + [drawer/action-drawer [[(view-profile-entry public-key) + (remove-from-contacts-entry contact) + (rename-entry) + (show-qr-entry) + (share-profile-entry)] + [(mark-untrustworthy-entry) + (block-user-entry)]]]) + +(defn actions [{:keys [chat-type] :as item} inside-chat?] + (case chat-type + constants/one-to-one-chat-type + [one-to-one-actions item inside-chat?] + constants/public-chat-type + [public-chat-actions item inside-chat?] + constants/private-group-chat-type + [private-group-chat-actions item inside-chat?] + [contact-actions item])) -(defn actions [chat-type chat-id] - (let [muted? (evt]] - [quo2.foundations.typography :as typography] + (:require [quo2.foundations.typography :as typography] [quo2.components.icon :as icons] [quo2.foundations.colors :as colors] [quo2.components.avatars.user-avatar :as user-avatar] [quo.react-native :as rn] - [status-im.utils.utils :refer [get-shortened-address]] + [status-im.utils.utils :as utils] [quo.platform :as platform] [quo2.components.markdown.text :as text] - [status-im.ui2.screens.chat.components.message-home-item.style :as style])) + [status-im.ui2.screens.chat.components.message-home-item.style :as style] + [status-im.utils.re-frame :as rf] + [status-im.ui2.screens.chat.actions :as actions])) (defn open-chat [chat-id] - (>evt [:dismiss-keyboard]) + (rf/dispatch [:dismiss-keyboard]) (if platform/android? - (>evt [:chat.ui/navigate-to-chat-nav2 chat-id]) - (>evt [:chat.ui/navigate-to-chat chat-id])) - (>evt [:search/home-filter-changed nil]) - (>evt [:accept-all-activity-center-notifications-from-chat chat-id])) + (rf/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id]) + (rf/dispatch [:chat.ui/navigate-to-chat chat-id])) + (rf/dispatch [:search/home-filter-changed nil]) + (rf/dispatch [:accept-all-activity-center-notifications-from-chat chat-id])) (defn contact-item [item] (let [{:keys [public-key ens-verified added? images]} item - display-name (first (evt]] + [status-im.utils.re-frame :as rf] [status-im.utils.datetime :as time] [quo2.foundations.typography :as typography] - [quo2.components.notifications.info-count :refer [info-count]] [quo2.components.icon :as icons] [quo2.foundations.colors :as colors] [quo2.components.avatars.user-avatar :as user-avatar] [quo.react-native :as rn] [quo.platform :as platform] + [quo2.core :as quo2] [quo2.components.markdown.text :as text] [status-im.ui2.screens.chat.actions :as actions] [status-im.ui2.screens.chat.components.message-home-item.style :as style])) @@ -34,7 +34,7 @@ children) "mention" - {:components [rn/text (evt [:dismiss-keyboard]) + (rf/dispatch [:dismiss-keyboard]) (if platform/android? - (>evt [:chat.ui/navigate-to-chat-nav2 chat-id]) - (>evt [:chat.ui/navigate-to-chat chat-id])) - (>evt [:search/home-filter-changed nil]) - (>evt [:accept-all-activity-center-notifications-from-chat chat-id])) - :on-long-press #(>evt [:bottom-sheet/show-sheet - {:content (fn [] [actions/actions item])}])}) + (rf/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id]) + (rf/dispatch [:chat.ui/navigate-to-chat chat-id])) + (rf/dispatch [:search/home-filter-changed nil]) + (rf/dispatch [:accept-all-activity-center-notifications-from-chat chat-id])) + :on-long-press #(rf/dispatch [:bottom-sheet/show-sheet + {:content (fn [] [actions/actions item false])}])}) [display-pic-view group-chat color display-name photo-path] [rn/view {:style {:margin-left 8}} [display-name-view display-name contact timestamp] @@ -129,7 +129,7 @@ (get-in last-message [:content :text])] [render-subheader (get-in last-message [:content :parsed-text])])] (if (> unviewed-mentions-count 0) - [info-count unviewed-mentions-count {:top 16}] + [quo2/info-count unviewed-mentions-count {:top 16}] (when (> unviewed-messages-count 0) [rn/view {:style (style/count-container)}]))])) diff --git a/translations/en.json b/translations/en.json index 45530e963f..e43c1d307e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -579,7 +579,7 @@ "community-private-key": "Community private key", "failed": "Failed", "faq": "Frequently asked questions", - "fetch-messages": "↓ Fetch messages", + "fetch-messages": "Fetch messages", "fetch-timeline": "↓ Fetch", "find": "Find", "finish": "Finish", @@ -1841,5 +1841,12 @@ "pending-requests": "Pending requests", "received": "Received", "sent": "Sent", - "and": "and" + "and": "and", + "rename": "Rename", + "mark-untrustworthy": "Mark as Untrustworthy", + "block-user": "Block User", + "group-details": "Group details", + "edit-name-and-image": "Edit name and image", + "change-group-privacy": "Change group privacy", + "manage-members": "Manage members" }