diff --git a/src/legacy/status_im/contact/block.cljs b/src/legacy/status_im/contact/block.cljs deleted file mode 100644 index 6975975513..0000000000 --- a/src/legacy/status_im/contact/block.cljs +++ /dev/null @@ -1,99 +0,0 @@ -(ns legacy.status-im.contact.block - (:require - [legacy.status-im.contact.db :as contact.db] - [legacy.status-im.data-store.chats :as chats-store] - [legacy.status-im.utils.deprecated-types :as types] - [re-frame.core :as re-frame] - [status-im.contexts.chat.contacts.events :as contacts-store] - [status-im.contexts.chat.messenger.messages.list.events :as message-list] - [status-im.navigation.events :as navigation] - [utils.re-frame :as rf])) - -(rf/defn clean-up-chat - [{:keys [db]} - public-key - {:keys [chat-id - unviewed-messages-count - unviewed-mentions-count - last-message]}] - (let [removed-messages-ids (keep - (fn [[message-id {:keys [from]}]] - (when (= from public-key) - message-id)) - (get-in db [:messages chat-id])) - db (-> db - ;; remove messages - (update-in [:messages chat-id] - #(apply dissoc % removed-messages-ids)) - (update-in [:chats chat-id] - assoc - :unviewed-messages-count unviewed-messages-count - :unviewed-mentions-count unviewed-mentions-count - :last-message last-message))] - {:db (assoc-in db - [:message-lists chat-id] - (message-list/add-many nil (vals (get-in db [:messages chat-id]))))})) - -(rf/defn contact-blocked - {:events [:contacts/blocked]} - [{:keys [db] :as cofx} {:keys [public-key]} chats-js] - (let [fxs (when chats-js - (map #(->> (chats-store/<-rpc %) - (clean-up-chat public-key)) - (types/js->clj chats-js)))] - (apply - rf/merge - cofx - {:db (-> - db - (update :chats dissoc public-key) - (update :chats-home-list disj public-key) - (assoc-in [:contacts/contacts public-key - :added?] - false)) - :fx [[:activity-center.notifications/fetch-unread-count] - [:effects/push-notifications-clear-message-notifications [public-key]] - [:dispatch-later - [{:ms 500 - :dispatch [:chat.ui/close-and-remove-chat public-key]}]]]} - fxs))) - -(rf/defn block-contact - {:events [:contact.ui/block-contact-confirmed]} - [{:keys [db] :as cofx} public-key] - (let [contact (-> (contact.db/public-key->contact - (:contacts/contacts db) - public-key) - (assoc :blocked? true - :added? false - :active? false)) - current-chat-id (:current-chat-id db) - from-one-to-one-chat? (not (get-in db [:chats current-chat-id :group-chat]))] - (rf/merge cofx - {:db (assoc-in db [:contacts/contacts public-key] contact)} - (contacts-store/block - public-key - (fn [^js block-contact] - (re-frame/dispatch [:contacts/blocked contact (.-chats block-contact)]) - (re-frame/dispatch [:sanitize-messages-and-process-response block-contact]) - (re-frame/dispatch [:hide-popover]))) - ;; reset navigation to avoid going back to non existing one to one chat - (when current-chat-id - (if from-one-to-one-chat? - (navigation/pop-to-root :shell-stack) - (navigation/navigate-back)))))) - -(rf/defn contact-unblocked - {:events [:contacts/unblocked]} - [{:keys [db]} contact-id] - (let [contact (-> (get-in db [:contacts/contacts contact-id]) - (assoc :blocked? false))] - {:db (assoc-in db [:contacts/contacts contact-id] contact)})) - -(rf/defn unblock-contact - {:events [:contact.ui/unblock-contact-pressed]} - [cofx contact-id] - (contacts-store/unblock - cofx - contact-id - #(re-frame/dispatch [:contacts/unblocked contact-id]))) diff --git a/src/legacy/status_im/contact/db.cljs b/src/legacy/status_im/contact/db.cljs deleted file mode 100644 index 2cc0ca51a2..0000000000 --- a/src/legacy/status_im/contact/db.cljs +++ /dev/null @@ -1,87 +0,0 @@ -(ns legacy.status-im.contact.db - (:require - [clojure.set :as set] - [clojure.string :as string] - [status-im.constants :as constants] - [utils.address :as address])) - -(defn public-key-and-ens-name->new-contact - [public-key ens-name] - (let [contact {:public-key public-key}] - (if ens-name - (-> contact - (assoc :ens-name ens-name) - (assoc :ens-verified true) - (assoc :name ens-name)) - contact))) - -(defn public-key->contact - [contacts public-key] - (when public-key - (get contacts public-key {:public-key public-key}))) - -(defn- contact-by-address - [[addr contact] address] - (when (address/address= addr address) - contact)) - -(defn find-contact-by-address - [contacts address] - (some #(contact-by-address % address) contacts)) - -(defn sort-contacts - [contacts] - (sort (fn [c1 c2] - (let [name1 (:primary-name c1) - name2 (:primary-name c2)] - (when (and name1 name2) - (compare (string/lower-case name1) - (string/lower-case name2))))) - (vals contacts))) - -(defn query-chat-contacts - [{:keys [contacts]} all-contacts query-fn] - (let [participant-set (into #{} (filter identity) contacts)] - (query-fn (comp participant-set :public-key) (vals all-contacts)))) - -(defn get-all-contacts-in-group-chat - [members admins contacts {:keys [public-key preferred-name name display-name] :as current-account}] - (let [current-contact (some-> - current-account - (select-keys [:name :preferred-name :public-key :images :compressed-key]) - (set/rename-keys {:name :alias :preferred-name :name}) - (assoc :primary-name (or display-name preferred-name name))) - all-contacts (cond-> contacts - current-contact - (assoc public-key current-contact))] - (->> members - (map #(or (get all-contacts %) - {:public-key %})) - (sort-by (comp string/lower-case - (fn [{:keys [primary-name name alias public-key]}] - (or primary-name - name - alias - public-key)))) - (map #(if (get admins (:public-key %)) - (assoc % :admin? true) - %))))) - -(defn enrich-contact - ([contact] (enrich-contact contact nil nil)) - ([{:keys [public-key] :as contact} setting own-public-key] - (cond-> contact - (and setting - (not= public-key own-public-key) - (or (= setting constants/profile-pictures-visibility-none) - (and (= setting constants/profile-pictures-visibility-contacts-only) - (not (:added? contact))))) - (dissoc :images)))) - -(defn enrich-contacts - [contacts profile-pictures-visibility own-public-key] - (reduce-kv - (fn [acc public-key contact] - (assoc acc public-key (enrich-contact contact profile-pictures-visibility own-public-key))) - {} - contacts)) diff --git a/src/legacy/status_im/contact/db_test.cljs b/src/legacy/status_im/contact/db_test.cljs deleted file mode 100644 index 0de7f95754..0000000000 --- a/src/legacy/status_im/contact/db_test.cljs +++ /dev/null @@ -1,49 +0,0 @@ -(ns legacy.status-im.contact.db-test - (:require [cljs.test :refer-macros [deftest is testing]] - [legacy.status-im.contact.db :as contact.db])) - -(deftest contacts-subs - (testing "get-all-contacts-in-group-chat" - (let - [chat-contact-ids - #{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917" - "0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f" - "0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"} - admins - #{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"} - - contacts - {"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f" - {:last-updated 0 - :name "User B" - :primary-name "User B" - :last-online 0 - :public-key - "0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}} - current-multiaccount - {:last-updated 0 - :signed-up? true - :sharing-usage-data? false - :primary-name "User A" - :name "User A" - :public-key - "0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}] - (is - (= - (contact.db/get-all-contacts-in-group-chat chat-contact-ids - admins - contacts - current-multiaccount) - [{:admin? true - :public-key - "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"} - {:alias "User A" - :primary-name "User A" - :public-key - "0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"} - {:last-updated 0 - :name "User B" - :primary-name "User B" - :last-online 0 - :public-key - "0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}]))))) diff --git a/src/legacy/status_im/events.cljs b/src/legacy/status_im/events.cljs index 84d381e76e..beef15d244 100644 --- a/src/legacy/status_im/events.cljs +++ b/src/legacy/status_im/events.cljs @@ -5,7 +5,6 @@ legacy.status-im.browser.core legacy.status-im.browser.permissions legacy.status-im.chat.models.loading - legacy.status-im.contact.block legacy.status-im.currency.core legacy.status-im.data-store.chats legacy.status-im.data-store.switcher-cards diff --git a/src/legacy/status_im/ui/screens/profile/components/sheets.cljs b/src/legacy/status_im/ui/screens/profile/components/sheets.cljs index c888c188b0..d6eb2939b3 100644 --- a/src/legacy/status_im/ui/screens/profile/components/sheets.cljs +++ b/src/legacy/status_im/ui/screens/profile/components/sheets.cljs @@ -22,7 +22,7 @@ :loading @in-progress? :accessibility-label :block-contact-confirm :on-press #(do (reset! in-progress? true) - (re-frame/dispatch [:contact.ui/block-contact-confirmed public-key]))} + (re-frame/dispatch [:contact/block-contact public-key]))} (i18n/label :t/block)] [react/view {:height 8}] [quo/button diff --git a/src/legacy/status_im/ui/screens/profile/contact/views.cljs b/src/legacy/status_im/ui/screens/profile/contact/views.cljs index 8d18f4ec21..8d0b10c3da 100644 --- a/src/legacy/status_im/ui/screens/profile/contact/views.cljs +++ b/src/legacy/status_im/ui/screens/profile/contact/views.cljs @@ -56,7 +56,7 @@ :selected blocked? :icon :main-icons/cancel :action (if blocked? - #(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key]) + #(re-frame/dispatch [:contact/unblock-contact public-key]) #(re-frame/dispatch [:show-popover {:view sheets/block-contact :prevent-closing? true diff --git a/src/quo/components/list_items/user.cljs b/src/quo/components/list_items/user.cljs index 9c704e9ace..7e774abc7c 100644 --- a/src/quo/components/list_items/user.cljs +++ b/src/quo/components/list_items/user.cljs @@ -17,26 +17,28 @@ :flex-direction :row :align-items :center}) -(defn action-icon - [{:keys [type on-press on-check disabled? checked?]} customization-color theme] - [rn/touchable-opacity - {:on-press on-press} - (case type - :options - [icons/icon :i/options - {:size 20 - :color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}] - :checkbox - [selectors/view - {:type :checkbox - :checked? checked? - :customization-color customization-color - :accessibility-label :user-list-toggle-check - :disabled? disabled? - :on-change (when on-check on-check)}] - :close - [text/text "not implemented"] - [rn/view])]) +(defn accessory-item + [{:keys [type on-press on-check disabled? checked? child]} customization-color theme] + (if (= type :custom) + child + [rn/touchable-opacity + {:on-press on-press} + (case type + :options + [icons/icon :i/options + {:size 20 + :color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}] + :checkbox + [selectors/view + {:type :checkbox + :checked? checked? + :customization-color customization-color + :accessibility-label :user-list-toggle-check + :disabled? disabled? + :on-change (when on-check on-check)}] + :close + [text/text "not implemented"] + [rn/view])])) (defn user [{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified? @@ -72,4 +74,4 @@ :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} short-chat-key])] (when accessory - [action-icon accessory customization-color disabled? theme])]]) + [accessory-item accessory customization-color disabled? theme])]]) diff --git a/src/quo/components/overlay/view.cljs b/src/quo/components/overlay/view.cljs index 8855ec0e36..38d8e3f5e2 100644 --- a/src/quo/components/overlay/view.cljs +++ b/src/quo/components/overlay/view.cljs @@ -2,19 +2,23 @@ (:require [quo.components.overlay.style :as style] [react-native.blur :as blur] - [react-native.core :as rn])) + [react-native.core :as rn] + [react-native.safe-area :as safe-area])) (defn view - [{:keys [type container-style]} & children] - [rn/view {:style (style/overlay-background type)} - (if (= type :shell) - [blur/view - {:blur-amount 20 - :blur-radius 25 - :blur-type :transparent - :overlay-color :transparent - :style style/container} - [rn/view {:style (merge style/blur-container container-style)} - children]] - [rn/view {:style (merge style/container container-style)} - children])]) + [{:keys [type container-style top-inset?]} & children] + (let [top-style (when top-inset? {:padding-top (safe-area/get-top)})] + [rn/view {:style (style/overlay-background type)} + (if (= type :shell) + [blur/view + {:blur-amount 20 + :blur-radius 25 + :blur-type :transparent + :overlay-color :transparent + :style style/container} + (into [rn/view + {:style (merge style/blur-container top-style container-style)}] + children)] + (into [rn/view + {:style (merge style/container top-style container-style)}] + children))])) diff --git a/src/quo/components/text_combinations/page_top/component_spec.cljs b/src/quo/components/text_combinations/page_top/component_spec.cljs index da6d7c3152..ff41b6d76c 100644 --- a/src/quo/components/text_combinations/page_top/component_spec.cljs +++ b/src/quo/components/text_combinations/page_top/component_spec.cljs @@ -113,7 +113,7 @@ (h/is-truthy (h/get-by-text "Title")) (h/is-truthy (h/get-by-label-text :address-text-input))) - (h/test "Address input" + (h/test "Recovery phrase" (h/render [page-top/view {:title "Title" :input :recovery-phrase}]) diff --git a/src/status_im/common/home/actions/view.cljs b/src/status_im/common/home/actions/view.cljs index 80ecfe382c..45ec1b0ea0 100644 --- a/src/status_im/common/home/actions/view.cljs +++ b/src/status_im/common/home/actions/view.cljs @@ -127,7 +127,7 @@ :context item :accessibility-label :block-user :button-text (i18n/label :t/block-user) - :on-press #(hide-sheet-and-dispatch [:contact.ui/block-contact-confirmed + :on-press #(hide-sheet-and-dispatch [:contact/block-contact public-key])}])}])) (defn mute-chat-entry diff --git a/src/status_im/common/toasts/events.cljs b/src/status_im/common/toasts/events.cljs index 5daa25716e..746321ed3f 100644 --- a/src/status_im/common/toasts/events.cljs +++ b/src/status_im/common/toasts/events.cljs @@ -19,7 +19,7 @@ (update :toasts dissoc :hide-toasts-timer-set))} (and (not update?) (= (count ordered) 1)) - (assoc :show-toasts [(:view-id db) (:theme db)]) + (assoc :show-toasts [(:view-id db) (or (:theme opts) (:theme db))]) (not (:id opts)) (update-in [:db :toasts :next-toast-number] inc)))) diff --git a/src/status_im/contexts/chat/contacts/events.cljs b/src/status_im/contexts/chat/contacts/events.cljs index 6f7c8f2414..0796e52c59 100644 --- a/src/status_im/contexts/chat/contacts/events.cljs +++ b/src/status_im/contexts/chat/contacts/events.cljs @@ -131,20 +131,3 @@ :js-response true :on-success #(rf/dispatch [:sanitize-messages-and-process-response %]) :on-error #(log/error "failed to set contact nickname " public-key nickname %)}]}) - -(rf/defn block - [_ contact-id on-success] - {:json-rpc/call [{:method "wakuext_blockContact" - :params [contact-id] - :js-response true - :on-success on-success - :on-error #(log/error "failed to block contact" % contact-id)}]}) - -(rf/defn unblock - [_ contact-id on-success] - {:json-rpc/call [{:method "wakuext_unblockContact" - :params [contact-id] - :on-success on-success - :js-response true - :on-error #(log/error "failed to unblock contact" % contact-id)}]}) - diff --git a/src/status_im/contexts/contact/blocking/events.cljs b/src/status_im/contexts/contact/blocking/events.cljs new file mode 100644 index 0000000000..61e703d7a6 --- /dev/null +++ b/src/status_im/contexts/contact/blocking/events.cljs @@ -0,0 +1,85 @@ +(ns status-im.contexts.contact.blocking.events + (:require + [legacy.status-im.data-store.chats :as chats-store] + [re-frame.core :as re-frame] + [status-im.contexts.chat.messenger.messages.list.events :as message-list] + [taoensso.timbre :as log] + [utils.re-frame :as rf] + [utils.transforms :as transforms])) + +(rf/defn clean-up-chat + [{:keys [db]} public-key + {:keys [chat-id unviewed-messages-count unviewed-mentions-count last-message]}] + (let [ids (keep (fn [[message-id {:keys [from]}]] + (when (= from public-key) message-id)) + (get-in db [:messages chat-id])) + db (-> db + ;; remove messages + (update-in [:messages chat-id] #(apply dissoc % ids)) + (update-in [:chats chat-id] + assoc + :unviewed-messages-count unviewed-messages-count + :unviewed-mentions-count unviewed-mentions-count + :last-message last-message))] + {:db (assoc-in db + [:message-lists chat-id] + (message-list/add-many nil (vals (get-in db [:messages chat-id]))))})) + +(rf/defn contact-blocked + {:events [:contact/blocked]} + [{:keys [db] :as cofx} {:keys [public-key]} chats-js] + (let [fxs (when chats-js + (map #(->> (chats-store/<-rpc %) + (clean-up-chat public-key)) + (transforms/js->clj chats-js)))] + (apply + rf/merge + cofx + {:db (-> db + (update :chats dissoc public-key) + (update :chats-home-list disj public-key) + (assoc-in [:contacts/contacts public-key :added?] false)) + :fx [[:activity-center.notifications/fetch-unread-count] + [:effects/push-notifications-clear-message-notifications [public-key]] + [:dispatch-later + [{:ms 500 + :dispatch [:chat.ui/close-and-remove-chat public-key]}]]]} + fxs))) + +(rf/reg-event-fx :contact/block-contact + (fn [{:keys [db]} [public-key]] + (let [contact (-> (get (:contacts/contacts db) public-key {:public-key public-key}) + (assoc :blocked? true + :added? false + :active? false)) + current-chat-id (:current-chat-id db) + from-one-to-one-chat? (not (get-in db [:chats current-chat-id :group-chat]))] + {:db (assoc-in db [:contacts/contacts public-key] contact) + :fx [[:json-rpc/call + [{:method "wakuext_blockContact" + :params [public-key] + :js-response true + :on-success (fn [^js response] + (re-frame/dispatch [:contact/blocked contact (.-chats response)]) + (re-frame/dispatch [:sanitize-messages-and-process-response response])) + :on-error #(log/error "failed to block contact" % public-key)}]] + [:dispatch [:hide-popover]] + ;; reset navigation to avoid going back to non existing one to one chat + (when current-chat-id + (if from-one-to-one-chat? + [:dispatch [:pop-to-root :shell-stack]] + [:dispatch [:navigate-back]]))]}))) + +(rf/reg-event-fx :contact/unblocked + (fn [{:keys [db]} [contact-id]] + {:db (update-in db + [:contacts/contacts contact-id] + #(assoc % :blocked? false :added true :active? true))})) + +(rf/reg-event-fx :contact/unblock-contact + (fn [_ [contact-id]] + {:json-rpc/call + [{:method "wakuext_unblockContact" + :params [contact-id] + :on-success #(re-frame/dispatch [:contact/unblocked contact-id]) + :on-error #(log/error "failed to unblock contact" % contact-id)}]})) diff --git a/src/status_im/contexts/profile/contact/block_contact/view.cljs b/src/status_im/contexts/profile/contact/block_contact/view.cljs index d9fb9badb6..75e5142ce4 100644 --- a/src/status_im/contexts/profile/contact/block_contact/view.cljs +++ b/src/status_im/contexts/profile/contact/block_contact/view.cljs @@ -24,7 +24,7 @@ :text (i18n/label :t/user-blocked {:username full-name})}]) - (rf/dispatch [:contact.ui/block-contact-confirmed + (rf/dispatch [:contact/block-contact public-key]) (rf/dispatch [:contact.ui/remove-contact-pressed {:public-key public-key}]) diff --git a/src/status_im/contexts/profile/contact/header/view.cljs b/src/status_im/contexts/profile/contact/header/view.cljs index 96f3263416..e65c54db3e 100644 --- a/src/status_im/contexts/profile/contact/header/view.cljs +++ b/src/status_im/contexts/profile/contact/header/view.cljs @@ -46,7 +46,7 @@ ens-name]) [ens-name public-key]) on-unblock-press (rn/use-callback (fn [] - (rf/dispatch [:contact.ui/unblock-contact-pressed + (rf/dispatch [:contact/unblock-contact public-key]) (rf/dispatch [:toasts/upsert {:id :user-unblocked diff --git a/src/status_im/contexts/profile/contact/unblock_contact/view.cljs b/src/status_im/contexts/profile/contact/unblock_contact/view.cljs new file mode 100644 index 0000000000..bf4999c227 --- /dev/null +++ b/src/status_im/contexts/profile/contact/unblock_contact/view.cljs @@ -0,0 +1,52 @@ +(ns status-im.contexts.profile.contact.unblock-contact.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [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 + [contact] + (let [{:keys [customization-color + public-key]} contact + full-name (profile.utils/displayed-name contact) + profile-picture (profile.utils/photo contact) + on-unblock-press (rn/use-callback + (fn [] + (rf/dispatch [:toasts/upsert + {:id :user-unblocked + :type :positive + :theme :dark + :text (i18n/label :t/user-unblocked + {:username + full-name})}]) + (rf/dispatch [:contact/unblock-contact + public-key]) + (on-close)) + [public-key full-name])] + [:<> + [quo/drawer-top + {:type :context-tag + :context-tag-type :default + :title (i18n/label :t/unblock) + :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/unblocking-a-user-message {:username full-name})]] + [quo/bottom-actions + {:actions :two-actions + :button-one-label (i18n/label :t/unblock) + :button-one-props {:type :danger + :accessibility-label :block-contact + :on-press on-unblock-press} + :button-two-label (i18n/label :t/cancel) + :button-two-props {:type :grey + :accessibility-label :cancel + :on-press on-close}}]])) diff --git a/src/status_im/contexts/profile/settings/list_items.cljs b/src/status_im/contexts/profile/settings/list_items.cljs index 9e09330c3d..203882d50f 100644 --- a/src/status_im/contexts/profile/settings/list_items.cljs +++ b/src/status_im/contexts/profile/settings/list_items.cljs @@ -17,13 +17,12 @@ :image :icon :blur? true :action :arrow}] - [(when config/show-not-implemented-features? - {:title (i18n/label :t/messages) - :on-press not-implemented/alert - :image-props :i/messages - :image :icon - :blur? true - :action :arrow}) + [{:title (i18n/label :t/messages) + :on-press #(rf/dispatch [:open-modal :screen/settings-messages]) + :image-props :i/messages + :image :icon + :blur? true + :action :arrow} (when config/show-not-implemented-features? {:title (i18n/label :t/wallet) :on-press not-implemented/alert diff --git a/src/status_im/contexts/profile/settings/screens/messages/blocked_users/view.cljs b/src/status_im/contexts/profile/settings/screens/messages/blocked_users/view.cljs new file mode 100644 index 0000000000..5b7b322da0 --- /dev/null +++ b/src/status_im/contexts/profile/settings/screens/messages/blocked_users/view.cljs @@ -0,0 +1,43 @@ +(ns status-im.contexts.profile.settings.screens.messages.blocked-users.view + (:require [quo.core :as quo] + [react-native.core :as rn] + [status-im.common.contact-list-item.view :as contact-list-item] + [status-im.contexts.profile.contact.unblock-contact.view :as unblock-contact] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn list-item + [user _ _ _] + [contact-list-item/contact-list-item + {:accessory {:type :custom + :child [quo/button + {:on-press #(rf/dispatch [:show-bottom-sheet + {:theme :dark + :content + (fn [] [unblock-contact/view user])}]) + :type :outline + :size 24 + :background :blur + :customization-color :blue} + (i18n/label :t/unblock)]}} + user]) + +(defn- navigate-back + [] + (rf/dispatch [:navigate-back])) + +(defn view + [] + (let [contacts (rf/sub [:contacts/blocked])] + [quo/overlay {:type :shell :top-inset? true} + [quo/page-nav + {:key :header + :background :blur + :icon-name :i/arrow-left + :on-press navigate-back}] + [quo/page-top {:title (i18n/label :t/blocked-users)}] + [rn/flat-list + {:data contacts + :key-fn :key + :render-fn list-item + :accessibility-label :contacts-list}]])) diff --git a/src/status_im/contexts/profile/settings/screens/messages/view.cljs b/src/status_im/contexts/profile/settings/screens/messages/view.cljs new file mode 100644 index 0000000000..3adbeb24e0 --- /dev/null +++ b/src/status_im/contexts/profile/settings/screens/messages/view.cljs @@ -0,0 +1,29 @@ +(ns status-im.contexts.profile.settings.screens.messages.view + (:require [quo.core :as quo] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn- navigate-back + [] + (rf/dispatch [:navigate-back])) + +(defn- open-blocked-users + [] + (rf/dispatch [:open-modal :screen/settings-blocked-users])) + +(defn view + [] + [quo/overlay {:type :shell :top-inset? true} + [quo/page-nav + {:background :blur + :icon-name :i/arrow-left + :on-press navigate-back}] + [quo/page-top {:title (i18n/label :t/messages)}] + [quo/category + {:label (i18n/label :t/contacts) + :data [{:title (i18n/label :t/blocked-users) + :on-press open-blocked-users + :blur? true + :action :arrow}] + :blur? true + :list-type :settings}]]) diff --git a/src/status_im/contexts/profile/settings/screens/password/view.cljs b/src/status_im/contexts/profile/settings/screens/password/view.cljs index dc0df7a4ed..d95f380d73 100644 --- a/src/status_im/contexts/profile/settings/screens/password/view.cljs +++ b/src/status_im/contexts/profile/settings/screens/password/view.cljs @@ -1,12 +1,9 @@ (ns status-im.contexts.profile.settings.screens.password.view (:require [quo.core :as quo] [quo.theme :as quo.theme] - [react-native.core :as rn] - [react-native.safe-area :as safe-area] [status-im.common.biometric.utils :as biometric] [status-im.common.not-implemented :as not-implemented] [status-im.constants :as constants] - [status-im.contexts.profile.settings.screens.password.style :as style] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -56,27 +53,19 @@ :image-props :i/password :action :arrow}) +(defn- navigate-back + [] + (rf/dispatch [:navigate-back])) + (defn view [] - (let [theme (quo.theme/use-theme) - insets (safe-area/get-insets)] - [quo/overlay {:type :shell} - [rn/view - {:key :navigation - :style (style/navigation (:top insets))} - [quo/page-nav - {:background :blur - :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back])}]] - [rn/view - {:key :header - :style style/header} - [quo/text - {:accessibility-label :password-settings-label - :weight :semi-bold - :number-of-lines 1 - :size :heading-1} - (i18n/label :t/password)]] + (let [theme (quo.theme/use-theme)] + [quo/overlay {:type :shell :top-inset? true} + [quo/page-nav + {:background :blur + :icon-name :i/arrow-left + :on-press navigate-back}] + [quo/page-top {:title (i18n/label :t/password)}] [quo/category {:key :category :data [(get-biometric-item theme) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 36fffa907f..c0986e2343 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -23,6 +23,7 @@ status-im.contexts.communities.events status-im.contexts.communities.overview.events status-im.contexts.communities.sharing.events + status-im.contexts.contact.blocking.events status-im.contexts.onboarding.common.overlay.events status-im.contexts.onboarding.events status-im.contexts.profile.events diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 39281e4e59..f2bf40c5eb 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -48,6 +48,9 @@ [status-im.contexts.profile.edit.name.view :as edit-name] [status-im.contexts.profile.edit.view :as edit-profile] [status-im.contexts.profile.profiles.view :as profiles] + [status-im.contexts.profile.settings.screens.messages.blocked-users.view :as + settings.blocked-users] + [status-im.contexts.profile.settings.screens.messages.view :as settings.messages] [status-im.contexts.profile.settings.screens.password.view :as settings-password] [status-im.contexts.profile.settings.view :as settings] [status-im.contexts.shell.activity-center.view :as activity-center] @@ -471,7 +474,15 @@ {:name :settings-password :options options/transparent-modal-screen-options - :component settings-password/view}] + :component settings-password/view} + + {:name :screen/settings-messages + :options options/transparent-modal-screen-options + :component settings.messages/view} + + {:name :screen/settings-blocked-users + :options options/transparent-modal-screen-options + :component settings.blocked-users/view}] [{:name :shell :options {:theme :dark}}] diff --git a/src/status_im/subs/contact.cljs b/src/status_im/subs/contact.cljs index 4b1a7ee2a2..e3a6089005 100644 --- a/src/status_im/subs/contact.cljs +++ b/src/status_im/subs/contact.cljs @@ -1,7 +1,7 @@ (ns status-im.subs.contact (:require + [clojure.set :as set] [clojure.string :as string] - [legacy.status-im.contact.db :as contact.db] [legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils] [quo.theme] [re-frame.core :as re-frame] @@ -13,12 +13,17 @@ [utils.i18n :as i18n] [utils.image-server :as image-server])) +(defn query-chat-contacts + [{:keys [contacts]} all-contacts query-fn] + (let [participant-set (into #{} (filter identity) contacts)] + (query-fn (comp participant-set :public-key) (vals all-contacts)))) + (re-frame/reg-sub ::query-current-chat-contacts :<- [:chats/current-chat] :<- [:contacts/contacts] (fn [[chat contacts] [_ query-fn]] - (contact.db/query-chat-contacts chat contacts query-fn))) + (query-chat-contacts chat contacts query-fn))) (re-frame/reg-sub :multiaccount/profile-pictures-show-to @@ -73,6 +78,25 @@ (assoc contact :images images))) +(defn- enrich-contact + ([contact] (enrich-contact contact nil nil)) + ([{:keys [public-key] :as contact} setting own-public-key] + (cond-> contact + (and setting + (not= public-key own-public-key) + (or (= setting constants/profile-pictures-visibility-none) + (and (= setting constants/profile-pictures-visibility-contacts-only) + (not (:added? contact))))) + (dissoc :images)))) + +(defn- enrich-contacts + [contacts profile-pictures-visibility own-public-key] + (reduce-kv + (fn [acc public-key contact] + (assoc acc public-key (enrich-contact contact profile-pictures-visibility own-public-key))) + {} + contacts)) + (defn- reduce-contacts-image-uri [contacts port font-file theme] (reduce-kv (fn [acc public-key contact] @@ -90,16 +114,26 @@ :<- [:initials-avatar-font-file] :<- [:theme] (fn [[contacts profile-pictures-visibility public-key port font-file theme]] - (let [contacts (contact.db/enrich-contacts contacts profile-pictures-visibility public-key)] + (let [contacts (enrich-contacts contacts profile-pictures-visibility public-key)] (reduce-contacts-image-uri contacts port font-file theme)))) +(defn sort-contacts + [contacts] + (sort (fn [c1 c2] + (let [name1 (:primary-name c1) + name2 (:primary-name c2)] + (when (and name1 name2) + (compare (string/lower-case name1) + (string/lower-case name2))))) + (vals contacts))) + (re-frame/reg-sub :contacts/active :<- [:contacts/contacts] (fn [contacts] (->> contacts (filter (fn [[_ contact]] (:active? contact))) - contact.db/sort-contacts))) + sort-contacts))) (re-frame/reg-sub :contacts/active-sections @@ -165,7 +199,7 @@ (->> contacts (filter (fn [[_ contact]] (:blocked? contact))) - contact.db/sort-contacts))) + sort-contacts))) (re-frame/reg-sub :contacts/blocked-set @@ -179,10 +213,20 @@ (fn [blocked-contacts] (count blocked-contacts))) -(defn- enrich-contact +(defn public-key-and-ens-name->new-contact + [public-key ens-name] + (let [contact {:public-key public-key}] + (if ens-name + (-> contact + (assoc :ens-name ens-name) + (assoc :ens-verified true) + (assoc :name ens-name)) + contact))) + +(defn- prepare-contact [_ contact-identity ens-name port font-file theme] - (let [contact (contact.db/enrich-contact - (contact.db/public-key-and-ens-name->new-contact contact-identity ens-name))] + (let [contact (enrich-contact + (public-key-and-ens-name->new-contact contact-identity ens-name))] (replace-contact-image-uri contact port contact-identity font-file theme))) (re-frame/reg-sub @@ -197,7 +241,7 @@ (let [contact (get contacts contact-identity)] (cond-> contact (nil? contact) - (enrich-contact contact-identity ens-name port font-file theme))))) + (prepare-contact contact-identity ens-name port font-file theme))))) (re-frame/reg-sub :contacts/contact-by-identity @@ -228,13 +272,36 @@ (fn [contacts] (filter :added? contacts))) +(defn get-all-contacts-in-group-chat + [members admins contacts {:keys [public-key preferred-name name display-name] :as current-account}] + (let [current-contact (some-> + current-account + (select-keys [:name :preferred-name :public-key :images :compressed-key]) + (set/rename-keys {:name :alias :preferred-name :name}) + (assoc :primary-name (or display-name preferred-name name))) + all-contacts (cond-> contacts + current-contact + (assoc public-key current-contact))] + (->> members + (map #(or (get all-contacts %) + {:public-key %})) + (sort-by (comp string/lower-case + (fn [{:keys [primary-name name alias public-key]}] + (or primary-name + name + alias + public-key)))) + (map #(if (get admins (:public-key %)) + (assoc % :admin? true) + %))))) + (re-frame/reg-sub :contacts/current-chat-contacts :<- [:chats/current-chat] :<- [:contacts/contacts] :<- [:profile/profile] (fn [[{:keys [contacts admins]} all-contacts current-multiaccount]] - (contact.db/get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount))) + (get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount))) (re-frame/reg-sub :contacts/contacts-by-chat @@ -243,7 +310,16 @@ (re-frame/subscribe [:contacts/contacts]) (re-frame/subscribe [:profile/profile])]) (fn [[{:keys [contacts admins]} all-contacts current-multiaccount]] - (contact.db/get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount))) + (get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount))) + +(defn- contact-by-address + [[addr contact] address] + (when (address/address= addr address) + contact)) + +(defn find-contact-by-address + [contacts address] + (some #(contact-by-address % address) contacts)) (re-frame/reg-sub :contacts/contact-by-address @@ -252,7 +328,7 @@ (fn [[contacts multiaccount] [_ address]] (if (address/address= address (:public-key multiaccount)) multiaccount - (contact.db/find-contact-by-address contacts address)))) + (find-contact-by-address contacts address)))) (re-frame/reg-sub :contacts/contact-customization-color-by-address diff --git a/translations/en.json b/translations/en.json index 13db041b1f..c3a21f00ca 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2076,6 +2076,7 @@ "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.", + "unblocking-a-user-message": "After unblocking {{username}}, you will be able to connect with them as a contact and see their messages in group chats and communities.", "group-details": "Group details", "edit-name-and-image": "Edit name and image", "change-group-privacy": "Change group privacy",