diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index 572f0ac5a9..ad4624f798 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -1,8 +1,10 @@ (ns status-im.chats-list.screen + (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.components.react :refer [list-view list-item view + animated-view text image touchable-highlight]] @@ -13,45 +15,72 @@ action-button-item]] [status-im.components.drawer.view :refer [drawer-view open-drawer]] [status-im.components.styles :refer [color-blue + toolbar-background1 toolbar-background2]] [status-im.components.toolbar :refer [toolbar]] [status-im.components.icons.ionicons :refer [icon]] [status-im.i18n :refer [label]] - [status-im.chats-list.styles :as st])) + [status-im.chats-list.styles :as st] + [status-im.components.tabs.styles :refer [tabs-height]])) -(defn chats-list-toolbar [] +(defview chats-list-toolbar [] + [chats-scrolled? [:get :chats-scrolled?]] [toolbar {:nav-action {:image {:source {:uri :icon_hamburger} :style st/hamburger-icon} :handler open-drawer} :title (label :t/chats) - :background-color toolbar-background2 + :background-color (if chats-scrolled? + toolbar-background1 + toolbar-background2) ;; TODO implement search :action {:image {:source {:uri :icon_search} :style st/search-icon} :handler (fn [])}}]) (defn chats-list [] - (let [chats (subscribe [:get :chats])] + (let [chats (subscribe [:get :chats]) + chats-scrolled? (subscribe [:get :chats-scrolled?]) + animation? (subscribe [:animations :tabs-bar-animation?]) + tabs-bar-value (subscribe [:animations :tabs-bar-value]) + container-height (r/atom 0) + content-height (r/atom 0)] + (dispatch [:set :chats-scrolled? false]) (fn [] [drawer-view [view st/chats-container [chats-list-toolbar] - [list-view {:dataSource (to-datasource @chats) - :renderRow (fn [row _ _] - (list-item [chat-list-item row])) - :style st/list-container}] - [action-button {:buttonColor color-blue - :offsetY 16 - :offsetX 16} - [action-button-item - {:title (label :t/new-chat) - :buttonColor :#9b59b6 - :onPress #(dispatch [:navigate-to :contact-list])} - [icon {:name :android-create - :style st/create-icon}]] - [action-button-item - {:title (label :t/new-group-chat) - :buttonColor :#1abc9c - :onPress #(dispatch [:show-group-new])} - [icon {:name :person-stalker - :style st/person-stalker-icon}]]]]]))) + [list-view {:dataSource (to-datasource @chats) + :renderRow (fn [row _ _] + (list-item [chat-list-item row])) + :style st/list-container + ;;; if "maximazing" chat list will make scroll to 0, + ;;; then disable maximazing + :onLayout (fn [event] + (when-not @chats-scrolled? + (let [height (.. event -nativeEvent -layout -height)] + (reset! container-height height)))) + :onContentSizeChange (fn [width height] + (reset! content-height height)) + :onScroll (fn [e] + (let [offset (.. e -nativeEvent -contentOffset -y) + min-content-height (+ @container-height tabs-height) + scrolled? (and (< 0 offset) (< min-content-height @content-height))] + (dispatch [:set :chats-scrolled? scrolled?]) + (dispatch [:set-animation :tabs-bar-animation? true])))}] + [animated-view {:style (st/action-buttons-container @animation? (or @tabs-bar-value 0)) + :pointerEvents :box-none} + [action-button {:buttonColor color-blue + :offsetY 16 + :offsetX 16} + [action-button-item + {:title (label :t/new-chat) + :buttonColor :#9b59b6 + :onPress #(dispatch [:navigate-to :contact-list])} + [icon {:name :android-create + :style st/create-icon}]] + [action-button-item + {:title (label :t/new-group-chat) + :buttonColor :#1abc9c + :onPress #(dispatch [:show-group-new])} + [icon {:name :person-stalker + :style st/person-stalker-icon}]]]]]]))) diff --git a/src/status_im/chats_list/styles.cljs b/src/status_im/chats_list/styles.cljs index ca72f89042..6621aedfce 100644 --- a/src/status_im/chats_list/styles.cljs +++ b/src/status_im/chats_list/styles.cljs @@ -6,7 +6,8 @@ online-color text1-color text2-color - new-messages-count-color]])) + new-messages-count-color]] + [status-im.components.tabs.styles :refer [tabs-height]])) (def chat-container {:flexDirection :row @@ -113,3 +114,11 @@ {:fontSize 20 :height 22 :color :white}) + +(defn action-buttons-container [animation? offset-y] + {:position :absolute + :left 0 + :right 0 + :top 0 + :bottom 0 + :transform [{:translateY (if animation? offset-y 1)}]}) diff --git a/src/status_im/components/tabs/styles.cljs b/src/status_im/components/tabs/styles.cljs index 45af60e439..2d873e88cd 100644 --- a/src/status_im/components/tabs/styles.cljs +++ b/src/status_im/components/tabs/styles.cljs @@ -10,21 +10,21 @@ text2-color toolbar-background1]])) +(def tabs-height 59) (def tab-height 56) -(def tabs - {:flex 1 - :position :absolute - :bottom 0 - :right 0 - :left 0 - }) +(defn tabs-container [hidden? animation? offset-y] + {:height tabs-height + :backgroundColor color-white + :marginBottom (if (or hidden? animation?) + (- tabs-height) 0) + :transform [{:translateY (if animation? offset-y 1)}]}) (def top-gradient {:flexDirection :row :height 3}) -(def tabs-container +(def tabs-inner-container {:flexDirection :row :height tab-height :opacity 1 @@ -55,10 +55,9 @@ :alignItems :center}) (defn tab-view-container [offset-x] - {:flex 1 - :position :absolute + {:position :absolute :top 0 :left 0 :right 0 - :bottom tab-height + :bottom 0 :transform [{:translateX offset-x}]}) diff --git a/src/status_im/components/tabs/tabs.cljs b/src/status_im/components/tabs/tabs.cljs index bd12614f3f..a6d10d5d8d 100644 --- a/src/status_im/components/tabs/tabs.cljs +++ b/src/status_im/components/tabs/tabs.cljs @@ -2,6 +2,7 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] [status-im.components.react :refer [view + animated-view text-input text image @@ -9,7 +10,8 @@ linear-gradient]] [reagent.core :as r] [status-im.components.tabs.styles :as st] - [status-im.components.tabs.tab :refer [tab]])) + [status-im.components.tabs.tab :refer [tab]] + [status-im.components.animation :as anim])) (defn create-tab [index data selected-view-id] (let [data (merge data {:key index @@ -17,10 +19,43 @@ :selected-view-id selected-view-id})] [tab data])) -(defview tabs [{:keys [style tab-list selected-view-id]}] - (let [style (merge st/tabs style)] - [view {:style style} - [linear-gradient {:colors ["rgba(24, 52, 76, 0.01)" "rgba(24, 52, 76, 0.085)" "rgba(24, 52, 76, 0.165)"] - :style st/top-gradient}] - [view st/tabs-container - (doall (map-indexed #(create-tab %1 %2 selected-view-id) tab-list))]])) +(defn animation-logic [{:keys [hidden? val]}] + (let [was-hidden? (atom (not @hidden?))] + (fn [_] + (when (not= @was-hidden? @hidden?) + (let [to-value (if @hidden? 0 (- st/tabs-height))] + (swap! was-hidden? not) + (anim/start + (anim/timing val {:toValue to-value + :duration 300}) + (fn [e] + ;; if to-value was changed, then new animation has started + (when (= to-value (if @hidden? 0 (- st/tabs-height))) + (dispatch [:set-animation :tabs-bar-animation? false]))))))))) + +(defn tabs-container [& children] + (let [chats-scrolled? (subscribe [:get :chats-scrolled?]) + animation? (subscribe [:animations :tabs-bar-animation?]) + tabs-bar-value (subscribe [:animations :tabs-bar-value]) + context {:hidden? chats-scrolled? + :val @tabs-bar-value} + on-update (animation-logic context)] + (anim/set-value @tabs-bar-value 0) + (r/create-class + {:component-did-mount + on-update + :component-did-update + on-update + :reagent-render + (fn [& children] + @chats-scrolled? + (into [animated-view {:style (st/tabs-container @chats-scrolled? @animation? @tabs-bar-value) + :pointerEvents (if @chats-scrolled? :none :auto)}] + children))}))) + +(defn tabs [{:keys [tab-list selected-view-id]}] + [tabs-container + [linear-gradient {:colors ["rgba(24, 52, 76, 0.01)" "rgba(24, 52, 76, 0.085)" "rgba(24, 52, 76, 0.165)"] + :style st/top-gradient}] + [view st/tabs-inner-container + (doall (map-indexed #(create-tab %1 %2 selected-view-id) tab-list))]]) diff --git a/src/status_im/db.cljs b/src/status_im/db.cljs index 2b3ad6f88f..25772a58fa 100644 --- a/src/status_im/db.cljs +++ b/src/status_im/db.cljs @@ -44,7 +44,8 @@ :message-input-buttons-scale 1 :messages-offset 0 :commands-input-is-switching? false - :response-resize? false}}) + :response-resize? false + :tabs-bar-value (anim/create-value 0)}}) (def protocol-initialized-path [:protocol-initialized]) (defn chat-input-text-path [chat-id]