Tabs animation

This commit is contained in:
virvar 2016-06-09 15:55:43 +03:00
parent ff5e4c66c3
commit 16d8060c28
5 changed files with 104 additions and 35 deletions

View File

@ -1,11 +1,16 @@
(ns status-im.components.main-tabs
(:require-macros [status-im.utils.views :refer [defview]])
(:require-macros [reagent.ratom :refer [reaction]]
[status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[reagent.core :as r]
[status-im.components.react :refer [view
animated-view
text-input
text
image
touchable-highlight]]
touchable-highlight
get-dimensions]]
[status-im.components.animation :as anim]
[status-im.chats-list.screen :refer [chats-list]]
[status-im.discovery.screen :refer [discovery]]
[status-im.contacts.screen :refer [contact-list]]
@ -14,33 +19,91 @@
[status-im.components.styles :as common-st]
[status-im.i18n :refer [label]]))
(def window-width (:width (get-dimensions "window")))
(def tab-list
[{:view-id :chat-list
:title (label :t/chats)
:screen chats-list
:icon :icon_tab_chats}
:icon :icon_tab_chats
:index 0}
{:view-id :discovery
:title (label :t/discovery)
:screen discovery
:icon :icon_tab_discovery}
:icon :icon_tab_discovery
:index 1}
{:view-id :contact-list
:title (label :t/contacts)
:screen contact-list
:icon :icon_tab_contacts}])
:icon :icon_tab_contacts
:index 2}])
(defn show-view? [current-view view-id]
(let [key-map {:key view-id}]
(if (= current-view view-id)
(merge st/show-tab key-map)
(merge st/hide-tab key-map))))
(defn animation-logic [{:keys [offsets val tab-id to-tab-id]}]
(fn [_]
(when-let [offsets @offsets]
(let [from-value (:from offsets)
to-value (:to offsets)
to-tab-id @to-tab-id]
(anim/set-value val from-value)
(when to-value
(anim/start
(anim/timing val {:toValue to-value
:duration 300})
(when (= tab-id to-tab-id)
(fn [arg]
(when (.-finished arg)
(dispatch [:on-navigated-to-tab]))))))))))
(defn tab-view [current-view {:keys [view-id screen]}]
[view (show-view? current-view view-id)
(defn get-tab-index-by-id [id]
(:index (first (filter #(= id (:view-id %)) tab-list))))
(defn get-offsets [tab-id from-id to-id]
(let [tab (get-tab-index-by-id tab-id)
from (get-tab-index-by-id from-id)
to (get-tab-index-by-id to-id)]
(if (or (= tab from) (= tab to))
(cond
(or (nil? from) (= from to)) {:from 0}
(< from to) (if (= tab to)
{:from window-width, :to 0}
{:from 0, :to (- window-width)})
(< to from) (if (= tab to)
{:from (- window-width), :to 0}
{:from 0, :to window-width}))
{:from (- window-width)})))
(defn tab-view-container [tab-id content]
(let [cur-tab-id (subscribe [:get :view-id])
prev-tab-id (subscribe [:get :prev-tab-view-id])
offsets (reaction (get-offsets tab-id @prev-tab-id @cur-tab-id))
anim-value (anim/create-value (- window-width))
context {:offsets offsets
:val anim-value
:tab-id tab-id
:to-tab-id cur-tab-id}
on-update (animation-logic context)]
(r/create-class
{:component-did-mount
on-update
:component-did-update
on-update
:reagent-render
(fn [tab-id content]
@offsets
[animated-view {:style (st/tab-view-container anim-value)}
content])})))
(defn tab-view [{:keys [view-id screen]}]
^{:key view-id}
[tab-view-container view-id
[screen]])
(defview main-tabs []
[view-id [:get :view-id]]
[view common-st/flex
(doall (map #(tab-view view-id %1) tab-list))
[tabs {:selected-view-id view-id
:tab-list tab-list}]])
[view-id [:get :view-id]
tab-animation? [:get :prev-tab-view-id]]
[view {:style common-st/flex}
[view {:style common-st/flex
:pointerEvents (if tab-animation? :none :auto)}
(doall (map #(tab-view %) tab-list))]
[tabs {:selected-view-id view-id
:tab-list tab-list}]])

View File

@ -29,4 +29,4 @@
(def default-chat-color color-purple)
(def flex
{:style {:flex 1}})
{:flex 1})

View File

@ -54,17 +54,11 @@
:justifyContent :center
:alignItems :center})
(def show-tab
{:flex 1
:pointerEvents :auto
:position :absolute
:top 0
:left 0
:right 0
:bottom tab-height})
(def hide-tab
{:opacity 0
:pointerEvents :none
:overflow :hidden})
(defn tab-view-container [offset-x]
{:flex 1
:position :absolute
:top 0
:left 0
:right 0
:bottom tab-height
:transform [{:translateX offset-x}]})

View File

@ -10,9 +10,9 @@
[status-im.components.tabs.styles :as st]))
(defview tab [{:keys [view-id title icon selected-view-id]}]
[touchable-highlight {:style st/tab
:onPress #(dispatch [:navigate-to
view-id])}
[touchable-highlight {:style st/tab
:disabled (= view-id selected-view-id)
:onPress #(dispatch [:navigate-to-tab view-id])}
[view {:style st/tab-container}
[image {:source {:uri icon}
:style st/tab-icon}]

View File

@ -43,6 +43,18 @@
(assoc :view-id view-id)
(assoc :navigation-stack navigation-stack'))))))
(register-handler :navigate-to-tab
(enrich preload-data!)
(fn [db [_ view-id]]
(-> db
(assoc :prev-tab-view-id (:view-id db))
(replace-view view-id))))
(register-handler :on-navigated-to-tab
(enrich preload-data!)
(fn [db [_]]
(assoc db :prev-tab-view-id nil)))
(register-handler :show-group-new
(debug
(fn [db _]