diff --git a/src/quo/components/list_items/user.cljs b/src/quo/components/list_items/user.cljs index f4b40ac0ea..f1434a539c 100644 --- a/src/quo/components/list_items/user.cljs +++ b/src/quo/components/list_items/user.cljs @@ -18,9 +18,9 @@ :align-items :center}) (defn action-icon - [{:keys [type on-press on-check disabled? checked?]} theme] + [{:keys [type on-press on-check disabled? checked?]} customization-color theme] [rn/touchable-opacity - {:on-press (when on-press on-press)} + {:on-press on-press} (case type :options [icons/icon :i/options @@ -30,6 +30,7 @@ [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)}] @@ -68,4 +69,4 @@ :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} short-chat-key])] (when accessory - [action-icon accessory theme])]]) + [action-icon accessory customization-color theme])]]) diff --git a/src/react_native/gesture.cljs b/src/react_native/gesture.cljs index 2f0bdb6fcd..eafc4b8c11 100644 --- a/src/react_native/gesture.cljs +++ b/src/react_native/gesture.cljs @@ -95,13 +95,34 @@ (into [{:title title :header? true}] data)) sections)) +(defn- find-sticky-indices + [data] + (->> data + (map-indexed (fn [index item] (when (:header? item) index))) + (remove nil?) + (vec))) + +(defn- is-last-item-in-section + [data index] + (let [next-item (nth data (inc index) nil)] + (or (nil? next-item) (:header? next-item)))) + (defn section-list - [{:keys [sections render-section-header-fn render-fn] :as props}] + [{:keys [sections sticky-section-headers-enabled render-section-header-fn render-section-footer-fn + render-fn] + :or {sticky-section-headers-enabled true} + :as props}] (let [data (flatten-sections sections)] [flat-list (merge props - {:data data - :render-fn (fn [p1 p2 p3 p4] - (if (:header? p1) - [render-section-header-fn p1 p2 p3 p4] - [render-fn p1 p2 p3 p4]))})])) + {:data data + :render-fn (fn [p1 p2 p3 p4] + [:<> + (if (:header? p1) + [render-section-header-fn p1 p2 p3 p4] + [render-fn p1 p2 p3 p4]) + (when (and render-section-footer-fn + (is-last-item-in-section data p2)) + [render-section-footer-fn p1 p2 p3 p4])]) + :sticky-header-indices (when sticky-section-headers-enabled + (find-sticky-indices data))})])) diff --git a/src/status_im/common/contact_list/style.cljs b/src/status_im/common/contact_list/style.cljs index ebd7f77b6e..cf45907a5c 100644 --- a/src/status_im/common/contact_list/style.cljs +++ b/src/status_im/common/contact_list/style.cljs @@ -1,5 +1,9 @@ -(ns status-im.common.contact-list.style) +(ns status-im.common.contact-list.style + (:require [quo.foundations.colors :as colors])) + +(def contacts-section-footer + {:height 8}) (defn contacts-section-header - [first-item?] - {:padding-top (if first-item? 0 8)}) + [theme] + {:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}) diff --git a/src/status_im/common/contact_list/view.cljs b/src/status_im/common/contact_list/view.cljs index ecbc6fc076..690ab3098f 100644 --- a/src/status_im/common/contact_list/view.cljs +++ b/src/status_im/common/contact_list/view.cljs @@ -1,10 +1,16 @@ (ns status-im.common.contact-list.view (:require [quo.core :as quo] + [quo.theme] [react-native.core :as rn] [status-im.common.contact-list.style :as style])) +(defn contacts-section-footer + [] + [rn/view style/contacts-section-footer]) + (defn contacts-section-header - [{:keys [title index]}] - [rn/view (style/contacts-section-header (= index 0)) - [quo/divider-label title]]) + [{:keys [title]}] + (let [theme (quo.theme/use-theme-value)] + [rn/view (style/contacts-section-header theme) + [quo/divider-label title]])) diff --git a/src/status_im/contexts/chat/group_details/view.cljs b/src/status_im/contexts/chat/group_details/view.cljs index 27088acd71..cfbf434e9a 100644 --- a/src/status_im/contexts/chat/group_details/view.cljs +++ b/src/status_im/contexts/chat/group_details/view.cljs @@ -62,6 +62,7 @@ :sticky-section-headers-enabled false :sections (rf/sub [:contacts/grouped-by-first-letter]) :render-section-header-fn contact-list/contacts-section-header + :render-section-footer-fn contact-list/contacts-section-footer :content-container-style {:padding-bottom 20} :render-data {:group group} :render-fn add-member-contact-item-render}] diff --git a/src/status_im/contexts/chat/home/new_chat/styles.cljs b/src/status_im/contexts/chat/home/new_chat/styles.cljs index 89ed5aab11..86f79cb5e3 100644 --- a/src/status_im/contexts/chat/home/new_chat/styles.cljs +++ b/src/status_im/contexts/chat/home/new_chat/styles.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.chat.home.new-chat.styles (:require + [quo.foundations.colors :as colors] [react-native.safe-area :as safe-area])) (def contact-selection-heading @@ -9,11 +10,16 @@ :margin-top 24 :margin-bottom 16}) -(def chat-button - {:position :absolute - :bottom (+ 12 (safe-area/get-bottom)) - :left 20 - :right 20}) +(defn chat-button-container + [theme] + {:position :absolute + :bottom 0 + :padding-bottom 33 + :background-color (colors/theme-colors colors/white-opa-70 colors/neutral-95-opa-70 theme) + :padding-top 12 + :padding-horizontal 20 + :left 0 + :right 0}) (defn no-contacts [] diff --git a/src/status_im/contexts/chat/home/new_chat/view.cljs b/src/status_im/contexts/chat/home/new_chat/view.cljs index 07f5fa4ec3..ff14da6fc9 100644 --- a/src/status_im/contexts/chat/home/new_chat/view.cljs +++ b/src/status_im/contexts/chat/home/new_chat/view.cljs @@ -2,7 +2,7 @@ (:require [quo.core :as quo] [quo.foundations.colors :as colors] - [quo.theme :as quo.theme] + [quo.theme] [re-frame.core :as re-frame] [react-native.core :as rn] [react-native.gesture :as gesture] @@ -85,11 +85,13 @@ :on-check on-toggle}} item])) -(defn- view-internal - [{:keys [scroll-enabled? on-scroll close theme]}] - (let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) +(defn view + [{:keys [scroll-enabled? on-scroll close]}] + (let [theme (quo.theme/use-theme-value) + contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) selected-contacts-count (rf/sub [:selected-contacts-count]) selected-contacts (rf/sub [:group/selected-contacts]) + customization-color (rf/sub [:profile/customization-color]) one-contact-selected? (= selected-contacts-count 1) [has-error? set-has-error] (rn/use-state false) render-fn (rn/use-callback (fn [item] @@ -111,7 +113,9 @@ {:weight :semi-bold :size :heading-1 :style {:color (colors/theme-colors colors/neutral-100 colors/white theme)}} - (i18n/label :t/new-chat)] + (if (or (not contacts-selected?) one-contact-selected?) + (i18n/label :t/new-chat) + (i18n/label :t/new-group-chat))] (when (seq contacts) [quo/text {:size :paragraph-2 @@ -126,25 +130,25 @@ (if (empty? contacts) [no-contacts-view {:theme theme}] [gesture/section-list - {:key-fn :title - :sticky-section-headers-enabled false - :sections (rf/sub [:contacts/filtered-active-sections]) - :render-section-header-fn contact-list/contacts-section-header - :content-container-style {:padding-bottom 70} - :render-fn render-fn - :scroll-enabled @scroll-enabled? - :on-scroll on-scroll}]) + {:key-fn :title + :sections (rf/sub [:contacts/filtered-active-sections]) + :render-section-header-fn contact-list/contacts-section-header + :render-section-footer-fn contact-list/contacts-section-footer + :content-container-style {:padding-bottom 70} + :render-fn render-fn + :scroll-enabled @scroll-enabled? + :on-scroll on-scroll}]) (when contacts-selected? - [quo/button - {:type :primary - :accessibility-label :next-button - :container-style style/chat-button - :on-press (fn [] - (if one-contact-selected? - (rf/dispatch [:chat.ui/start-chat public-key]) - (rf/dispatch [:navigate-to :new-group])))} - (if one-contact-selected? - (i18n/label :t/chat-with {:selected-user primary-name}) - (i18n/label :t/setup-group-chat))])])) - -(def view (quo.theme/with-theme view-internal)) + [rn/view + {:style (style/chat-button-container theme)} + [quo/button + {:type :primary + :customization-color customization-color + :accessibility-label :next-button + :on-press (fn [] + (if one-contact-selected? + (rf/dispatch [:chat.ui/start-chat public-key]) + (rf/dispatch [:navigate-to :new-group])))} + (if one-contact-selected? + (i18n/label :t/chat-with {:selected-user primary-name}) + (i18n/label :t/setup-group-chat))]])])) diff --git a/src/status_im/contexts/chat/home/view.cljs b/src/status_im/contexts/chat/home/view.cljs index ec18f3a0ce..5e44d1b56c 100644 --- a/src/status_im/contexts/chat/home/view.cljs +++ b/src/status_im/contexts/chat/home/view.cljs @@ -106,6 +106,7 @@ :sections items :sticky-section-headers-enabled false :render-section-header-fn contact-list/contacts-section-header + :render-section-footer-fn contact-list/contacts-section-footer :render-fn (fn [data] (contact-item-render data theme)) :scroll-event-throttle 8 @@ -126,48 +127,42 @@ :title (i18n/label :t/invite-friends-to-status) :description (i18n/label :t/share-invite-link)}}) -(defn- f-view-internal - [{:keys [theme]}] - (let [scroll-ref (atom nil) - set-scroll-ref #(reset! scroll-ref %)] - (fn [] - (let [{:keys [universal-profile-url]} (rf/sub [:profile/profile]) - customization-color (rf/sub [:profile/customization-color]) - pending-contact-requests (rf/sub [:activity-center/pending-contact-requests]) - selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent) - scroll-shared-value (reanimated/use-shared-value 0)] - [:<> - (if (= selected-tab :tab/contacts) - [contacts - {:pending-contact-requests pending-contact-requests - :set-scroll-ref set-scroll-ref - :scroll-shared-value scroll-shared-value - :theme theme}] - [chats - {:selected-tab selected-tab - :set-scroll-ref set-scroll-ref - :scroll-shared-value scroll-shared-value - :theme theme}]) - [:f> common.banner/animated-banner - {:content (banner-data universal-profile-url) - :customization-color customization-color - :scroll-ref scroll-ref - :tabs [{:id :tab/recent - :label (i18n/label :t/recent) - :accessibility-label :tab-recent} - {:id :tab/groups - :label (i18n/label :t/groups) - :accessibility-label :tab-groups} - {:id :tab/contacts - :label (i18n/label :t/contacts) - :accessibility-label :tab-contacts - :notification-dot? (pos? (count pending-contact-requests))}] - :selected-tab selected-tab - :on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab])) - :scroll-shared-value scroll-shared-value}]])))) - -(defn- internal-chats-home-view - [params] - [:f> f-view-internal params]) - -(def view (quo.theme/with-theme internal-chats-home-view)) +(defn view + [] + (let [theme (quo.theme/use-theme-value) + scroll-ref (rn/use-ref-atom nil) + set-scroll-ref (rn/use-callback #(reset! scroll-ref %)) + {:keys [universal-profile-url]} (rf/sub [:profile/profile]) + customization-color (rf/sub [:profile/customization-color]) + pending-contact-requests (rf/sub [:activity-center/pending-contact-requests]) + selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent) + scroll-shared-value (reanimated/use-shared-value 0)] + [:<> + (if (= selected-tab :tab/contacts) + [contacts + {:pending-contact-requests pending-contact-requests + :set-scroll-ref set-scroll-ref + :scroll-shared-value scroll-shared-value + :theme theme}] + [chats + {:selected-tab selected-tab + :set-scroll-ref set-scroll-ref + :scroll-shared-value scroll-shared-value + :theme theme}]) + [common.banner/animated-banner + {:content (banner-data universal-profile-url) + :customization-color customization-color + :scroll-ref scroll-ref + :tabs [{:id :tab/recent + :label (i18n/label :t/recent) + :accessibility-label :tab-recent} + {:id :tab/groups + :label (i18n/label :t/groups) + :accessibility-label :tab-groups} + {:id :tab/contacts + :label (i18n/label :t/contacts) + :accessibility-label :tab-contacts + :notification-dot? (pos? (count pending-contact-requests))}] + :selected-tab selected-tab + :on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab])) + :scroll-shared-value scroll-shared-value}]]))