Improve shell animations (#14341)

This commit is contained in:
Parvesh Monu 2022-11-15 16:45:43 +05:30 committed by GitHub
parent 1228f4aa26
commit f408035f5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 99 additions and 75 deletions

View File

@ -50,11 +50,13 @@ export function stackPointer (stackId, selectedStackId) {
);
}
export function bottomTabIconColor (stackId, selectedStackId, passThrough, selectedTabColor, defaultColor, passThroughColor) {
export function bottomTabIconColor (stackId, selectedStackId, homeStackOpen,
passThrough, selectedTabColor, defaultColor,
passThroughColor) {
return useDerivedValue(
function () {
'worklet'
if (selectedStackId.value == stackId){
if (selectedStackId.value == stackId && homeStackOpen.value){
return selectedTabColor;
}
else if (passThrough.value){
@ -70,8 +72,10 @@ export function bottomTabIconColor (stackId, selectedStackId, passThrough, selec
// Home Stack
const shellAnimationTime = 200;
const defaultDurationAndEasing = {
duration: 300,
duration: shellAnimationTime,
easing: Easing.bezier(0, 0, 1, 1),
}

View File

@ -60,10 +60,12 @@
[_]
(let [pressed? (reagent/atom false)]
(fn [{:keys [type label on-press count customization-color style]}]
[rn/touchable-without-feedback
[rn/touchable-opacity
{:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
:on-press on-press
:active-opacity 1
:style {:padding 5}
:accessibility-label type}
[rn/view {:style (merge
{:flex-direction :row

View File

@ -1,5 +1,6 @@
(ns quo2.components.navigation.floating-shell-button
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.dynamic-button :as dynamic-button]))
(defn dynamic-button-view [type dynamic-buttons style]
@ -16,21 +17,28 @@
"[floating-shell-button dynamic-buttons style]
dynamic-buttons
{:button-type {:on-press on-press :count count}}"
[dynamic-buttons style]
[rn/view {:style (merge {:flex-direction :row
:margin-horizontal 12} style)}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons {:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[rn/view {:style {:flex 1}}
[rn/view {:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]])
[dynamic-buttons style opacity-anim pointer-anim]
[:f>
(fn []
(let [original-style (merge {:flex-direction :row
:margin-horizontal 12} style)
animated-style (reanimated/apply-animations-to-style
{:opacity opacity-anim
:pointer-events pointer-anim}
original-style)]
[reanimated/view {:style animated-style}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons {:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[rn/view {:style {:flex 1}}
[rn/view {:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]]))])

View File

@ -37,10 +37,7 @@
(defn get-shared-values []
(let [selected-stack-id-sv (reanimated/use-shared-value
;; passing keywords or nil is not working with reanimated
(name (if @selected-stack-id @selected-stack-id :none)))
;; Second shared value of selected-stack-id required to make sure stack is still visible while minimizing
selected-stack-id-sv2 (reanimated/use-shared-value
(name (if @selected-stack-id @selected-stack-id :none)))
(name (or @selected-stack-id :communities-stack)))
pass-through-sv (reanimated/use-shared-value @pass-through?)
home-stack-open-sv (reanimated/use-shared-value @home-stack-open?)
animate-home-stack-left (reanimated/use-shared-value (not @home-stack-open?))
@ -54,22 +51,22 @@
acc
stack-opacity-keyword (.stackOpacity
^js reanimated/worklet-factory
(name id) selected-stack-id-sv2)
(name id) selected-stack-id-sv)
stack-pointer-keyword (.stackPointer
^js reanimated/worklet-factory
(name id) selected-stack-id-sv2)
(name id) selected-stack-id-sv)
tabs-icon-color-keyword (.bottomTabIconColor
^js reanimated/worklet-factory
(name id) selected-stack-id-sv pass-through-sv
colors/white colors/neutral-50 colors/white-opa-40))))
(name id) selected-stack-id-sv home-stack-open-sv
pass-through-sv colors/white colors/neutral-50
colors/white-opa-40))))
{:selected-stack-id selected-stack-id-sv
:selected-stack-id2 selected-stack-id-sv2
:pass-through? pass-through-sv
:home-stack-open? home-stack-open-sv
:animate-home-stack-left animate-home-stack-left
:home-stack-left (.homeStackLeft
^js reanimated/worklet-factory
selected-stack-id-sv2 animate-home-stack-left home-stack-open-sv
selected-stack-id-sv animate-home-stack-left home-stack-open-sv
(clj->js (:left home-stack-position)))
:home-stack-top (.homeStackTop
^js reanimated/worklet-factory
@ -85,24 +82,33 @@
;; Animation
(defn change-tab [shared-values stack-id]
(when-not (colors/dark?)
(js/setTimeout #(re-frame/dispatch [:change-root-status-bar-style :dark]) 300))
(if @home-stack-open?
(reanimated/set-shared-value (:animate-home-stack-left shared-values) false)
(reset! home-stack-open? true))
(reset! selected-stack-id stack-id)
(reanimated/set-shared-value (:selected-stack-id2 shared-values) (name stack-id))
(defn open-home-stack [shared-values stack-id]
(reanimated/set-shared-value (:selected-stack-id shared-values) (name stack-id))
(reanimated/set-shared-value (:home-stack-open? shared-values) true)
(when-not (colors/dark?)
(js/setTimeout
#(re-frame/dispatch [:change-root-status-bar-style :dark])
constants/shell-animation-time))
(reset! home-stack-open? true)
(reset! selected-stack-id stack-id)
(async-storage/set-item! :selected-stack-id stack-id))
(defn change-tab [shared-values stack-id]
(reanimated/set-shared-value (:animate-home-stack-left shared-values) false)
(reanimated/set-shared-value (:selected-stack-id shared-values) (name stack-id))
(reset! selected-stack-id stack-id)
(async-storage/set-item! :selected-stack-id stack-id))
(defn bottom-tab-on-press [shared-values stack-id]
(if @home-stack-open?
(change-tab shared-values stack-id)
(open-home-stack shared-values stack-id)))
(defn close-home-stack [shared-values]
(re-frame/dispatch [:change-root-status-bar-style :light])
(reanimated/set-shared-value (:animate-home-stack-left shared-values) true)
(reanimated/set-shared-value (:home-stack-open? shared-values) false)
(when-not (colors/dark?)
(re-frame/dispatch [:change-root-status-bar-style :light]))
(reset! home-stack-open? false)
(reset! selected-stack-id nil)
(reanimated/set-shared-value (:home-stack-open? shared-values) false)
(reanimated/set-shared-value (:selected-stack-id shared-values) "none")
(async-storage/set-item! :selected-stack-id nil))

View File

@ -3,7 +3,6 @@
[reagent.core :as reagent]
[re-frame.core :as re-frame]
[status-im.switcher.styles :as styles]
[status-im.utils.platform :as platform]
[status-im.switcher.constants :as constants]
[status-im.switcher.animation :as animation]
[quo2.components.navigation.bottom-nav-tab :as bottom-nav-tab]))
@ -33,11 +32,8 @@
(defn bottom-tab-on-press [shared-values stack-id]
(when-not (= stack-id @animation/selected-stack-id)
(let [stack-load-delay (cond
@animation/home-stack-open? 0
platform/android? 250
:else 300)]
(animation/change-tab shared-values stack-id)
(let [stack-load-delay (if @animation/home-stack-open? 0 constants/shell-animation-time)]
(animation/bottom-tab-on-press shared-values stack-id)
(js/setTimeout #(load-selected-stack stack-id) stack-load-delay))))
(defn bottom-tab [icon stack-id shared-values]

View File

@ -4,13 +4,15 @@
[status-im.utils.handlers :refer [<sub]]
[status-im.utils.platform :as platform]))
(def shell-animation-time 200)
(defn bottom-tabs-container-height []
(if platform/android? 57 82))
(defn bottom-tabs-extended-container-height []
(if platform/android? 90 120))
(def status-bar-offset
(defn status-bar-offset []
(if platform/android? (.-currentHeight ^js rn/status-bar) 0))
;; status bar height is not included in : the dimensions/window for devices with a notch
@ -18,8 +20,8 @@
(defn dimensions []
(let [{:keys [width height]} (<sub [:dimensions/window])]
{:width width
:height (if (> status-bar-offset 28)
(+ height status-bar-offset)
:height (if (> (status-bar-offset) 28)
(+ height (status-bar-offset))
height)}))
(def stacks-ids [:communities-stack :chats-stack :wallet-stack :browser-stack])

View File

@ -1,14 +1,11 @@
(ns status-im.switcher.home-stack
(:require [react-native.reanimated :as reanimated]
[status-im.i18n.i18n :as i18n]
[status-im.switcher.styles :as styles]
[status-im.switcher.animation :as animation]
[status-im.ui2.screens.chat.home :as chat.home]
(:require [status-im.switcher.styles :as styles]
[react-native.reanimated :as reanimated]
[status-im.switcher.constants :as constants]
[status-im.ui2.screens.chat.home :as chat.home]
[status-im.switcher.bottom-tabs :as bottom-tabs]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
[quo2.components.navigation.floating-shell-button :as floating-shell-button]
[status-im.ui2.screens.communities.communities-home :as communities-home]))
(defn load-stack? [stack-id]
@ -53,9 +50,4 @@
[stack-view :communities-stack shared-values]
[stack-view :chats-stack shared-values]
[stack-view :browser-stack shared-values]
[stack-view :wallet-stack shared-values]
[floating-shell-button/floating-shell-button
{:jump-to {:on-press #(animation/close-home-stack shared-values)
:label (i18n/label :t/jump-to)}}
{:position :absolute
:bottom 12}]]))])
[stack-view :wallet-stack shared-values]]))])

View File

@ -1,8 +1,11 @@
(ns status-im.switcher.shell-stack
(:require [status-im.switcher.shell :as shell]
(:require [status-im.i18n.i18n :as i18n]
[status-im.switcher.shell :as shell]
[status-im.switcher.constants :as constants]
[status-im.switcher.animation :as animation]
[status-im.switcher.home-stack :as home-stack]
[status-im.switcher.bottom-tabs :as bottom-tabs]))
[status-im.switcher.bottom-tabs :as bottom-tabs]
[quo2.components.navigation.floating-shell-button :as floating-shell-button]))
(defn shell-stack []
[:f>
@ -11,4 +14,11 @@
[:<>
[shell/shell]
[bottom-tabs/bottom-tabs shared-values]
[home-stack/home-stack shared-values]]))])
[home-stack/home-stack shared-values]
[floating-shell-button/floating-shell-button
{:jump-to {:on-press #(animation/close-home-stack shared-values)
:label (i18n/label :t/jump-to)}}
{:position :absolute
:bottom (+ (constants/bottom-tabs-container-height) 7)} ;; bottom offset is 12 = 7 + 5(padding on button)
(:home-stack-opacity shared-values)
(:home-stack-pointer shared-values)]]))])

View File

@ -2,6 +2,7 @@
(:require [react-native.core :as rn]
[status-im.ui2.screens.quo2-preview.preview :as preview]
[reagent.core :as reagent]
[react-native.reanimated :as reanimated]
[quo2.components.navigation.floating-shell-button :as quo2]
[quo2.foundations.colors :as colors]
[status-im.i18n.i18n :as i18n]))
@ -43,13 +44,16 @@
(defn cool-preview []
(let [state (reagent/atom {:show-jump-to? true
:scroll-type :notification-down})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60
:align-items :center}
[quo2/floating-shell-button (mock-data @state)]]]])))
[:f>
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60
:align-items :center}
[quo2/floating-shell-button (mock-data @state)
nil (reanimated/use-shared-value 1)
(reanimated/use-shared-value "auto")]]]])]))
(defn preview-floating-shell-button []
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)