Tabs animation
This commit is contained in:
parent
ff5e4c66c3
commit
16d8060c28
|
@ -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))
|
||||
[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}]])
|
||||
|
|
|
@ -29,4 +29,4 @@
|
|||
(def default-chat-color color-purple)
|
||||
|
||||
(def flex
|
||||
{:style {:flex 1}})
|
||||
{:flex 1})
|
||||
|
|
|
@ -54,17 +54,11 @@
|
|||
:justifyContent :center
|
||||
:alignItems :center})
|
||||
|
||||
(def show-tab
|
||||
(defn tab-view-container [offset-x]
|
||||
{:flex 1
|
||||
:pointerEvents :auto
|
||||
:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom tab-height})
|
||||
|
||||
(def hide-tab
|
||||
{:opacity 0
|
||||
:pointerEvents :none
|
||||
:overflow :hidden})
|
||||
|
||||
:bottom tab-height
|
||||
:transform [{:translateX offset-x}]})
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
(defview tab [{:keys [view-id title icon selected-view-id]}]
|
||||
[touchable-highlight {:style st/tab
|
||||
:onPress #(dispatch [:navigate-to
|
||||
view-id])}
|
||||
: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}]
|
||||
|
|
|
@ -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 _]
|
||||
|
|
Loading…
Reference in New Issue