diff --git a/src/quo/components/info/information_box/style.cljs b/src/quo/components/info/information_box/style.cljs index 31682ee33d..026e1f8898 100644 --- a/src/quo/components/info/information_box/style.cljs +++ b/src/quo/components/info/information_box/style.cljs @@ -3,7 +3,7 @@ [quo.foundations.colors :as colors])) (def ^:private themes - {:light {:default {:bg colors/white + {:light {:default {:bg colors/neutral-5 :border colors/neutral-20 :icon colors/neutral-50 :text colors/neutral-100} diff --git a/src/status_im/contexts/profile/contact/actions/view.cljs b/src/status_im/contexts/profile/contact/actions/view.cljs index ff0aaf8ab3..7f929bef3d 100644 --- a/src/status_im/contexts/profile/contact/actions/view.cljs +++ b/src/status_im/contexts/profile/contact/actions/view.cljs @@ -5,21 +5,28 @@ [status-im.common.not-implemented :as not-implemented] [status-im.constants :as constants] [status-im.contexts.profile.contact.add-nickname.view :as add-nickname] + [status-im.contexts.profile.contact.block-contact.view :as block-contact] [status-im.contexts.profile.utils :as profile.utils] [utils.i18n :as i18n] [utils.re-frame :as rf])) +(defn on-add-nickname + [] + (rf/dispatch [:show-bottom-sheet + {:content + (fn [] [add-nickname/view])}])) + +(defn on-block-contact + [] + (rf/dispatch [:show-bottom-sheet + {:content + (fn [] [block-contact/view])}])) + (defn view [] - (let [{:keys [nickname - public-key - contact-request-state] + (let [{:keys [nickname public-key contact-request-state blocked?] :as contact} (rf/sub [:contacts/current-contact]) - full-name (profile.utils/displayed-name contact) - on-add-nickname (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:content - (fn [] [add-nickname/view])}])) on-remove-nickname (rn/use-callback (fn [] (rf/dispatch [:hide-bottom-sheet]) @@ -55,41 +62,43 @@ (rf/dispatch [:contact.ui/remove-contact-pressed contact])) [public-key full-name])] [quo/action-drawer - [[{:icon :i/edit - :label (if has-nickname? - (i18n/label :t/edit-nickname) - (i18n/label :t/add-nickname-title)) - :on-press on-add-nickname - :accessibility-label (if nickname :edit-nickname :add-nickname)} - {:icon :i/qr-code - :label (i18n/label :t/show-qr) - :on-press on-show-qr - :accessibility-label :show-qr-code} - {:icon :i/share - :label (i18n/label :t/share-profile) - :on-press on-share-profile - :accessibility-label :share-profile} - (when has-nickname? - {:icon :i/delete - :label (i18n/label :t/remove-nickname) - :on-press on-remove-nickname - :add-divider? true - :accessibility-label :remove-nickname - :danger? true}) - {:icon :i/untrustworthy - :label (i18n/label :t/mark-untrustworthy) - :on-press not-implemented/alert - :accessibility-label :mark-untrustworthy - :add-divider? (when-not has-nickname? true) - :danger? true} - (when (= constants/contact-request-state-mutual contact-request-state) - {:icon :i/remove-user - :label (i18n/label :t/remove-contact) - :on-press on-remove-contact - :accessibility-label :remove-contact - :danger? true}) - {:icon :i/block - :label (i18n/label :t/block-user) - :on-press not-implemented/alert - :accessibility-label :block-user - :danger? true}]]])) + [(concat + [{:icon :i/edit + :label (if has-nickname? + (i18n/label :t/edit-nickname) + (i18n/label :t/add-nickname-title)) + :on-press on-add-nickname + :accessibility-label (if nickname :edit-nickname :add-nickname)} + {:icon :i/qr-code + :label (i18n/label :t/show-qr) + :on-press on-show-qr + :accessibility-label :show-qr-code} + {:icon :i/share + :label (i18n/label :t/share-profile) + :on-press on-share-profile + :accessibility-label :share-profile} + (when has-nickname? + {:icon :i/delete + :label (i18n/label :t/remove-nickname) + :on-press on-remove-nickname + :add-divider? true + :accessibility-label :remove-nickname + :danger? true})] + (when-not blocked? + [{:icon :i/untrustworthy + :label (i18n/label :t/mark-untrustworthy) + :on-press not-implemented/alert + :accessibility-label :mark-untrustworthy + :add-divider? (when-not has-nickname? true) + :danger? true} + (when (= constants/contact-request-state-mutual contact-request-state) + {:icon :i/remove-user + :label (i18n/label :t/remove-contact) + :on-press on-remove-contact + :accessibility-label :remove-contact + :danger? true}) + {:icon :i/block + :label (i18n/label :t/block-user) + :on-press on-block-contact + :accessibility-label :block-user + :danger? true}]))]])) diff --git a/src/status_im/contexts/profile/contact/add_nickname/view.cljs b/src/status_im/contexts/profile/contact/add_nickname/view.cljs index d15e904226..a6754a6e03 100644 --- a/src/status_im/contexts/profile/contact/add_nickname/view.cljs +++ b/src/status_im/contexts/profile/contact/add_nickname/view.cljs @@ -14,8 +14,8 @@ [] (let [{:keys [public-key primary-name nickname customization-color] :as profile} (rf/sub [:contacts/current-contact]) - ;; TODO(@mohsen): remove :blue, https://github.com/status-im/status-mobile/issues/18733 - customization-color (or customization-color :blue) + ;; TODO(@mohsen): remove default color, https://github.com/status-im/status-mobile/issues/18733 + customization-color (or customization-color constants/profile-default-color) full-name (profile.utils/displayed-name profile) profile-picture (profile.utils/photo profile) [unsaved-nickname set-unsaved-nickname] (rn/use-state nickname) @@ -54,15 +54,15 @@ :customization-color customization-color}] [rn/view {:style style/input-wrapper} [quo/input - {:type :text - :char-limit constants/profile-name-max-length - :max-length constants/profile-name-max-length - :auto-focus true - :default-value unsaved-nickname - :error? (not (string/blank? error-msg)) - :label (i18n/label :t/nickname) - :on-change-text on-nickname-change} - :on-submit-editing on-nickname-submit] + {:type :text + :char-limit constants/profile-name-max-length + :max-length constants/profile-name-max-length + :auto-focus true + :default-value unsaved-nickname + :error? (not (string/blank? error-msg)) + :label (i18n/label :t/nickname) + :on-change-text on-nickname-change + :on-submit-editing on-nickname-submit}] [quo/info-message {:icon :i/info :size :default diff --git a/src/status_im/contexts/profile/contact/block_contact/style.cljs b/src/status_im/contexts/profile/contact/block_contact/style.cljs new file mode 100644 index 0000000000..069de20b11 --- /dev/null +++ b/src/status_im/contexts/profile/contact/block_contact/style.cljs @@ -0,0 +1,11 @@ +(ns status-im.contexts.profile.contact.block-contact.style) + +(def content-wrapper + {:padding-vertical 8 + :padding-horizontal 20 + :gap 12}) + +(def checkbox-wrapper + {:flex-direction :row + :align-items :center + :gap 8}) diff --git a/src/status_im/contexts/profile/contact/block_contact/view.cljs b/src/status_im/contexts/profile/contact/block_contact/view.cljs new file mode 100644 index 0000000000..a511823797 --- /dev/null +++ b/src/status_im/contexts/profile/contact/block_contact/view.cljs @@ -0,0 +1,70 @@ +(ns status-im.contexts.profile.contact.block-contact.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [status-im.constants :as constants] + [status-im.contexts.profile.contact.block-contact.style :as style] + [status-im.contexts.profile.utils :as profile.utils] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn on-close [] (rf/dispatch [:hide-bottom-sheet])) + +(defn view + [] + (let [{:keys [customization-color contact-request-state public-key] + :as contact} (rf/sub [:contacts/current-contact]) + ;; TODO(@mohsen): remove default color, https://github.com/status-im/status-mobile/issues/18733 + customization-color (or customization-color constants/profile-default-color) + full-name (profile.utils/displayed-name contact) + profile-picture (profile.utils/photo contact) + [remove-contact? set-remove-contact?] (rn/use-state false) + on-remove-toggle (rn/use-callback #(set-remove-contact? not) []) + on-block-press (rn/use-callback + (fn [] + (rf/dispatch [:toasts/upsert + {:id :user-blocked + :type :positive + :text (i18n/label :t/user-blocked + {:username + full-name})}]) + (rf/dispatch [:contact.ui/block-contact-confirmed + public-key]) + (when remove-contact? + (rf/dispatch [:contact.ui/remove-contact-pressed + {:public-key public-key}])) + (on-close)) + [remove-contact? public-key full-name])] + [:<> + [quo/drawer-top + {:type :context-tag + :context-tag-type :default + :title (i18n/label :t/block) + :full-name full-name + :profile-picture profile-picture + :customization-color customization-color}] + [rn/view {:style style/content-wrapper} + [quo/text + {:weight :medium + :size :paragraph-1} + (i18n/label :t/block-user-title-message {:username full-name})] + [quo/information-box + {:icon :i/info + :type :default} + (i18n/label :t/blocking-a-user-message {:username full-name})] + (when (= constants/contact-request-state-mutual contact-request-state) + [rn/pressable + {:style style/checkbox-wrapper + :on-press on-remove-toggle} + [quo/selectors + {:type :checkbox + :checked? remove-contact? + :on-change on-remove-toggle}] + [quo/text (i18n/label :t/remove-contact)]])] + [quo/bottom-actions + {:actions :two-actions + :button-one-label (i18n/label :t/block) + :button-one-props {:type :danger + :on-press on-block-press} + :button-two-label (i18n/label :t/cancel) + :button-two-props {:type :grey + :on-press on-close}}]])) diff --git a/src/status_im/contexts/profile/contact/contact_request/view.cljs b/src/status_im/contexts/profile/contact/contact_request/view.cljs index fc8e04e64f..fb5d9b3b4e 100644 --- a/src/status_im/contexts/profile/contact/contact_request/view.cljs +++ b/src/status_im/contexts/profile/contact/contact_request/view.cljs @@ -2,6 +2,7 @@ (:require [clojure.string :as string] [quo.core :as quo] [react-native.core :as rn] + [status-im.constants :as constants] [status-im.contexts.profile.contact.contact-request.style :as style] [status-im.contexts.profile.utils :as profile.utils] [utils.i18n :as i18n] @@ -11,8 +12,8 @@ [] (let [{:keys [public-key customization-color] :as profile} (rf/sub [:contacts/current-contact]) - ;; TODO: remove :blue when #18733 merged. - customization-color (or customization-color :blue) + ;; TODO: remove default color when #18733 merged. + customization-color (or customization-color constants/profile-default-color) full-name (profile.utils/displayed-name profile) profile-picture (profile.utils/photo profile) [message set-message] (rn/use-state "") diff --git a/src/status_im/contexts/profile/contact/contact_review/view.cljs b/src/status_im/contexts/profile/contact/contact_review/view.cljs index ab00ce4545..7051032eb8 100644 --- a/src/status_im/contexts/profile/contact/contact_review/view.cljs +++ b/src/status_im/contexts/profile/contact/contact_review/view.cljs @@ -1,6 +1,7 @@ (ns status-im.contexts.profile.contact.contact-review.view (:require [quo.core :as quo] [react-native.core :as rn] + [status-im.constants :as constants] [status-im.contexts.profile.contact.contact-review.style :as style] [status-im.contexts.profile.utils :as profile.utils] [utils.i18n :as i18n] @@ -14,7 +15,7 @@ :keys [message]} (rf/sub [:activity-center/pending-contact-request-from-contact-id public-key]) ;; TODO(@seanstrom): https://github.com/status-im/status-mobile/issues/18733 - customization-color (or customization-color :blue) + customization-color (or customization-color constants/profile-default-color) full-name (profile.utils/displayed-name profile) profile-picture (profile.utils/photo profile) on-contact-accept (rn/use-callback diff --git a/src/status_im/contexts/profile/contact/header/view.cljs b/src/status_im/contexts/profile/contact/header/view.cljs index 70021c0df3..cdefb26930 100644 --- a/src/status_im/contexts/profile/contact/header/view.cljs +++ b/src/status_im/contexts/profile/contact/header/view.cljs @@ -13,24 +13,41 @@ [utils.i18n :as i18n] [utils.re-frame :as rf])) +(defn on-contact-request + [] + (rf/dispatch [:show-bottom-sheet + {:content (fn [] [contact-request/view])}])) + +(defn on-contact-review + [] + (rf/dispatch [:show-bottom-sheet + {:content (fn [] [contact-review/view])}])) + (defn view [{:keys [scroll-y]}] (let [{:keys [public-key customization-color ens-name - emoji-hash bio contact-request-state] - :as profile} (rf/sub [:contacts/current-contact]) - customization-color (or customization-color :blue) - full-name (profile.utils/displayed-name profile) - profile-picture (profile.utils/photo profile) + emoji-hash bio blocked? contact-request-state] + :as contact} (rf/sub [:contacts/current-contact]) + ;; TODO(@mohsen): remove default color, https://github.com/status-im/status-mobile/issues/18733 + customization-color (or customization-color constants/profile-default-color) + full-name (profile.utils/displayed-name contact) + profile-picture (profile.utils/photo contact) online? (rf/sub [:visibility-status-updates/online? public-key]) theme (quo.theme/use-theme-value) - on-contact-request (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:content (fn [] [contact-request/view])}])) - on-contact-review (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:content (fn [] [contact-review/view])}])) on-start-chat (rn/use-callback #(rf/dispatch [:chat.ui/start-chat public-key ens-name]) - [ens-name public-key])] + [ens-name public-key]) + on-unblock-press (rn/use-callback (fn [] + (rf/dispatch [:contact.ui/unblock-contact-pressed + public-key]) + (rf/dispatch [:toasts/upsert + {:id :user-unblocked + :type :positive + :text (i18n/label :t/user-unblocked + {:username + full-name})}])) + [public-key full-name])] [rn/view {:style style/header-container} [rn/view {:style style/header-top-wrapper} [rn/view {:style style/avatar-wrapper} @@ -53,10 +70,20 @@ :description-text bio :emoji-dash emoji-hash}] + (when blocked? + [quo/button + {:container-style style/button-wrapper + :on-press on-unblock-press + :icon-left :i/block} + (i18n/label :t/unblock)]) + (cond - (or (not contact-request-state) - (= contact-request-state constants/contact-request-state-none) - (= contact-request-state constants/contact-request-state-dismissed)) + (and (not blocked?) + (or + (not contact-request-state) + (= contact-request-state constants/contact-request-state-none) + (= contact-request-state constants/contact-request-state-dismissed))) + [quo/button {:container-style style/button-wrapper :on-press on-contact-request diff --git a/src/status_im/contexts/profile/contact/view.cljs b/src/status_im/contexts/profile/contact/view.cljs index 16e0a98753..e7f0e099ef 100644 --- a/src/status_im/contexts/profile/contact/view.cljs +++ b/src/status_im/contexts/profile/contact/view.cljs @@ -4,6 +4,7 @@ [react-native.core :as rn] [react-native.reanimated :as reanimated] [status-im.common.scroll-page.view :as scroll-page] + [status-im.constants :as constants] [status-im.contexts.profile.contact.actions.view :as actions] [status-im.contexts.profile.contact.header.view :as contact-header] [utils.re-frame :as rf])) @@ -21,8 +22,8 @@ {:navigate-back? true :height 148 :on-scroll #(reanimated/set-shared-value scroll-y %) - ;; TODO(@mohsen): remove colors/primary-50, https://github.com/status-im/status-mobile/issues/18733 - :cover-color (or customization-color colors/primary-50) + ;; TODO(@mohsen): remove default color, https://github.com/status-im/status-mobile/issues/18733 + :cover-color (or customization-color constants/profile-default-color) :background-color (colors/theme-colors colors/white colors/neutral-95 theme) :page-nav-props {:right-side [{:icon-name :i/options :on-press on-action-press}]}} diff --git a/translations/en.json b/translations/en.json index b46893bcf9..1d0c74a214 100644 --- a/translations/en.json +++ b/translations/en.json @@ -94,6 +94,8 @@ "blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name", "blank-keycard-title": "Looks like you’ve tapped \na blank keycard", "block": "Block", + "user-blocked": "{{username}} blocked", + "user-unblocked": "{{username}} unblocked", "unblock": "Unblock", "block-contact": "Block this user", "block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you", @@ -2065,6 +2067,8 @@ "rename": "Rename", "mark-untrustworthy": "Mark as Untrustworthy", "block-user": "Block user", + "block-user-title-message": "You will not see {{username}}'s messages, but {{username}} still can see your messages in mutual group chats and communities. {{username}} will be unable to message you.", + "blocking-a-user-message": "Blocking a user purges the database of all messages that you’ve previously received from {{username}} in all contexts.", "group-details": "Group details", "edit-name-and-image": "Edit name and image", "change-group-privacy": "Change group privacy",