diff --git a/src/js/worklets/profile_header.js b/src/js/worklets/profile_header.js new file mode 100644 index 0000000000..f26ee27690 --- /dev/null +++ b/src/js/worklets/profile_header.js @@ -0,0 +1,14 @@ +import { useAnimatedStyle, withTiming } from 'react-native-reanimated'; + +export function profileHeaderAnimation(scrollY, threshold, topBarHeight) { + return useAnimatedStyle(() => { + 'worklet'; + const opacity = scrollY.value < threshold ? withTiming(0) : withTiming(1); + const translateY = scrollY.value < threshold ? withTiming(topBarHeight) : withTiming(0); + + return { + opacity: opacity, + transform: [{ translateY: translateY }], + }; + }); +} diff --git a/src/mocks/js_dependencies.cljs b/src/mocks/js_dependencies.cljs index 9302e5ba00..c9d908745b 100644 --- a/src/mocks/js_dependencies.cljs +++ b/src/mocks/js_dependencies.cljs @@ -431,6 +431,7 @@ "../src/js/worklets/chat/messenger/composer.js" #js {} "../src/js/worklets/chat/messenger/placeholder.js" #js {} "../src/js/worklets/parallax.js" #js {} + "../src/js/worklets/profile_header.js" #js {} "../src/js/worklets/identifiers_highlighting.js" #js {} "./fleets.js" default-fleets "../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json")) diff --git a/src/quo/components/navigation/page_nav/view.cljs b/src/quo/components/navigation/page_nav/view.cljs index 00802d221d..a317a4ddee 100644 --- a/src/quo/components/navigation/page_nav/view.cljs +++ b/src/quo/components/navigation/page_nav/view.cljs @@ -11,7 +11,9 @@ [quo.components.markdown.text :as text] [quo.components.navigation.page-nav.style :as style] [quo.theme :as theme] - [react-native.core :as rn])) + [react-native.core :as rn] + [react-native.reanimated :as reanimated] + [utils.worklets.profile-header :as header-worklet])) (def ^:private button-type {:white :grey @@ -85,14 +87,24 @@ :else nil)]) +(def header-height 155) +(def page-nav-height 25) +(def threshold (- header-height page-nav-height)) + (defn- title-center - [{:keys [centered? title center-opacity]}] - [rn/view {:style (style/center-content-container centered? center-opacity)} - [text/text - {:weight :medium - :size :paragraph-1 - :number-of-lines 1} - title]]) + [{:keys [centered? title center-opacity scroll-y]}] + (let [animated-style (when scroll-y + (header-worklet/profile-header-animation scroll-y + threshold + page-nav-height))] + [reanimated/view + {:style [(style/center-content-container centered? center-opacity) + animated-style]} + [text/text + {:weight :medium + :size :paragraph-1 + :number-of-lines 1} + title]])) (defn- dropdown-center [{:keys [theme background dropdown-on-press dropdown-selected? dropdown-text center-opacity]}] @@ -295,6 +307,7 @@ `:title` - title - text-align: `:center` or `:left` + - scroll-y: a shared value (optional) `:dropdown` - dropdown-on-press: a callback - dropdown-selected?: a boolean diff --git a/src/status_im/contexts/profile/settings/view.cljs b/src/status_im/contexts/profile/settings/view.cljs index bf605b9cbc..76965eb723 100644 --- a/src/status_im/contexts/profile/settings/view.cljs +++ b/src/status_im/contexts/profile/settings/view.cljs @@ -9,6 +9,7 @@ [status-im.contexts.profile.settings.header.view :as settings.header] [status-im.contexts.profile.settings.list-items :as settings.items] [status-im.contexts.profile.settings.style :as style] + [status-im.contexts.profile.utils :as profile.utils] [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -42,7 +43,9 @@ (let [insets (safe-area/get-insets) customization-color (rf/sub [:profile/customization-color]) scroll-y (reanimated/use-shared-value 0) - logout-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])] + logout-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed]) + profile (rf/sub [:profile/profile]) + full-name (profile.utils/displayed-name profile)] [quo/overlay {:type :shell} [rn/view {:key :header @@ -50,7 +53,11 @@ :inset (:top insets) :theme theme})} [quo/page-nav - {:background :blur + {:title full-name + :background :blur + :type :title + :text-align :left + :scroll-y scroll-y :icon-name :i/close :on-press #(rf/dispatch [:navigate-back]) :right-side [{:icon-name :i/multi-profile diff --git a/src/utils/worklets/profile_header.cljs b/src/utils/worklets/profile_header.cljs new file mode 100644 index 0000000000..a5d1fc0a45 --- /dev/null +++ b/src/utils/worklets/profile_header.cljs @@ -0,0 +1,10 @@ +(ns utils.worklets.profile-header) + +(def ^:private worklets (js/require "../src/js/worklets/profile_header.js")) + +(defn profile-header-animation + [scroll-y threshold top-bar-height] + (.profileHeaderAnimation ^js worklets + scroll-y + threshold + top-bar-height))