Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify tabbar animation #11107

Merged
merged 1 commit into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/quo/animated.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
:ease-in (bezier 0.42 0 1 1)
:ease-out (bezier 0 0 0.58 1)
:ease-in-out (bezier 0.42 0 0.58 1)
:cubic (bezier 0.55 0.055 0.675 0.19)
:keyboard (bezier 0.17 0.59 0.4 0.77)})

(def springs {:lazy {:damping 50
Expand Down
103 changes: 32 additions & 71 deletions src/status_im/ui/components/tabbar/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,24 @@
[quo.gesture-handler :as gesture-handler]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[cljs-bean.core :refer [bean]]
[status-im.i18n :as i18n]
[status-im.ui.components.animation :as animation]
[quo.components.safe-area :as safe-area]
[status-im.ui.screens.routing.core :as navigation]
[quo.animated :as animated]
[quo.react-native :as rn]
[status-im.ui.components.badge :as badge]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.tabbar.styles :as tabs.styles]
[status-im.utils.platform :as platform]))

(defonce visible-native (animation/create-value 0))
(defonce last-to-value (atom 1))

(defn animate
([visible-native duration to]
(animate visible-native duration to nil))
([visible-native duration to callback]
(when (not= to @last-to-value)
(reset! last-to-value to)
(animation/start
(animation/timing visible-native
{:toValue to
:duration duration
:easing (animation/cubic)
:useNativeDriver true})
callback))))

(defn main-tab? [view-id]
(contains?
#{:home :wallet :open-dapp :my-profile :wallet-onboarding-setup}
#{:chat-stack :browser-stack :wallet-stack :profile-stack
:home :wallet :open-dapp :my-profile :wallet-onboarding-setup}
view-id))

(defn minimize-bar [route-name]
(if (main-tab? route-name)
(animate visible-native 150 0)
(animate visible-native 150 1)))

(def tabs-list-data
(->>
[{:nav-stack :chat-stack
Expand Down Expand Up @@ -89,45 +72,25 @@
[react/text {:style (tabs.styles/tab-title active?)}
label]]]]])))

(defn tabs []
(let [listeners (atom [])
keyboard-shown? (reagent/atom false)
keyboard-visible (animation/create-value 0)]
(reagent/create-class
{:component-did-mount
(fn []
(when platform/android?
(reset!
listeners
[(.addListener ^js react/keyboard "keyboardDidShow"
(fn []
(reset! keyboard-shown? true)
(reagent/flush)
(animation/start
(animation/timing keyboard-visible
{:toValue 1
:duration 200}))))
(.addListener ^js react/keyboard "keyboardDidHide"
(fn []
(animation/start
(animation/timing keyboard-visible
{:toValue 0
:duration 200})
#(do (reset! keyboard-shown? false)
(reagent/flush)))))])))
:component-will-unmount
(fn []
(when (not-empty @listeners)
(doseq [^js listener @listeners]
(when listener
(.remove listener)))))
:reagent-render
(fn [{:keys [navigate index inset]}]
[react/animated-view {:style (tabs.styles/tabs-wrapper @keyboard-shown? keyboard-visible)
:pointer-events (if @keyboard-shown? "none" "auto")}
[react/animated-view {:style (tabs.styles/space-handler inset)
:pointer-events "none"}]
[react/animated-view {:style (tabs.styles/animated-container visible-native inset)}
(def tabs
(reagent/adapt-react-class
(fn [props]
(let [{:keys [navigate index route]} (bean props)
{:keys [keyboard-shown]
:or {keyboard-shown false}} (when platform/android? (rn/use-keyboard))
{:keys [bottom]} (safe-area/use-safe-area)
animated-visible (animated/use-timing-transition
(main-tab? (keyword route))
{:duration 150})
keyboard-visible (animated/use-timing-transition
keyboard-shown
{:duration 200})]
(reagent/as-element
[animated/view {:style (tabs.styles/tabs-wrapper keyboard-shown keyboard-visible)
:pointer-events (if keyboard-shown "none" "auto")}
[animated/view {:style (tabs.styles/space-handler bottom)
:pointer-events "none"}]
[animated/view {:style (tabs.styles/animated-container animated-visible bottom)}
(for [[route-index
{:keys [nav-stack accessibility-label count-subscription content]}]
tabs-list-data
Expand All @@ -142,15 +105,13 @@
:active? (= (str index) (str route-index))
:nav-stack nav-stack}])]
[react/view
{:style (tabs.styles/ios-titles-cover inset)}]])})))
{:style (tabs.styles/ios-titles-cover bottom)}]])))))

(defn tabbar [props]
(let [navigate (oget props "navigation" "navigate")
index (oget props "state" "index")]
state (bean (oget props "state"))
index (get state :index)]
(reagent/as-element
[react/safe-area-consumer
(fn [insets]
(reagent/as-element
[tabs {:navigate navigate
:index index
:inset (oget insets "bottom")}]))])))
[tabs {:navigate navigate
:route (navigation/get-active-route-name state)
:index index}])))
14 changes: 4 additions & 10 deletions src/status_im/ui/components/tabbar/styles.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns status-im.ui.components.tabbar.styles
(:require [status-im.ui.components.animation :as animation]
(:require [quo.animated :as animated]
[status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform]))

Expand Down Expand Up @@ -84,17 +84,14 @@
:shadow-color (if (colors/dark?)
"rgba(0, 0, 0, 0.75)"
"rgba(0, 9, 26, 0.12)")
:elevation 8
:elevation 8
:background-color colors/white
:position :absolute
:left 0
:right 0
:height tabs-height
:bottom inset
:transform [{:translateY
(animation/interpolate visible?
{:inputRange [0 1]
:outputRange [0 tabs-diff]})}]})
:transform [{:translateY (animated/mix visible? tabs-diff 0)}]})

(defn ios-titles-cover [inset]
{:background-color colors/white
Expand All @@ -111,10 +108,7 @@
:left 0
:right 0
:bottom 0
:transform [{:translateY
(animation/interpolate visible
{:inputRange [0 1]
:outputRange [0 tabs-height]})}]}
:transform [{:translateY (animated/mix visible 0 tabs-height)}]}
(when keyboard
{:position :absolute})))

Expand Down
7 changes: 7 additions & 0 deletions src/status_im/ui/screens/routing/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
["@react-navigation/stack" :refer (createStackNavigator TransitionPresets)]
["@react-navigation/bottom-tabs" :refer (createBottomTabNavigator)]
[reagent.core :as reagent]
[cljs-bean.core :refer [bean]]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
Expand All @@ -28,6 +29,12 @@
[callback]
(.removeEventListener BackHandler "hardwareBackPress" callback))

(defn get-active-route-name [{:keys [index routes]}]
(let [route (bean (get routes index))]
(if-let [inner-state (get route :state)]
(get-active-route-name (bean inner-state))
(some-> (get route :name) keyword))))

(def transition-presets TransitionPresets)

(def modal-presentation-ios (merge (js->clj (.-ModalPresentationIOS ^js transition-presets))
Expand Down
13 changes: 2 additions & 11 deletions src/status_im/ui/screens/views.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns status-im.ui.screens.views
(:require [status-im.utils.universal-links.core :as utils.universal-links]
[re-frame.core :as re-frame]
[cljs-bean.core :refer [bean]]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.components.react :as react]
[status-im.ui.screens.routing.core :as navigation]
Expand All @@ -13,7 +14,6 @@
[status-im.ui.screens.popover.views :as popover]
[status-im.ui.screens.multiaccounts.recover.views :as recover.views]
[status-im.ui.screens.wallet.send.views :as wallet]
[status-im.ui.components.tabbar.core :as tabbar]
[status-im.ui.components.status-bar.view :as statusbar]
status-im.ui.screens.wallet.collectibles.etheremon.views
status-im.ui.screens.wallet.collectibles.cryptostrikers.views
Expand Down Expand Up @@ -71,17 +71,8 @@
(reset! state state-obj)
(resolve true)))))

(defn get-active-route-name [state]
(let [index (get state "index")
route (get-in state ["routes" index])]
(if-let [state' (get route "state")]
(get-active-route-name state')
(some-> (get route "name") keyword))))

(defn on-state-change [state]
(let [route-name (get-active-route-name (js->clj state))]
(tabbar/minimize-bar route-name)

(let [route-name (navigation/get-active-route-name (bean state))]
;; NOTE(Ferossgp): Keycard did-load events backward compatibility
(re-frame/dispatch [:screens/on-will-focus route-name])

Expand Down