From 9ed4cc03e3e6852f47688fcd9bac39df2d12274d Mon Sep 17 00:00:00 2001 From: virvar Date: Wed, 15 Jun 2016 16:41:08 +0300 Subject: [PATCH 1/2] Grey action bar. Hide navbar on chat list scroll. --- src/status_im/chats_list/screen.cljs | 39 ++++++++++++++++---- src/status_im/components/tabs/styles.cljs | 19 ++++------ src/status_im/components/tabs/tabs.cljs | 45 +++++++++++++++++++---- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index 572f0ac5a9..afd8047b39 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -1,4 +1,5 @@ (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 @@ -13,33 +14,55 @@ 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]) + chat-scrolled? (subscribe [:get :chats-scrolled?]) + 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}] + [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 @chat-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?])))}] [action-button {:buttonColor color-blue :offsetY 16 :offsetX 16} diff --git a/src/status_im/components/tabs/styles.cljs b/src/status_im/components/tabs/styles.cljs index 45af60e439..7dc57d6d24 100644 --- a/src/status_im/components/tabs/styles.cljs +++ b/src/status_im/components/tabs/styles.cljs @@ -10,21 +10,19 @@ 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 [offset-y] + {:height tabs-height + :backgroundColor color-white + :marginBottom offset-y}) (def top-gradient {:flexDirection :row :height 3}) -(def tabs-container +(def tabs-inner-container {:flexDirection :row :height tab-height :opacity 1 @@ -55,10 +53,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..bc326a7d43 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,37 @@ :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]}] + (fn [_] + (let [to-value (if @hidden? (- st/tab-height) 0)] + (anim/start + (anim/timing val {:toValue to-value + :duration 300}) + (fn [e] + (when-not (.-finished e) + nil)))))) + +(defn tabs-container [& children] + (let [chats-scrolled? (subscribe [:get :chats-scrolled?]) + anim-value (anim/create-value 0) + context {:hidden? chats-scrolled? + :val anim-value} + on-update (animation-logic context)] + (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 anim-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))]]) From 8622859c3a1fc256c63b437c10ba2e6ce0d93824 Mon Sep 17 00:00:00 2001 From: virvar Date: Thu, 16 Jun 2016 12:44:56 +0300 Subject: [PATCH 2/2] Improve tabs bar animation --- src/status_im/chats_list/screen.cljs | 42 +++++++++++++---------- src/status_im/chats_list/styles.cljs | 11 +++++- src/status_im/components/tabs/styles.cljs | 6 ++-- src/status_im/components/tabs/tabs.cljs | 30 +++++++++------- src/status_im/db.cljs | 3 +- 5 files changed, 58 insertions(+), 34 deletions(-) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index afd8047b39..ad4624f798 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -4,6 +4,7 @@ [status-im.components.react :refer [list-view list-item view + animated-view text image touchable-highlight]] @@ -38,7 +39,9 @@ (defn chats-list [] (let [chats (subscribe [:get :chats]) - chat-scrolled? (subscribe [:get :chats-scrolled?]) + 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]) @@ -53,7 +56,7 @@ ;;; if "maximazing" chat list will make scroll to 0, ;;; then disable maximazing :onLayout (fn [event] - (when-not @chat-scrolled? + (when-not @chats-scrolled? (let [height (.. event -nativeEvent -layout -height)] (reset! container-height height)))) :onContentSizeChange (fn [width height] @@ -62,19 +65,22 @@ (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?])))}] - [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}]]]]]))) + (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 7dc57d6d24..2d873e88cd 100644 --- a/src/status_im/components/tabs/styles.cljs +++ b/src/status_im/components/tabs/styles.cljs @@ -13,10 +13,12 @@ (def tabs-height 59) (def tab-height 56) -(defn tabs-container [offset-y] +(defn tabs-container [hidden? animation? offset-y] {:height tabs-height :backgroundColor color-white - :marginBottom offset-y}) + :marginBottom (if (or hidden? animation?) + (- tabs-height) 0) + :transform [{:translateY (if animation? offset-y 1)}]}) (def top-gradient {:flexDirection :row diff --git a/src/status_im/components/tabs/tabs.cljs b/src/status_im/components/tabs/tabs.cljs index bc326a7d43..a6d10d5d8d 100644 --- a/src/status_im/components/tabs/tabs.cljs +++ b/src/status_im/components/tabs/tabs.cljs @@ -20,21 +20,27 @@ [tab data])) (defn animation-logic [{:keys [hidden? val]}] - (fn [_] - (let [to-value (if @hidden? (- st/tab-height) 0)] - (anim/start - (anim/timing val {:toValue to-value - :duration 300}) - (fn [e] - (when-not (.-finished e) - nil)))))) + (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?]) - anim-value (anim/create-value 0) - context {:hidden? chats-scrolled? - :val anim-value} + 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 @@ -43,7 +49,7 @@ :reagent-render (fn [& children] @chats-scrolled? - (into [animated-view {:style (st/tabs-container anim-value) + (into [animated-view {:style (st/tabs-container @chats-scrolled? @animation? @tabs-bar-value) :pointerEvents (if @chats-scrolled? :none :auto)}] children))}))) 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]