Fix android tabbar animation

Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
Gheorghe Pinzaru 2020-03-20 12:38:44 +03:00
parent dd7b3c21ae
commit 81070f07b0
No known key found for this signature in database
GPG Key ID: C9A094959935A952
13 changed files with 132 additions and 97 deletions

View File

@ -43,6 +43,7 @@
"react-native-mail"
"react-native-shake"
"@react-native-community/netinfo"
"react-native-gesture-handler"
"react-native-safe-area-context"]
;; Desktop modules
:desktop-modules ["buffer"

View File

@ -274,3 +274,6 @@
(def safe-area-consumer (adapt-class (object/get js-dependencies/safe-area-context "SafeAreaConsumer")))
(def safe-area-view (adapt-class (object/get js-dependencies/safe-area-context "SafeAreaView")))
(def touchable-without-feedback-gesture (adapt-class (object/get js-dependencies/react-native-gesture-handler "TouchableWithoutFeedback")))

View File

@ -42,3 +42,5 @@
(def react-navigation-native (js/require "@react-navigation/native"))
(def react-navigation-stack (js/require "@react-navigation/stack"))
(def react-navigation-bottom-tabs (js/require "@react-navigation/bottom-tabs"))
(def react-native-gesture-handler (js/require "react-native-gesture-handler"))

View File

@ -11,19 +11,17 @@
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]))
(defonce visible? (animation/create-value 0))
(defonce minimized-state (reagent/atom nil))
(defonce visible-native (animation/create-value 0))
(defonce last-to-value (atom 1))
(defn animate
([visible duration to]
(animate visible duration to nil))
([visible duration to callback]
([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
(animation/timing visible-native
{:toValue to
:duration duration
:easing (animation/cubic)
@ -37,12 +35,8 @@
(defn minimize-bar [route-name]
(if (main-tab? route-name)
(do
(reset! minimized-state false)
(animate visible? 150 0))
(do
(reset! minimized-state true)
(animate visible? 150 1))))
(animate visible-native 150 0)
(animate visible-native 150 1)))
(def tabs-list-data
(->>
@ -73,31 +67,35 @@
(fn [{:keys [icon label active? nav-stack on-press
accessibility-label count-subscription]}]
(let [count (when count-subscription @(re-frame/subscribe [count-subscription]))]
[react/touchable-highlight {:style tabs.styles/touchable-container
:on-press on-press
:accessibility-label accessibility-label}
[react/view {:style tabs.styles/tab-container}
[react/view {:style tabs.styles/icon-container}
[vector-icons/icon icon (tabs.styles/icon active?)]
(when count
(cond
(or (pos? count) (pos? (:other count)))
[react/view {:style (if (= nav-stack :chat-stack)
tabs.styles/message-counter
tabs.styles/counter)}
[badge/message-counter (or (:other count) count) true]]
(pos? (:public count))
[react/view {:style tabs.styles/counter-public-container}
[react/view {:style tabs.styles/counter-public
:accessibility-label :public-unread-badge}]]))]
(when-not platform/desktop?
[react/view {:style tabs.styles/tab-title-container}
[react/text {:style (tabs.styles/tab-title active?)}
label]])]])))
[react/view {:style tabs.styles/touchable-container}
[react/touchable-without-feedback-gesture
{:style {:height "100%"
:width "100%"}
:on-press on-press
:accessibility-label accessibility-label}
[react/view {:style tabs.styles/tab-container}
[react/view {:style tabs.styles/icon-container}
[vector-icons/icon icon (tabs.styles/icon active?)]
(when count
(cond
(or (pos? count) (pos? (:other count)))
[react/view {:style (if (= nav-stack :chat-stack)
tabs.styles/message-counter
tabs.styles/counter)}
[badge/message-counter (or (:other count) count) true]]
(pos? (:public count))
[react/view {:style tabs.styles/counter-public-container}
[react/view {:style tabs.styles/counter-public
:accessibility-label :public-unread-badge}]]))]
(when-not platform/desktop?
[react/view {:style tabs.styles/tab-title-container}
[react/text {:style (tabs.styles/tab-title active?)}
label]])]]])))
(defn tabs []
(let [listeners (atom [])
keyboard-shown? (reagent/atom false)]
(let [listeners (atom [])
keyboard-shown? (reagent/atom false)
keyboard-visible (animation/create-value 0)]
(reagent/create-class
{:component-did-mount
(fn []
@ -106,10 +104,20 @@
listeners
[(.addListener react/keyboard "keyboardDidShow"
(fn []
(reset! keyboard-shown? true)))
(reset! keyboard-shown? true)
(reagent/flush)
(animation/start
(animation/timing keyboard-visible
{:toValue 1
:duration 200}))))
(.addListener react/keyboard "keyboardDidHide"
(fn []
(reset! keyboard-shown? false)))])))
(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)
@ -118,25 +126,24 @@
(.remove listener)))))
:reagent-render
(fn [{:keys [navigate index inset]}]
[react/animated-view {:style (tabs.styles/tabs-wrapper @keyboard-shown? @minimized-state inset)}
[react/animated-view {:style (tabs.styles/animated-container visible?)}
[react/view
{:style tabs.styles/tabs-container}
[react/view {:style tabs.styles/tabs}
(for [[route-index
{:keys [nav-stack accessibility-label count-subscription content]}]
tabs-list-data
:let [{:keys [icon title]} content]]
^{:key nav-stack}
[tab
{:icon icon
:label title
:on-press #(navigate (name nav-stack))
:accessibility-label accessibility-label
:count-subscription count-subscription
:active? (= (str index) (str route-index))
:nav-stack nav-stack}])]]]
[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)}
(for [[route-index
{:keys [nav-stack accessibility-label count-subscription content]}]
tabs-list-data
:let [{:keys [icon title]} content]]
^{:key nav-stack}
[tab
{:icon icon
:label title
:on-press #(navigate (name nav-stack))
:accessibility-label accessibility-label
:count-subscription count-subscription
:active? (= (str index) (str route-index))
:nav-stack nav-stack}])]
[react/view
{:style (tabs.styles/ios-titles-cover inset)}]])})))

View File

@ -15,7 +15,7 @@
(def tabs-diff (- tabs-height minimized-tabs-height))
(def minimized-tab-ratio
(/ minimized-tabs-height tabs-height))
(/ tabs-height minimized-tabs-height))
(def counter
{:right 0
@ -81,30 +81,23 @@
{:color (if active? colors/blue colors/gray)
:font-size 11})
(styles/def tabs-container
{:height minimized-tabs-height
:align-self :stretch
(defn animated-container [visible? inset]
{:flex-direction :row
:shadow-radius 4
:shadow-offset {:width 0 :height -5}
:shadow-opacity 0.3
:shadow-color "rgba(0, 9, 26, 0.12)"
:elevation 8
:background-color :white
:ios {:shadow-radius 4
:shadow-offset {:width 0 :height -5}
:shadow-opacity 0.3
:shadow-color "rgba(0, 9, 26, 0.12)"}
:desktop {:background-color :white
:shadow-radius 4
:shadow-offset {:width 0 :height -5}
:shadow-opacity 0.3
:shadow-color "rgba(0, 9, 26, 0.12)"}})
(def tabs
{:align-self :stretch
:padding-horizontal 8
:flex-direction :row})
(defn animated-container [visible?]
{:transform [{:translateY
(animation/interpolate visible?
{:inputRange [0 1]
:outputRange [(- tabs-diff) 0]})}]})
:position :absolute
:left 0
:right 0
:height tabs-height
:bottom inset
:transform [{:translateY
(animation/interpolate visible?
{:inputRange [0 1]
:outputRange [0 tabs-diff]})}]})
(defn ios-titles-cover [inset]
{:background-color :white
@ -115,11 +108,18 @@
:right 0
:left 0})
(defn tabs-wrapper [keyboard minimized inset]
(merge {:padding-bottom inset
:elevation 8
:padding-top (if minimized 0 tabs-diff)
:background-color :white}
(defn tabs-wrapper [keyboard visible]
(merge {:padding-horizontal 8
:elevation 8
:left 0
:right 0
:bottom 0
:transform [{:translateY
(animation/interpolate visible
{:inputRange [0 1]
:outputRange [0 tabs-height]})}]}
(when keyboard
{:position :absolute
:bottom (- tabs-height)})))
{:position :absolute})))
(defn space-handler [inset]
{:height (+ inset minimized-tabs-height)})

View File

@ -4,7 +4,6 @@
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.components.tabbar.styles :as main-tabs.styles]
[status-im.ui.components.styles :as components.styles]
[status-im.constants :as constants]
[status-im.utils.platform :as utils.platform]
@ -112,7 +111,12 @@
:label :t/invite-friends}])])
(views/defview bottom-container [{:keys [on-press disabled label accessibility-label]}]
[react/view {:style main-tabs.styles/tabs-container}
[react/view {:style {:height 52
:elevation 8
:shadow-radius 4
:shadow-offset {:width 0 :height -5}
:shadow-opacity 0.3
:shadow-color "rgba(0, 9, 26, 0.12)"}}
[react/view {:style components.styles/flex}]
[react/view {:style styles/bottom-container}
[components.common/bottom-button

View File

@ -4,7 +4,6 @@
[status-im.i18n :as i18n]
[reagent.core :as reagent]
[clojure.string :as string]
[status-im.ui.components.tabbar.styles :as main-tabs.styles]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.utils.platform :as utils.platform]
@ -52,8 +51,12 @@
(defn footer [syncing]
[react/touchable-highlight {:on-press (when-not @syncing
synchronize-installations!)
;; TODO: Inspect the need of coupling with tabbar here
:style main-tabs.styles/tabs-container}
:style {:height 52
:elevation 8
:shadow-radius 4
:shadow-offset {:width 0 :height -5}
:shadow-opacity 0.3
:shadow-color "rgba(0, 9, 26, 0.12)"}}
[react/view
{:style styles/footer-content}
[react/text

View File

@ -1,7 +1,8 @@
(ns status-im.ui.screens.routing.browser-stack
(:require [status-im.ui.screens.routing.core :as navigation]
[status-im.ui.screens.browser.open-dapp.views :as open-dapp]
[status-im.ui.screens.browser.views :as browser]))
[status-im.ui.screens.browser.views :as browser]
[status-im.ui.components.tabbar.styles :as tabbar.styles]))
(defonce stack (navigation/create-stack))
@ -9,6 +10,7 @@
[stack {:initial-route-name :open-dapp
:header-mode :none}
[{:name :open-dapp
:style {:padding-bottom tabbar.styles/tabs-diff}
:component open-dapp/open-dapp}
{:name :browser
:back-handler :noop

View File

@ -7,6 +7,7 @@
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.chat.models.loading :as chat.loading]
[status-im.ui.screens.group.events :as group.events]
[status-im.ui.components.tabbar.styles :as tabbar.styles]
[status-im.ui.screens.stickers.views :as stickers]))
(defonce stack (navigation/create-stack))
@ -16,6 +17,7 @@
:header-mode :none}
[{:name :home
:on-focus [::chat.loading/offload-all-messages]
:style {:padding-bottom tabbar.styles/tabs-diff}
:component home/home}
{:name :chat
:on-focus [::chat.loading/load-messages]

View File

@ -45,14 +45,19 @@
(remove-back-handler-listener "hardwareBackPress" on-back-press))))
#js [])))
(defn wrapped-screen-style [{:keys [insets]} insets-obj]
(defn wrapped-screen-style [{:keys [insets style]} insets-obj]
(merge
{:background-color :white
:flex 1}
style
(when (get insets :bottom)
{:padding-bottom (oget insets-obj "bottom")})
{:padding-bottom (+ (oget insets-obj "bottom")
(get style :padding-bottom)
(get style :padding-vertical))})
(when (get insets :top true)
{:padding-top (oget insets-obj "top")})))
{:padding-top (+ (oget insets-obj "top")
(get style :padding-top)
(get style :padding-vertical))})))
(defn presentation-type [{:keys [transition] :as opts}]
(if (and platform/ios? (= transition :presentation-ios))

View File

@ -35,6 +35,7 @@
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
[status-im.ui.screens.hardwallet.pin.views :as hardwallet.pin]
[status-im.ui.screens.hardwallet.settings.views :as hardwallet.settings]
[status-im.ui.components.tabbar.styles :as tabbar.styles]
[status-im.ui.screens.routing.core :as navigation]))
(defonce stack (navigation/create-stack))
@ -43,6 +44,7 @@
[stack {:initial-route-name :my-profile
:header-mode :none}
[{:name :my-profile
:style {:padding-bottom tabbar.styles/tabs-diff}
:component profile.user/my-profile}
{:name :contacts-list
:component contacts-list/contacts-list}

View File

@ -10,6 +10,7 @@
[status-im.ui.screens.wallet.add-new.views :as add-account]
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
[status-im.ui.screens.wallet.events :as wallet.events]
[status-im.ui.components.tabbar.styles :as tabbar.styles]
[status-im.ui.screens.routing.core :as navigation]))
(defonce stack (navigation/create-stack))
@ -18,6 +19,7 @@
[stack {:initial-route-name :wallet
:header-mode :none}
[{:name :wallet
:style {:padding-bottom tabbar.styles/tabs-diff}
:component wallet.accounts/accounts-overview}
{:name :wallet-account
:component wallet.account/account}

View File

@ -66,3 +66,5 @@
(def react-navigation-stack #js {:createStackNavigator identity
:TransitionPresets #js {:ModalPresentationIOS #js {}}})
(def react-navigation-bottom-tabs #js {:createBottomTabNavigator identity})
(def react-native-gesture-handler #js {})