Skip to content

Commit bb508b2

Browse files
[#17986] refactor: apply header animation on scroll list
1 parent b7d054e commit bb508b2

File tree

6 files changed

+109
-41
lines changed

6 files changed

+109
-41
lines changed

Diff for: src/quo/foundations/colors.cljs

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
(def black-opa-30 (alpha black 0.3))
149149
(def black-opa-60 (alpha black 0.6))
150150
(def onboarding-header-black "#000716")
151-
151+
(def border-avatar-light "#475060") ;; Simulate blur transparent avatar's border in light mode
152152
;;;;Primary
153153

154154
;;Solid
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
(ns status-im2.contexts.profile.settings.header.avatar
2+
(:require [quo.core :as quo]
3+
[quo.theme :as quo.theme]
4+
[react-native.reanimated :as reanimated]
5+
[status-im2.contexts.profile.settings.header.style :as style]))
6+
(defonce ^:const scroll-animation-input-range [0 50])
7+
(def header-extrapolation-option
8+
{:extrapolateLeft "clamp"
9+
:extrapolateRight "clamp"})
10+
(defn f-avatar
11+
[{:keys [scroll-y full-name online? profile-picture customization-color]}]
12+
(let [image-scale-animation (reanimated/interpolate scroll-y
13+
scroll-animation-input-range
14+
[1 0.5]
15+
header-extrapolation-option)
16+
image-top-margin-animation (reanimated/interpolate scroll-y
17+
scroll-animation-input-range
18+
[0 20]
19+
header-extrapolation-option)
20+
image-side-margin-animation (reanimated/interpolate scroll-y
21+
scroll-animation-input-range
22+
[0 -20]
23+
header-extrapolation-option)
24+
theme (quo.theme/get-theme)]
25+
[reanimated/view
26+
{:style (style/avatar-container theme
27+
image-scale-animation
28+
image-top-margin-animation
29+
image-side-margin-animation)}
30+
[quo/user-avatar
31+
{:full-name full-name
32+
:online? online?
33+
:profile-picture profile-picture
34+
:status-indicator? true
35+
:ring? true
36+
:customization-color customization-color
37+
:size :big}]]))
38+
39+
(defn view
40+
[props]
41+
[:f> f-avatar props])

Diff for: src/status_im2/contexts/profile/settings/header/header_shape.cljs

+10-10
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44
[react-native.svg :as svg]
55
[status-im2.contexts.profile.settings.header.style :as style]))
66

7-
(defn left-shape
7+
(defn left-radius
88
[background-color]
9-
[svg/svg {:width "109" :height "68" :viewBox "0 0 109 68" :fill "none"}
9+
[svg/svg {:width "20" :height "20" :viewBox "0 0 20 20" :fill "none"}
1010
[svg/path
11-
{:d
12-
"M0 0H109V48H103.821C101.8 25.574 82.9522 8 60 8C36.9215 8 17.993 25.768 16.1475 48.3707C6.94517 50.1664 0 58.2721 0 68V0Z"
11+
{:d "M20 0C7 2 0 10 0 20V0H15Z"
1312
:fill background-color}]])
1413

15-
(defn right-shape
14+
(defn right-radius
1615
[background-color]
17-
[svg/svg {:width "25" :height "68" :viewBox "0 0 25 68" :fill "none"}
16+
[svg/svg {:width "20" :height "21" :viewBox "0 0 20 21" :fill "none"}
1817
[svg/path
19-
{:d "M0.000610352 0H24.5005V68L24.5003 68C24.5003 56.9543 15.546 48 4.50031 48H0.000610352V0Z"
18+
{:d "M20 20V0H0C11 0 20 9 20 20Z"
2019
:fill background-color}]])
2120

2221
(defn view
2322
[customization-color theme]
2423
(let [background-color (colors/resolve-color customization-color theme 40)]
25-
[rn/view {:style style/header-shape-container}
26-
[left-shape background-color]
24+
[rn/view
2725
[rn/view {:style (style/header-middle-shape background-color)}]
28-
[right-shape background-color]]))
26+
[rn/view {:style style/radius-container}
27+
[left-radius background-color]
28+
[right-radius background-color]]]))
+23-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
(ns status-im2.contexts.profile.settings.header.style
2-
(:require [quo.foundations.colors :as colors]))
2+
(:require [quo.foundations.colors :as colors]
3+
[react-native.reanimated :as reanimated]))
4+
35
(defonce ^:const navigation-bar-height 100)
46
(defonce ^:const header-offset 56)
57

@@ -9,11 +11,12 @@
911
:min-height 100
1012
:flex 1})
1113

12-
(def avatar-container
14+
(def avatar-row-wrapper
1315
{:display :flex
14-
:padding-left 20
16+
:padding-left 16
1517
:padding-right 12
16-
:margin-top -56
18+
:margin-top -60
19+
:margin-bottom -4
1720
:align-items :flex-end
1821
:justify-content :space-between
1922
:flex-direction :row})
@@ -22,11 +25,24 @@
2225
{:padding-horizontal 20
2326
:padding-vertical 12})
2427

25-
(def header-shape-container
26-
{:flex-direction :row})
27-
2828
(defn header-middle-shape
2929
[background-color]
3030
{:background-color background-color
3131
:height 48
3232
:flex-grow 1})
33+
34+
(def radius-container
35+
{:flex-direction :row
36+
:justify-content :space-between})
37+
38+
(defn avatar-container
39+
[theme scale-animation top-margin-animation side-margin-animation]
40+
(reanimated/apply-animations-to-style
41+
{:transform [{:scale scale-animation}]
42+
:margin-top top-margin-animation
43+
:margin-left side-margin-animation
44+
:margin-bottom side-margin-animation}
45+
{:align-items :flex-start
46+
:border-width 4
47+
:border-color (colors/theme-colors colors/border-avatar-light colors/neutral-80-opa-80 theme)
48+
:border-radius 100}))
+16-18
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
(ns status-im2.contexts.profile.settings.header.view
22
(:require [clojure.string :as string]
33
[quo.core :as quo]
4-
[quo.theme :as quo.theme]
54
[react-native.core :as rn]
5+
[status-im2.contexts.profile.settings.header.avatar :as header.avatar]
66
[status-im2.contexts.profile.settings.header.header-shape :as header.shape]
77
[status-im2.contexts.profile.settings.header.style :as style]
88
[status-im2.contexts.profile.utils :as profile.utils]
99
[utils.i18n :as i18n]
1010
[utils.re-frame :as rf]))
1111

1212
(defn- f-view
13-
[theme]
13+
[{:keys [theme scroll-y]}]
1414
(let [{:keys [public-key emoji-hash] :as profile} (rf/sub [:profile/profile-with-image])
1515
online? (rf/sub [:visibility-status-updates/online?
1616
public-key])
@@ -20,28 +20,26 @@
2020
emoji-string (string/join emoji-hash)]
2121
[rn/view
2222
[header.shape/view customization-color theme]
23-
[rn/view {:style style/avatar-container}
24-
[quo/user-avatar
25-
{:full-name full-name
23+
[rn/view {:style style/avatar-row-wrapper}
24+
[header.avatar/view
25+
{:scroll-y scroll-y
26+
:display-name full-name
2627
:online? online?
27-
:profile-picture profile-picture
28-
:status-indicator? true
29-
:ring? true
3028
:customization-color customization-color
31-
:size :big}]
32-
[quo/dropdown
33-
{:background :blur
34-
:size :size-32
35-
:type :outline
36-
:icon? true
37-
:icon-name :i/online}
38-
(i18n/label :t/status-always-online)]]
29+
:profile-picture profile-picture}]
30+
[rn/view {:style {:margin-bottom 4}}
31+
[quo/dropdown
32+
{:background :blur
33+
:size :size-32
34+
:type :outline
35+
:icon? true
36+
:icon-name :i/online}
37+
(i18n/label :t/online)]]]
3938
[quo/text-combinations
4039
{:container-style style/title-container
4140
:emoji-hash emoji-string
4241
:title full-name}]]))
4342

44-
(defn- internal-header-view
43+
(defn view
4544
[params]
4645
[:f> f-view params])
47-
(def view (quo.theme/with-theme internal-header-view))

Diff for: src/status_im2/contexts/profile/settings/view.cljs

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
(ns status-im2.contexts.profile.settings.view
2-
(:require [quo.core :as quo]
2+
(:require [oops.core :as oops]
3+
[quo.core :as quo]
34
[quo.theme :as quo.theme]
45
[react-native.core :as rn]
6+
[react-native.reanimated :as reanimated]
57
[react-native.safe-area :as safe-area]
68
[status-im2.common.not-implemented :as not-implemented]
79
[status-im2.contexts.profile.settings.constants :as settings.constants]
@@ -13,16 +15,21 @@
1315

1416
(defn- f-settings-item-view
1517
[data]
16-
(println data)
1718
[quo/category
1819
{:list-type :settings
1920
:blur? true
2021
:data data}])
2122

23+
(defn scroll-handler
24+
[event scroll-y]
25+
(let [current-y (oops/oget event "nativeEvent.contentOffset.y")]
26+
(reanimated/set-shared-value scroll-y current-y)))
27+
2228
(defn- settings-view
2329
[theme]
2430
(let [insets (safe-area/get-insets)
25-
customization-color (rf/sub [:profile/customization-color])]
31+
customization-color (rf/sub [:profile/customization-color])
32+
scroll-y (reanimated/use-shared-value 0)]
2633
[quo/overlay {:type :shell}
2734
[rn/view {:style {:flex 1}}
2835
[rn/view
@@ -38,14 +45,20 @@
3845
{:icon-name :i/share
3946
:on-press #(debounce/dispatch-and-chill [:open-modal :share-shell] 1000)}]}]]
4047
[rn/flat-list
41-
{:header [settings.header/view]
48+
{:header [settings.header/view {:scroll-y scroll-y}]
4249
:data settings.constants/settings-items
4350
:key-fn str
4451
:shows-vertical-scroll-indicator false
4552
:render-fn f-settings-item-view
4653
:footer [rn/view {:style style/footer-container}
4754
[quo/button {:type :danger :icon-left :i/log-out}
4855
(i18n/label :t/logout)]]
56+
:scroll-event-throttle 16
57+
:on-scroll #(scroll-handler % scroll-y)
4958
:bounces false}]]]))
5059

51-
(def view (quo.theme/with-theme settings-view))
60+
(defn- internal-view
61+
[props]
62+
[:f> settings-view props])
63+
64+
(def view (quo.theme/with-theme internal-view))

0 commit comments

Comments
 (0)