Tabs animation

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

View File

@ -1,11 +1,16 @@
(ns status-im.components.main-tabs (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]] (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[reagent.core :as r]
[status-im.components.react :refer [view [status-im.components.react :refer [view
animated-view
text-input text-input
text text
image image
touchable-highlight]] touchable-highlight
get-dimensions]]
[status-im.components.animation :as anim]
[status-im.chats-list.screen :refer [chats-list]] [status-im.chats-list.screen :refer [chats-list]]
[status-im.discovery.screen :refer [discovery]] [status-im.discovery.screen :refer [discovery]]
[status-im.contacts.screen :refer [contact-list]] [status-im.contacts.screen :refer [contact-list]]
@ -14,33 +19,91 @@
[status-im.components.styles :as common-st] [status-im.components.styles :as common-st]
[status-im.i18n :refer [label]])) [status-im.i18n :refer [label]]))
(def window-width (:width (get-dimensions "window")))
(def tab-list (def tab-list
[{:view-id :chat-list [{:view-id :chat-list
:title (label :t/chats) :title (label :t/chats)
:screen chats-list :screen chats-list
:icon :icon_tab_chats} :icon :icon_tab_chats
:index 0}
{:view-id :discovery {:view-id :discovery
:title (label :t/discovery) :title (label :t/discovery)
:screen discovery :screen discovery
:icon :icon_tab_discovery} :icon :icon_tab_discovery
:index 1}
{:view-id :contact-list {:view-id :contact-list
:title (label :t/contacts) :title (label :t/contacts)
:screen contact-list :screen contact-list
:icon :icon_tab_contacts}]) :icon :icon_tab_contacts
:index 2}])
(defn show-view? [current-view view-id] (defn animation-logic [{:keys [offsets val tab-id to-tab-id]}]
(let [key-map {:key view-id}] (fn [_]
(if (= current-view view-id) (when-let [offsets @offsets]
(merge st/show-tab key-map) (let [from-value (:from offsets)
(merge st/hide-tab key-map)))) 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]}] (defn get-tab-index-by-id [id]
[view (show-view? current-view view-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]]) [screen]])
(defview main-tabs [] (defview main-tabs []
[view-id [:get :view-id]] [view-id [:get :view-id]
[view common-st/flex tab-animation? [:get :prev-tab-view-id]]
(doall (map #(tab-view view-id %1) tab-list)) [view {:style common-st/flex}
[tabs {:selected-view-id view-id [view {:style common-st/flex
:tab-list tab-list}]]) :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 default-chat-color color-purple)
(def flex (def flex
{:style {:flex 1}}) {:flex 1})

View File

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

View File

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

View File

@ -43,6 +43,18 @@
(assoc :view-id view-id) (assoc :view-id view-id)
(assoc :navigation-stack navigation-stack')))))) (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 (register-handler :show-group-new
(debug (debug
(fn [db _] (fn [db _]