Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
702b8b5d9f | ||
|
|
2fd9e80650 |
@@ -1,6 +1,6 @@
|
||||
(ns quo2.components.animated-header-flatlist.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn container-view
|
||||
[view-height]
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
(defn blur-view
|
||||
[animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity animation}
|
||||
{:position :absolute
|
||||
:top 0
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
(defn entity-picture
|
||||
[animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:width animation
|
||||
:height animation}
|
||||
{:transform [{:scale 1}]
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
(defn header-bottom-part
|
||||
[animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:border-top-right-radius animation
|
||||
:border-top-left-radius animation}
|
||||
{:position :absolute
|
||||
@@ -66,9 +66,9 @@
|
||||
|
||||
(defn header-comp
|
||||
[y-animation opacity-animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
;; here using `left` won't work on Android, so we are using `translateX`
|
||||
{:transform [{:translateX (reanimated/use-shared-value 64)} {:translateY y-animation}]
|
||||
{:transform [{:translateX (ra/use-val 64)} {:translateY y-animation}]
|
||||
:opacity opacity-animation}
|
||||
{:position :absolute
|
||||
:z-index 3}))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[reagent.core :as reagent]
|
||||
@@ -18,16 +18,16 @@
|
||||
|
||||
(defn interpolate
|
||||
[value input-range output-range]
|
||||
(reanimated/interpolate value
|
||||
input-range
|
||||
output-range
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"}))
|
||||
(ra/interpolate value
|
||||
input-range
|
||||
output-range
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"}))
|
||||
|
||||
(defn scroll-handler
|
||||
[event initial-y scroll-y]
|
||||
(let [current-y (- (oops/oget event "nativeEvent.contentOffset.y") initial-y)]
|
||||
(reanimated/set-shared-value scroll-y current-y)))
|
||||
(ra/set-val scroll-y current-y)))
|
||||
|
||||
(defn header
|
||||
[{:keys [theme-color display-picture-comp cover-uri title-comp]} top-inset scroll-y]
|
||||
@@ -45,9 +45,9 @@
|
||||
{:style {:width "100%"
|
||||
:height cover-height}
|
||||
:source {:uri cover-uri}}])
|
||||
[reanimated/view {:style (style/header-bottom-part border-animation)}
|
||||
[ra/view {:style (style/header-bottom-part border-animation)}
|
||||
[title-comp]]
|
||||
[reanimated/view {:style (style/entity-picture size-animation)}
|
||||
[ra/view {:style (style/entity-picture size-animation)}
|
||||
[display-picture-comp image-animation]]]))
|
||||
|
||||
(defn animated-header-list
|
||||
@@ -64,7 +64,7 @@
|
||||
initial-y (if platform/ios? (- (:top insets)) 0)]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [scroll-y (reanimated/use-shared-value initial-y)
|
||||
(let [scroll-y (ra/use-val initial-y)
|
||||
opacity-animation (interpolate scroll-y
|
||||
[(* threshold 0.33) (* threshold 0.66)]
|
||||
[0 1])
|
||||
@@ -80,14 +80,14 @@
|
||||
{:active-opacity 1
|
||||
:style (style/button-container {:right 20})}
|
||||
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
|
||||
[reanimated/blur-view
|
||||
[ra/blur-view
|
||||
{:blurAmount 32
|
||||
:blurType :light
|
||||
:overlayColor (if platform/ios? colors/white-opa-70 :transparent)
|
||||
:style (style/blur-view opacity-animation)}
|
||||
[reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)}
|
||||
[ra/view {:style (style/header-comp translate-animation title-opacity-animation)}
|
||||
[header-comp]]]
|
||||
[reanimated/flat-list
|
||||
[ra/flat-list
|
||||
{:data [nil]
|
||||
:render-fn main-comp
|
||||
:key-fn str
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn apply-anim
|
||||
[dd-height val]
|
||||
(reanimated/animate-shared-value-with-delay dd-height
|
||||
val
|
||||
300
|
||||
:easing1
|
||||
0))
|
||||
(ra/animate-delay dd-height
|
||||
val
|
||||
0
|
||||
300
|
||||
:easing1))
|
||||
|
||||
(def sizes
|
||||
{:big {:icon-size 20
|
||||
@@ -141,7 +141,7 @@
|
||||
[:f>
|
||||
(fn []
|
||||
(let [open? (reagent/atom false)
|
||||
dd-height (reanimated/use-shared-value 0)]
|
||||
dd-height (ra/use-val 0)]
|
||||
[rn/view {:style {:flex-grow 1}}
|
||||
[dropdown-comp
|
||||
{:items items
|
||||
@@ -155,8 +155,8 @@
|
||||
:default-item default-item
|
||||
:open? open?
|
||||
:dd-height dd-height}]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:height dd-height}
|
||||
{:height dd-height})}
|
||||
[items-comp
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def header-height 56)
|
||||
@@ -162,7 +162,7 @@
|
||||
border-bottom false}}]
|
||||
(let [status-bar-height (get insets :top 0)
|
||||
height (+ header-height status-bar-height)]
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (header-wrapper-style {:height height
|
||||
:background background
|
||||
:border-bottom border-bottom})}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.masked-view :as masked-view]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def message-skeleton-height 54)
|
||||
@@ -30,12 +30,12 @@
|
||||
author-width (content-width :author)
|
||||
message-width (content-width :message)
|
||||
{window-width :width} (rn/use-window-dimensions)
|
||||
translate-x (reanimated/use-shared-value (- window-width))
|
||||
animated-gradient-style (reanimated/apply-animations-to-style
|
||||
translate-x (ra/use-val (- window-width))
|
||||
animated-gradient-style (ra/apply-animations-to-style
|
||||
{:transform [{:translateX translate-x}]}
|
||||
{:width window-width
|
||||
:height "100%"})]
|
||||
(reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false)
|
||||
(ra/animate-repeat translate-x window-width (- 1) false 1000 :linear)
|
||||
[masked-view/masked-view
|
||||
{:style {:height message-skeleton-height}
|
||||
:maskElement (reagent/as-element
|
||||
@@ -70,7 +70,7 @@
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:background-color color}}
|
||||
[reanimated/linear-gradient
|
||||
[ra/linear-gradient
|
||||
{:colors [color color loading-color color color]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 1 :y 0}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[utils.string :as utils]))
|
||||
|
||||
(def themes-landed
|
||||
@@ -176,20 +176,20 @@
|
||||
[{:keys [type style non-pressable? animate-landing? labels on-long-press] :as message}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [sv-color (reanimated/use-shared-value
|
||||
(let [sv-color (ra/use-val
|
||||
(get-color :bg (if animate-landing? :landed :default) type))]
|
||||
(when animate-landing?
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
(ra/animate-delay
|
||||
sv-color
|
||||
(get-color :bg :default type)
|
||||
1000
|
||||
0
|
||||
:linear
|
||||
1000))
|
||||
[reanimated/touchable-opacity
|
||||
:linear))
|
||||
[ra/touchable-opacity
|
||||
{:on-press #(when-not non-pressable?
|
||||
(reanimated/set-shared-value sv-color (get-color :bg :pressed type)))
|
||||
(ra/set-val sv-color (get-color :bg :pressed type)))
|
||||
:on-long-press on-long-press
|
||||
:style (reanimated/apply-animations-to-style
|
||||
:style (ra/apply-animations-to-style
|
||||
{:background-color sv-color}
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn toggle-background-color
|
||||
[background-color press-out? pass-through?]
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
background-color
|
||||
(cond
|
||||
press-out? "transparent"
|
||||
@@ -31,14 +31,14 @@
|
||||
on-press pass-through? icon-color-anim accessibility-label test-ID]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [icon-animated-style (reanimated/apply-animations-to-style
|
||||
(let [icon-animated-style (ra/apply-animations-to-style
|
||||
{:tint-color icon-color-anim}
|
||||
{:width 24
|
||||
:height 24
|
||||
:margin-left 33
|
||||
:margin-top 8})
|
||||
background-color (reanimated/use-shared-value "transparent")
|
||||
background-animated-style (reanimated/apply-animations-to-style
|
||||
background-color (ra/use-val "transparent")
|
||||
background-animated-style (ra/apply-animations-to-style
|
||||
{:background-color background-color}
|
||||
{:width 90
|
||||
:height 40
|
||||
@@ -49,7 +49,7 @@
|
||||
:on-press-in #(toggle-background-color background-color false pass-through?)
|
||||
:on-press-out #(toggle-background-color background-color true pass-through?)
|
||||
:accessibility-label accessibility-label}
|
||||
[reanimated/view {:style background-animated-style}
|
||||
[ra/view {:style background-animated-style}
|
||||
;; In android animations are not working for the animated components which are nested by
|
||||
;; hole-view,
|
||||
;; Interestingly this only happens when hole view and blur view are used together
|
||||
@@ -69,10 +69,10 @@
|
||||
|
||||
:else
|
||||
[{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])}
|
||||
[reanimated/image
|
||||
[ra/image
|
||||
{:style icon-animated-style
|
||||
:source (icons/icon-source (keyword (str icon 24)))}]]
|
||||
[reanimated/image
|
||||
[ra/image
|
||||
{:style icon-animated-style
|
||||
:source (icons/icon-source (keyword (str icon 24)))}])
|
||||
(when new-notifications?
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns quo2.components.navigation.floating-shell-button
|
||||
(:require [quo2.components.buttons.dynamic-button :as dynamic-button]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn dynamic-button-view
|
||||
[type dynamic-buttons style]
|
||||
@@ -28,12 +28,12 @@
|
||||
:margin-horizontal 12
|
||||
:pointer-events :box-none}
|
||||
style)
|
||||
animated-style (reanimated/apply-animations-to-style
|
||||
animated-style (ra/apply-animations-to-style
|
||||
(if opacity-anim
|
||||
{:opacity opacity-anim}
|
||||
{})
|
||||
original-style)]
|
||||
[reanimated/view {:style animated-style}
|
||||
[ra/view {:style animated-style}
|
||||
;; Left Section
|
||||
[rn/view {:style {:flex 1}}
|
||||
[dynamic-button-view :search dynamic-buttons
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.record-audio.record-audio.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.core :refer [use-effect]]
|
||||
[quo2.components.record-audio.record-audio.helpers :refer
|
||||
[animate-linear-with-delay
|
||||
@@ -14,14 +14,14 @@
|
||||
[recording? ready-to-delete? reviewing-audio?]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [opacity (reanimated/use-shared-value 0)
|
||||
translate-x (reanimated/use-shared-value 20)
|
||||
scale (reanimated/use-shared-value 1)
|
||||
connector-opacity (reanimated/use-shared-value 0)
|
||||
connector-width (reanimated/use-shared-value 24)
|
||||
connector-height (reanimated/use-shared-value 12)
|
||||
border-radius-first-half (reanimated/use-shared-value 8)
|
||||
border-radius-second-half (reanimated/use-shared-value 8)
|
||||
(let [opacity (ra/use-val 0)
|
||||
translate-x (ra/use-val 20)
|
||||
scale (ra/use-val 1)
|
||||
connector-opacity (ra/use-val 0)
|
||||
connector-width (ra/use-val 24)
|
||||
connector-height (ra/use-val 12)
|
||||
border-radius-first-half (ra/use-val 8)
|
||||
border-radius-second-half (ra/use-val 8)
|
||||
start-x-animation (fn []
|
||||
(animate-linear-with-delay translate-x 12 50 133.33)
|
||||
(animate-easing-with-delay connector-opacity 1 0 93.33)
|
||||
@@ -73,14 +73,14 @@
|
||||
(reset-x-animation)))
|
||||
[@ready-to-delete?])
|
||||
[:<>
|
||||
[reanimated/view {:style (style/delete-button-container opacity)}
|
||||
[reanimated/view
|
||||
[ra/view {:style (style/delete-button-container opacity)}
|
||||
[ra/view
|
||||
{:style (style/delete-button-connector connector-opacity
|
||||
connector-width
|
||||
connector-height
|
||||
border-radius-first-half
|
||||
border-radius-second-half)}]]
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/delete-button scale translate-x opacity)
|
||||
:pointer-events :none}
|
||||
[icons/icon :i/delete
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.record-audio.record-audio.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.core :refer [use-effect]]
|
||||
[quo2.components.record-audio.record-audio.helpers :refer
|
||||
[animate-linear-with-delay
|
||||
@@ -14,13 +14,13 @@
|
||||
[recording? ready-to-lock? locked?]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [translate-x-y (reanimated/use-shared-value 20)
|
||||
opacity (reanimated/use-shared-value 0)
|
||||
connector-opacity (reanimated/use-shared-value 0)
|
||||
width (reanimated/use-shared-value 24)
|
||||
height (reanimated/use-shared-value 12)
|
||||
border-radius-first-half (reanimated/use-shared-value 8)
|
||||
border-radius-second-half (reanimated/use-shared-value 8)
|
||||
(let [translate-x-y (ra/use-val 20)
|
||||
opacity (ra/use-val 0)
|
||||
connector-opacity (ra/use-val 0)
|
||||
width (ra/use-val 24)
|
||||
height (ra/use-val 12)
|
||||
border-radius-first-half (ra/use-val 8)
|
||||
border-radius-second-half (ra/use-val 8)
|
||||
start-x-y-animation (fn []
|
||||
(animate-linear-with-delay translate-x-y 8 50 116.66)
|
||||
(animate-easing-with-delay connector-opacity 1 0 80)
|
||||
@@ -70,14 +70,14 @@
|
||||
(reset-x-y-animation)))
|
||||
[@locked?])
|
||||
[:<>
|
||||
[reanimated/view {:style (style/lock-button-container opacity)}
|
||||
[reanimated/view
|
||||
[ra/view {:style (style/lock-button-container opacity)}
|
||||
[ra/view
|
||||
{:style (style/lock-button-connector connector-opacity
|
||||
width
|
||||
height
|
||||
border-radius-first-half
|
||||
border-radius-second-half)}]]
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/lock-button translate-x-y opacity)
|
||||
:pointer-events :none}
|
||||
[icons/icon (if @ready-to-lock? :i/locked :i/unlocked)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[quo2.components.record-audio.record-audio.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn :refer [use-effect]]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.record-audio.record-audio.helpers :refer [set-value]]))
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[recording? reviewing-audio?]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [opacity (reanimated/use-shared-value 1)
|
||||
(let [opacity (ra/use-val 1)
|
||||
show-animation #(set-value opacity 1)
|
||||
hide-animation #(set-value opacity 0)]
|
||||
(use-effect (fn []
|
||||
@@ -19,7 +19,7 @@
|
||||
(hide-animation)
|
||||
(show-animation)))
|
||||
[@recording? @reviewing-audio?])
|
||||
[reanimated/view {:style (style/record-button-container opacity)}
|
||||
[ra/view {:style (style/record-button-container opacity)}
|
||||
[button/button
|
||||
{:type :outline
|
||||
:size 32
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[quo2.components.record-audio.record-audio.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn :refer [use-effect]]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.audio-toolkit :as audio]
|
||||
[taoensso.timbre :as log]
|
||||
[cljs-bean.core :as bean]
|
||||
@@ -37,7 +37,7 @@
|
||||
(fn [props]
|
||||
(let [{:keys [scale opacity color]} (bean/bean props)]
|
||||
(reagent/as-element
|
||||
[reanimated/view {:style (style/animated-circle scale opacity color)}]))))))
|
||||
[ra/view {:style (style/animated-circle scale opacity color)}]))))))
|
||||
|
||||
(defn record-button-big
|
||||
[recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating?
|
||||
@@ -45,29 +45,29 @@
|
||||
clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [scale (reanimated/use-shared-value 1)
|
||||
opacity (reanimated/use-shared-value 0)
|
||||
(let [scale (ra/use-val 1)
|
||||
opacity (ra/use-val 0)
|
||||
opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default)
|
||||
animations (map
|
||||
(fn [index]
|
||||
(let [ring-scale (ring-scale scale (* scale-padding index))]
|
||||
{:scale ring-scale
|
||||
:opacity (reanimated/interpolate ring-scale
|
||||
[1 scale-to-each]
|
||||
[opacity-from 0])}))
|
||||
:opacity (ra/interpolate ring-scale
|
||||
[1 scale-to-each]
|
||||
[opacity-from 0])}))
|
||||
(range 0 5))
|
||||
rings-color (cond
|
||||
@ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque
|
||||
colors/neutral-80)
|
||||
@ready-to-delete? colors/danger-50
|
||||
:else colors/primary-50)
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
translate-x (reanimated/use-shared-value 0)
|
||||
translate-y (ra/use-val 0)
|
||||
translate-x (ra/use-val 0)
|
||||
button-color colors/primary-50
|
||||
icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white)
|
||||
icon-opacity (reanimated/use-shared-value 1)
|
||||
red-overlay-opacity (reanimated/use-shared-value 0)
|
||||
gray-overlay-opacity (reanimated/use-shared-value 0)
|
||||
icon-opacity (ra/use-val 1)
|
||||
red-overlay-opacity (ra/use-val 0)
|
||||
gray-overlay-opacity (ra/use-val 0)
|
||||
complete-animation (fn []
|
||||
(cond
|
||||
(and @ready-to-lock? (not @record-button-is-animating?))
|
||||
@@ -114,7 +114,7 @@
|
||||
signal-anim-duration)))
|
||||
stop-animation (fn []
|
||||
(set-value opacity 0)
|
||||
(reanimated/cancel-animation scale)
|
||||
(ra/cancel-animation scale)
|
||||
(set-value scale 1)
|
||||
(when @clear-timeout (js/clearTimeout @clear-timeout)))
|
||||
start-y-animation (fn []
|
||||
@@ -190,7 +190,7 @@
|
||||
(start-x-animation)
|
||||
(reset-x-animation)))
|
||||
[@ready-to-delete?])
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/record-button-big-container translate-x translate-y opacity)
|
||||
:pointer-events :none}
|
||||
[:<>
|
||||
@@ -203,9 +203,9 @@
|
||||
:color rings-color}])
|
||||
animations)]
|
||||
[rn/view {:style (style/record-button-big-body button-color)}
|
||||
[reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
|
||||
[reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
|
||||
[reanimated/view {:style (style/record-button-big-icon-container icon-opacity)}
|
||||
[ra/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
|
||||
[ra/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
|
||||
[ra/view {:style (style/record-button-big-icon-container icon-opacity)}
|
||||
(if @locked?
|
||||
[rn/view {:style style/stop-icon}]
|
||||
[icons/icon :i/audio {:color icon-color}])]]]))])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.record-audio.record-audio.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.core :refer [use-effect]]
|
||||
[quo2.components.record-audio.record-audio.helpers :refer
|
||||
[animate-linear
|
||||
@@ -14,13 +14,13 @@
|
||||
[recording? ready-to-send? reviewing-audio?]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value 20)
|
||||
connector-opacity (reanimated/use-shared-value 0)
|
||||
width (reanimated/use-shared-value 12)
|
||||
height (reanimated/use-shared-value 24)
|
||||
border-radius-first-half (reanimated/use-shared-value 16)
|
||||
border-radius-second-half (reanimated/use-shared-value 8)
|
||||
(let [opacity (ra/use-val 0)
|
||||
translate-y (ra/use-val 20)
|
||||
connector-opacity (ra/use-val 0)
|
||||
width (ra/use-val 12)
|
||||
height (ra/use-val 24)
|
||||
border-radius-first-half (ra/use-val 16)
|
||||
border-radius-second-half (ra/use-val 8)
|
||||
start-y-animation (fn []
|
||||
(animate-linear-with-delay translate-y 12 50 133.33)
|
||||
(animate-easing-with-delay connector-opacity 1 0 93.33)
|
||||
@@ -74,14 +74,14 @@
|
||||
@recording? (reset-y-animation)))
|
||||
[@ready-to-send?])
|
||||
[:<>
|
||||
[reanimated/view {:style (style/send-button-container opacity)}
|
||||
[reanimated/view
|
||||
[ra/view {:style (style/send-button-container opacity)}
|
||||
[ra/view
|
||||
{:style (style/send-button-connector connector-opacity
|
||||
width
|
||||
height
|
||||
border-radius-first-half
|
||||
border-radius-second-half)}]]
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/send-button translate-y opacity)
|
||||
:pointer-events :none}
|
||||
[icons/icon :i/arrow-up
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(ns quo2.components.record-audio.record-audio.helpers
|
||||
(:require [react-native.reanimated :as reanimated]))
|
||||
(:require [react-native.reanimated :as ra]))
|
||||
|
||||
(defn animate-linear
|
||||
[shared-value value duration]
|
||||
(reanimated/animate-shared-value-with-timing
|
||||
(ra/animate
|
||||
shared-value
|
||||
value
|
||||
duration
|
||||
@@ -11,26 +11,26 @@
|
||||
|
||||
(defn animate-linear-with-delay
|
||||
[shared-value value duration delay]
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
(ra/animate-delay
|
||||
shared-value
|
||||
value
|
||||
delay
|
||||
duration
|
||||
:linear
|
||||
delay))
|
||||
:linear))
|
||||
|
||||
(defn animate-linear-with-delay-loop
|
||||
[shared-value value duration delay]
|
||||
(reanimated/animate-shared-value-with-delay-repeat
|
||||
(ra/animate-delay-repeat
|
||||
shared-value
|
||||
value
|
||||
duration
|
||||
:linear
|
||||
delay
|
||||
-1))
|
||||
-1
|
||||
duration
|
||||
:linear))
|
||||
|
||||
(defn animate-easing
|
||||
[shared-value value duration]
|
||||
(reanimated/animate-shared-value-with-timing
|
||||
(ra/animate
|
||||
shared-value
|
||||
value
|
||||
duration
|
||||
@@ -38,13 +38,13 @@
|
||||
|
||||
(defn animate-easing-with-delay
|
||||
[shared-value value duration delay]
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
(ra/animate-delay
|
||||
shared-value
|
||||
value
|
||||
delay
|
||||
duration
|
||||
:easing1
|
||||
delay))
|
||||
:easing1))
|
||||
|
||||
(defn set-value
|
||||
[shared-value value]
|
||||
(reanimated/set-shared-value shared-value value))
|
||||
(ra/set-val shared-value value))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(ns quo2.components.record-audio.record-audio.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn animated-circle
|
||||
[scale opacity color]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:scale scale}]
|
||||
:opacity opacity}
|
||||
{:width 56
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
(defn record-button-big-container
|
||||
[translate-x translate-y opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}
|
||||
{:translateX translate-x}]
|
||||
:opacity opacity}
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
(defn record-button-big-red-overlay
|
||||
[red-overlay-opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity red-overlay-opacity}
|
||||
{:position :absolute
|
||||
:top 0
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
(defn record-button-big-gray-overlay
|
||||
[gray-overlay-opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity gray-overlay-opacity}
|
||||
{:position :absolute
|
||||
:top 0
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
(defn record-button-big-icon-container
|
||||
[icon-opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity icon-opacity}
|
||||
{}))
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
(defn send-button-container
|
||||
[opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity}
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
@@ -90,7 +90,7 @@
|
||||
|
||||
(defn send-button-connector
|
||||
[opacity width height border-radius-first-half border-radius-second-half]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity
|
||||
:width width
|
||||
:height height
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
(defn send-button
|
||||
[translate-y opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]
|
||||
:opacity opacity}
|
||||
{:justify-content :center
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
(defn lock-button-container
|
||||
[opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity}
|
||||
{:transform [{:rotate "45deg"}]
|
||||
:justify-content :center
|
||||
@@ -138,7 +138,7 @@
|
||||
|
||||
(defn lock-button-connector
|
||||
[opacity width height border-radius-first-half border-radius-second-half]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity
|
||||
:width width
|
||||
:height height
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
(defn lock-button
|
||||
[translate-x-y opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateX translate-x-y}
|
||||
{:translateY translate-x-y}]
|
||||
:opacity opacity}
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
(defn delete-button-container
|
||||
[opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity}
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
(defn delete-button-connector
|
||||
[opacity width height border-radius-first-half border-radius-second-half]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity
|
||||
:width width
|
||||
:height height
|
||||
@@ -200,7 +200,7 @@
|
||||
|
||||
(defn delete-button
|
||||
[scale translate-x opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateX translate-x}
|
||||
{:scale scale}]
|
||||
:opacity opacity}
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
(defn record-button-container
|
||||
[opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity opacity}
|
||||
{:margin-bottom 32
|
||||
:margin-right 32}))
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
[react-native.flat-list :as rn-flat-list]
|
||||
[utils.collection]))
|
||||
|
||||
;; Animations
|
||||
(def slide-in-up-animation SlideInUp)
|
||||
(def slide-out-up-animation SlideOutUp)
|
||||
(def linear-transition LinearTransition)
|
||||
;;; Constants
|
||||
(def ^:const default-duration 300)
|
||||
|
||||
;; Animated Components
|
||||
;;; Worklets
|
||||
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
|
||||
|
||||
;;; Animated Components
|
||||
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View reanimated)))
|
||||
@@ -34,18 +35,22 @@
|
||||
(defn flat-list
|
||||
[props]
|
||||
[reanimated-flat-list (rn-flat-list/base-list-props props)])
|
||||
|
||||
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
|
||||
|
||||
(def linear-gradient (create-animated-component LinearGradient))
|
||||
(def fast-image (create-animated-component FastImage))
|
||||
(def blur-view (create-animated-component (.-BlurView blur)))
|
||||
|
||||
;; Hooks
|
||||
(def use-shared-value useSharedValue)
|
||||
(def use-animated-style useAnimatedStyle)
|
||||
;;; Easings
|
||||
(def in-out (.-inOut ^js Easing))
|
||||
(def bezier (.-bezier ^js Easing))
|
||||
(def easings
|
||||
{:default (in-out (.-quad ^js Easing))
|
||||
:linear (bezier 0 0 1 1)
|
||||
:easing1 (bezier 0.25 0.1 0.25 1)
|
||||
:easing2 (bezier 0 0.3 0.6 0.9)
|
||||
:easing3 (bezier 0.3 0.3 0.3 0.9)})
|
||||
|
||||
;; Animations
|
||||
;;; Animations
|
||||
(def with-timing withTiming)
|
||||
(def with-delay withDelay)
|
||||
(def with-spring withSpring)
|
||||
@@ -53,112 +58,103 @@
|
||||
(def key-frame Keyframe)
|
||||
(def with-repeat withRepeat)
|
||||
(def cancel-animation cancelAnimation)
|
||||
(defn with-repeat-timing
|
||||
[val reps reverse? duration easing]
|
||||
(with-repeat
|
||||
(with-timing val
|
||||
(clj->js {:duration duration
|
||||
:easing (get easings easing)}))
|
||||
reps
|
||||
reverse?))
|
||||
|
||||
;; Easings
|
||||
(def bezier (.-bezier ^js Easing))
|
||||
|
||||
(def in-out
|
||||
(.-inOut ^js Easing))
|
||||
|
||||
(def easings
|
||||
{:linear (bezier 0 0 1 1)
|
||||
:easing1 (bezier 0.25 0.1 0.25 1)
|
||||
:easing2 (bezier 0 0.3 0.6 0.9)
|
||||
:easing3 (bezier 0.3 0.3 0.3 0.9)})
|
||||
|
||||
;; Helper functions
|
||||
(defn get-shared-value
|
||||
;;; Hooks and Helpers
|
||||
(def use-val useSharedValue)
|
||||
(defn get-val
|
||||
[anim]
|
||||
(when anim
|
||||
(.-value anim)))
|
||||
|
||||
(defn set-shared-value
|
||||
(defn set-val
|
||||
[anim val]
|
||||
(when (and anim (some? val))
|
||||
(set! (.-value anim) val)))
|
||||
|
||||
;; Worklets
|
||||
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
|
||||
;;; Executing animation functions
|
||||
(defn animate
|
||||
([animation value]
|
||||
(animate animation value default-duration :default))
|
||||
([animation value duration]
|
||||
(animate animation value duration :default))
|
||||
([animation value duration easing]
|
||||
(set-val animation
|
||||
(with-timing value
|
||||
(clj->js {:duration duration
|
||||
:easing (get easings easing)})))))
|
||||
|
||||
(defn animate-spring
|
||||
[animation val {:keys [damping mass stiffness]}]
|
||||
(set-val animation
|
||||
(with-spring val
|
||||
(clj->js {:damping damping
|
||||
:mass mass
|
||||
:stiffness stiffness}))))
|
||||
|
||||
(defn animate-decay
|
||||
([animation velocity]
|
||||
(animate-decay animation velocity []))
|
||||
([animation velocity clamp]
|
||||
(set-val animation
|
||||
(with-decay (clj->js {:velocity velocity
|
||||
:clamp clamp})))))
|
||||
|
||||
(defn animate-delay
|
||||
([animation val delay]
|
||||
(animate-delay animation val delay default-duration :default))
|
||||
([animation val delay duration]
|
||||
(animate-delay animation val delay duration :default))
|
||||
([animation val delay duration easing]
|
||||
(set-val animation
|
||||
(with-delay delay
|
||||
(with-timing val
|
||||
(clj->js {:duration duration
|
||||
:easing (get easings easing)}))))))
|
||||
|
||||
(defn animate-repeat
|
||||
([animation val reps]
|
||||
(animate-repeat animation val reps false default-duration :default))
|
||||
([animation val reps reverse?]
|
||||
(animate-repeat animation val reps reverse? default-duration :default))
|
||||
([animation val reps reverse? duration]
|
||||
(animate-repeat animation val reps reverse? duration :default))
|
||||
([animation val reps reverse? duration easing]
|
||||
(set-val animation (with-repeat-timing val reps reverse? duration easing))))
|
||||
|
||||
(defn animate-delay-repeat
|
||||
([animation val duration easing delay reps]
|
||||
(animate-delay-repeat animation val duration easing delay reps false))
|
||||
([animation val duration easing delay reps reverse?]
|
||||
(set-val animation (with-delay delay (with-repeat-timing val reps reverse? duration easing)))))
|
||||
|
||||
(defn interpolate
|
||||
([shared-value input-range output-range]
|
||||
(interpolate shared-value input-range output-range nil))
|
||||
([shared-value input-range output-range extrapolation]
|
||||
([val input-range output-range]
|
||||
(interpolate val input-range output-range nil))
|
||||
([val input-range output-range extrapolation]
|
||||
(.interpolateValue ^js worklet-factory
|
||||
shared-value
|
||||
val
|
||||
(clj->js input-range)
|
||||
(clj->js output-range)
|
||||
(clj->js extrapolation))))
|
||||
|
||||
;;;; Component Animations
|
||||
|
||||
;;; Styling
|
||||
(def use-animated-style useAnimatedStyle)
|
||||
(defn apply-animations-to-style
|
||||
[animations style]
|
||||
(use-animated-style
|
||||
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style))))
|
||||
|
||||
;; Animators
|
||||
(defn animate-shared-value-with-timing
|
||||
[anim val duration easing]
|
||||
(set-shared-value anim
|
||||
(with-timing val
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing)))))
|
||||
|
||||
(defn animate-shared-value-with-delay
|
||||
[anim val duration easing delay]
|
||||
(set-shared-value anim
|
||||
(with-delay delay
|
||||
(with-timing val
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing))))))
|
||||
|
||||
(defn animate-shared-value-with-delay-default-easing
|
||||
[anim val duration delay]
|
||||
(set-shared-value anim
|
||||
(with-delay delay
|
||||
(with-timing val
|
||||
(js-obj "duration" duration
|
||||
"easing" (in-out (.-quad ^js Easing)))))))
|
||||
|
||||
(defn animate-shared-value-with-repeat
|
||||
[anim val duration easing number-of-repetitions reverse?]
|
||||
(set-shared-value anim
|
||||
(with-repeat (with-timing val
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing)))
|
||||
number-of-repetitions
|
||||
reverse?)))
|
||||
|
||||
(defn animate-shared-value-with-delay-repeat
|
||||
([anim val duration easing delay number-of-repetitions]
|
||||
(animate-shared-value-with-delay-repeat anim val duration easing delay number-of-repetitions false))
|
||||
([anim val duration easing delay number-of-repetitions reverse?]
|
||||
(set-shared-value anim
|
||||
(with-delay delay
|
||||
(with-repeat
|
||||
(with-timing val
|
||||
#js
|
||||
{:duration duration
|
||||
:easing (get easings easing)})
|
||||
number-of-repetitions
|
||||
reverse?)))))
|
||||
|
||||
(defn animate-shared-value-with-spring
|
||||
[anim val {:keys [mass stiffness damping]}]
|
||||
(set-shared-value anim
|
||||
(with-spring val
|
||||
(js-obj "mass" mass
|
||||
"damping" damping
|
||||
"stiffness" stiffness))))
|
||||
|
||||
(defn animate-shared-value-with-decay
|
||||
[anim velocity clamp]
|
||||
(set-shared-value anim
|
||||
(with-decay (clj->js {:velocity velocity
|
||||
:clamp clamp}))))
|
||||
|
||||
(defn with-timing-duration
|
||||
[val duration]
|
||||
(with-timing val
|
||||
(clj->js {:duration duration
|
||||
:easing (in-out (.-quad ^js Easing))})))
|
||||
;;; Built-in Animations
|
||||
(def slide-in-up-animation SlideInUp)
|
||||
(def slide-out-up-animation SlideOutUp)
|
||||
(def linear-transition LinearTransition)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im.ui2.screens.chat.pin-limit-popover.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
(fn []
|
||||
(let [width (rf/sub [:dimensions/window-width])
|
||||
show-pin-limit-modal? (rf/sub [:chats/pin-modal chat-id])
|
||||
opacity-animation (reanimated/use-shared-value 0)
|
||||
z-index-animation (reanimated/use-shared-value -1)]
|
||||
opacity-animation (ra/use-val 0)
|
||||
z-index-animation (ra/use-val -1)]
|
||||
(react/effect!
|
||||
#(do
|
||||
(reanimated/set-shared-value opacity-animation
|
||||
(reanimated/with-timing (if show-pin-limit-modal? 1 0)))
|
||||
(reanimated/set-shared-value z-index-animation
|
||||
(reanimated/with-timing (if show-pin-limit-modal? 10 -1)))))
|
||||
(ra/set-val opacity-animation
|
||||
(ra/with-timing (if show-pin-limit-modal? 1 0)))
|
||||
(ra/set-val z-index-animation
|
||||
(ra/with-timing (if show-pin-limit-modal? 10 -1)))))
|
||||
(when show-pin-limit-modal?
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:opacity opacity-animation
|
||||
:z-index z-index-animation}
|
||||
(style/pin-popover width))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
(defn with-animation
|
||||
[value & [options callback]]
|
||||
(reanimated/with-spring
|
||||
(ra/with-spring
|
||||
value
|
||||
(clj->js (merge {:mass 2
|
||||
:stiffness 500
|
||||
@@ -45,12 +45,12 @@
|
||||
max-pan-down (if @expanded?
|
||||
bg-height-expanded
|
||||
bg-height)]
|
||||
(reanimated/set-shared-value pan-y
|
||||
(max
|
||||
(min
|
||||
(.-translationY evt)
|
||||
max-pan-down)
|
||||
max-pan-up))))))
|
||||
(ra/set-val pan-y
|
||||
(max
|
||||
(min
|
||||
(.-translationY evt)
|
||||
max-pan-down)
|
||||
max-pan-up))))))
|
||||
(gesture/on-end
|
||||
(fn [_]
|
||||
(reset! gesture-running? false)
|
||||
@@ -127,8 +127,8 @@
|
||||
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
||||
bg-height-expanded (- window-height (:top insets))
|
||||
bg-height (max (min @content-height bg-height-expanded) 109)
|
||||
bottom-sheet-dy (reanimated/use-shared-value 0)
|
||||
pan-y (reanimated/use-shared-value 0)
|
||||
bottom-sheet-dy (ra/use-val 0)
|
||||
pan-y (ra/use-val 0)
|
||||
translate-y (.useTranslateY ^js bottom-sheet-js window-height bottom-sheet-dy pan-y)
|
||||
bg-opacity
|
||||
(.useBackgroundOpacity ^js bottom-sheet-js translate-y bg-height window-height)
|
||||
@@ -136,11 +136,11 @@
|
||||
(let [height (oget evt "nativeEvent" "layout" "height")]
|
||||
(reset! content-height height)))
|
||||
on-expanded (fn []
|
||||
(reanimated/set-shared-value bottom-sheet-dy bg-height-expanded)
|
||||
(reanimated/set-shared-value pan-y 0))
|
||||
(ra/set-val bottom-sheet-dy bg-height-expanded)
|
||||
(ra/set-val pan-y 0))
|
||||
on-collapsed (fn []
|
||||
(reanimated/set-shared-value bottom-sheet-dy bg-height)
|
||||
(reanimated/set-shared-value pan-y 0))
|
||||
(ra/set-val bottom-sheet-dy bg-height)
|
||||
(ra/set-val pan-y 0))
|
||||
bottom-sheet-gesture (get-bottom-sheet-gesture
|
||||
pan-y
|
||||
translate-y
|
||||
@@ -185,38 +185,38 @@
|
||||
@show-bottom-sheet?
|
||||
(if @expanded?
|
||||
(do
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
bottom-sheet-dy
|
||||
(with-animation (+ bg-height-expanded (.-value pan-y))))
|
||||
;; Workaround for
|
||||
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
|
||||
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
|
||||
;; withTiming/withSpring callback not working
|
||||
;; on-expanded should be called as a callback of
|
||||
;; with-animation instead, once this issue has been resolved
|
||||
(timer/set-timeout on-expanded animation-delay))
|
||||
(do
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
bottom-sheet-dy
|
||||
(with-animation (+ bg-height (.-value pan-y))))
|
||||
;; Workaround for
|
||||
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
|
||||
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
|
||||
;; withTiming/withSpring callback not working
|
||||
;; on-collapsed should be called as a callback of
|
||||
;; with-animation instead, once this issue has been resolved
|
||||
(timer/set-timeout on-collapsed animation-delay)))
|
||||
|
||||
(= @show-bottom-sheet? false)
|
||||
(reanimated/set-shared-value bottom-sheet-dy (with-animation 0)))))
|
||||
(ra/set-val bottom-sheet-dy (with-animation 0)))))
|
||||
[@show-bottom-sheet? @expanded? @gesture-running?])
|
||||
|
||||
[:<>
|
||||
[rn/touchable-without-feedback {:on-press (when backdrop-dismiss? close-bottom-sheet)}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:opacity bg-opacity}
|
||||
styles/backdrop)}]]
|
||||
(cond->> [reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
(cond->> [ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
{:width window-width
|
||||
:height window-height})}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im2.common.scroll-page.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn image-slider
|
||||
[size]
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
(defn blur-slider
|
||||
[animation height]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateY animation}]}
|
||||
{:z-index 5
|
||||
:position :absolute
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
(defn sticky-header-title
|
||||
[animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:opacity animation}
|
||||
{:position :absolute
|
||||
:flex-direction :row
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
(defn display-picture-container
|
||||
[animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:scale animation}]}
|
||||
{:border-radius 50
|
||||
:border-width 1
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.scroll-page.style :as style]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn icon-color
|
||||
[]
|
||||
@@ -38,23 +38,23 @@
|
||||
navigate-back?]
|
||||
(let [input-range (if platform/ios? [-47 10] [0 10])
|
||||
output-range (if platform/ios? [-208 0] [-208 -45])
|
||||
y (reanimated/use-shared-value scroll-height)
|
||||
translate-animation (reanimated/interpolate y
|
||||
input-range
|
||||
output-range
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})
|
||||
opacity-animation (reanimated/use-shared-value 0)
|
||||
y (ra/use-val scroll-height)
|
||||
translate-animation (ra/interpolate y
|
||||
input-range
|
||||
output-range
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})
|
||||
opacity-animation (ra/use-val 0)
|
||||
threshold (if platform/ios? 30 170)]
|
||||
(rn/use-effect
|
||||
#(do
|
||||
(reanimated/set-shared-value y scroll-height)
|
||||
(reanimated/set-shared-value opacity-animation
|
||||
(reanimated/with-timing (if (>= scroll-height threshold) 1 0)
|
||||
(clj->js {:duration 300}))))
|
||||
(ra/set-val y scroll-height)
|
||||
(ra/set-val opacity-animation
|
||||
(ra/with-timing (if (>= scroll-height threshold) 1 0)
|
||||
(clj->js {:duration 300}))))
|
||||
[scroll-height])
|
||||
[:<>
|
||||
[reanimated/blur-view
|
||||
[ra/blur-view
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
@@ -66,7 +66,7 @@
|
||||
:left 0
|
||||
:right 0}}
|
||||
(when logo
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/sticky-header-title opacity-animation)}
|
||||
[rn/image
|
||||
{:source logo
|
||||
@@ -101,17 +101,17 @@
|
||||
(defn display-picture
|
||||
[scroll-height cover]
|
||||
(let [input-range (if platform/ios? [-67 10] [0 150])
|
||||
y (reanimated/use-shared-value scroll-height)
|
||||
animation (reanimated/interpolate y
|
||||
input-range
|
||||
[1.2 0.5]
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})]
|
||||
y (ra/use-val scroll-height)
|
||||
animation (ra/interpolate y
|
||||
input-range
|
||||
[1.2 0.5]
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})]
|
||||
(rn/use-effect #(do
|
||||
(reanimated/set-shared-value y scroll-height)
|
||||
(ra/set-val y scroll-height)
|
||||
js/undefined)
|
||||
[scroll-height])
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/display-picture-container animation)}
|
||||
[rn/image
|
||||
{:source cover
|
||||
|
||||
@@ -2,26 +2,26 @@
|
||||
(:require [quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.utils.utils :as utils.utils]
|
||||
[status-im2.common.toasts.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
;; (def ^:private slide-out-up-animation
|
||||
;; (-> ^js reanimated/slide-out-up-animation
|
||||
;; (-> ^js ra/slide-out-up-animation
|
||||
;; .springify
|
||||
;; (.damping 20)
|
||||
;; (.stiffness 300)))
|
||||
|
||||
;; (def ^:private slide-in-up-animation
|
||||
;; (-> ^js reanimated/slide-in-up-animation
|
||||
;; (-> ^js ra/slide-in-up-animation
|
||||
;; .springify
|
||||
;; (.damping 20)
|
||||
;; (.stiffness 300)))
|
||||
|
||||
;; (def ^:private linear-transition
|
||||
;; (-> ^js reanimated/linear-transition
|
||||
;; (-> ^js ra/linear-transition
|
||||
;; .springify
|
||||
;; (.damping 20)
|
||||
;; (.stiffness 300)))
|
||||
@@ -44,7 +44,7 @@
|
||||
on-dismissed #((or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) id)
|
||||
create-timer (fn []
|
||||
(reset! timer (utils.utils/set-timeout close! duration)))
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
translate-y (ra/use-val 0)
|
||||
pan
|
||||
(->
|
||||
(gesture/gesture-pan)
|
||||
@@ -56,38 +56,38 @@
|
||||
(cond
|
||||
;; reset translate y on pan down
|
||||
(> evt-translation-y 100)
|
||||
(reanimated/animate-shared-value-with-spring translate-y
|
||||
0
|
||||
{:mass 1
|
||||
:damping 20
|
||||
:stiffness 300})
|
||||
(ra/animate-spring translate-y
|
||||
0
|
||||
{:mass 1
|
||||
:damping 20
|
||||
:stiffness 300})
|
||||
;; dismiss on pan up
|
||||
(< evt-translation-y -30)
|
||||
(do (reanimated/animate-shared-value-with-spring
|
||||
(do (ra/animate-spring
|
||||
translate-y
|
||||
-500
|
||||
{:mass 1 :damping 20 :stiffness 300})
|
||||
(reset! dismissed-locally? true)
|
||||
(close!))
|
||||
:else
|
||||
(reanimated/set-shared-value translate-y
|
||||
evt-translation-y)))))
|
||||
(ra/set-val translate-y
|
||||
evt-translation-y)))))
|
||||
(gesture/on-end (fn [_]
|
||||
(when-not @dismissed-locally?
|
||||
(reanimated/set-shared-value translate-y 0)
|
||||
(ra/set-val translate-y 0)
|
||||
(create-timer)))))]
|
||||
;; create auto dismiss timer, clear timer when unmount or duration changed
|
||||
(rn/use-effect (fn [] (create-timer) clear-timer) [duration])
|
||||
(rn/use-unmount on-dismissed)
|
||||
[gesture/gesture-detector {:gesture pan}
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{;; TODO: this will eanble layout animation at runtime and causing flicker on android
|
||||
;; we need to resolve this and re-enable layout animation
|
||||
;; issue at https://github.com/status-im/status-mobile/issues/14752
|
||||
;; :entering slide-in-up-animation
|
||||
;; :exiting slide-out-up-animation
|
||||
;; :layout reanimated/linear-transition
|
||||
:style (reanimated/apply-animations-to-style
|
||||
;; :layout ra/linear-transition
|
||||
:style (ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
style/each-toast-container)}
|
||||
[toast id]]]))])))
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
(:require
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im2.contexts.chat.lightbox.style :as style]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.lightbox.common :as common]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def small-image-size 40)
|
||||
|
||||
@@ -25,10 +24,10 @@
|
||||
[:f>
|
||||
(fn []
|
||||
(let [size (if (= @scroll-index index) focused-image-size small-image-size)
|
||||
size-value (common/use-val size)
|
||||
size-value (ra/use-val size)
|
||||
{:keys [scroll-index-lock? small-list-ref
|
||||
flat-list-ref]} atoms]
|
||||
(common/set-val-timing size-value size)
|
||||
(ra/animate size-value size)
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press (fn []
|
||||
@@ -44,11 +43,11 @@
|
||||
#js {:animated true :index index}))
|
||||
(if platform/ios? 50 150))
|
||||
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)]))}
|
||||
[reanimated/fast-image
|
||||
[ra/fast-image
|
||||
{:source {:uri (:image (:content item))}
|
||||
:style (reanimated/apply-animations-to-style {:width size-value
|
||||
:height size-value}
|
||||
{:border-radius 10})}]]))])
|
||||
:style (ra/apply-animations-to-style {:width size-value
|
||||
:height size-value}
|
||||
{:border-radius 10})}]]))])
|
||||
|
||||
(defn bottom-view
|
||||
[messages index scroll-index insets animations item-width atoms]
|
||||
@@ -56,7 +55,7 @@
|
||||
(fn []
|
||||
(let [text (get-in (first messages) [:content :text])
|
||||
padding-horizontal (- (/ item-width 2) (/ focused-image-size 2))]
|
||||
[reanimated/linear-gradient
|
||||
[ra/linear-gradient
|
||||
{:colors [:black :transparent]
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
(ns status-im2.contexts.chat.lightbox.common
|
||||
(:require [react-native.reanimated :as reanimated]))
|
||||
|
||||
(def top-view-height 56)
|
||||
|
||||
;; TODO: Abstract Reanimated methods in a better way, issue:
|
||||
;; https://github.com/status-im/status-mobile/issues/15176
|
||||
(defn set-val-timing
|
||||
[animation value]
|
||||
(reanimated/set-shared-value animation (reanimated/with-timing value)))
|
||||
|
||||
(defn use-val
|
||||
[value]
|
||||
(reanimated/use-shared-value value))
|
||||
@@ -1,8 +1,7 @@
|
||||
(ns status-im2.contexts.chat.lightbox.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.lightbox.common :as common]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
;;;; MAIN-VIEW
|
||||
(def container-view
|
||||
@@ -13,7 +12,7 @@
|
||||
[top-inset {:keys [opacity rotate top-view-y top-view-x top-view-width top-view-bg top-layout]}
|
||||
window-width
|
||||
bg-color]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
(if platform/ios?
|
||||
{:transform [{:translateY top-layout}
|
||||
{:rotate rotate}
|
||||
@@ -27,7 +26,8 @@
|
||||
{:position :absolute
|
||||
:padding-horizontal 20
|
||||
:top (if platform/ios? top-inset 0)
|
||||
:height common/top-view-height
|
||||
;; height defined in top_view.cljs, but can't import due to circular dependency
|
||||
:height 56
|
||||
:z-index 4
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
@@ -49,7 +49,7 @@
|
||||
;;;; BOTTOM-VIEW
|
||||
(defn gradient-container
|
||||
[insets {:keys [opacity bottom-layout]}]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateY bottom-layout}]
|
||||
:opacity opacity}
|
||||
{:position :absolute
|
||||
|
||||
@@ -5,38 +5,39 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.orientation :as orientation]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.lightbox.common :as common]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im2.contexts.chat.lightbox.style :as style]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:const top-view-height 56)
|
||||
|
||||
(defn animate-rotation
|
||||
[result screen-width screen-height insets-atom
|
||||
{:keys [rotate top-view-y top-view-x top-view-width top-view-bg]}]
|
||||
(let [top-x (+ (/ common/top-view-height 2) (:top insets-atom))]
|
||||
(let [top-x (+ (/ top-view-height 2) (:top insets-atom))]
|
||||
(cond
|
||||
(= result orientation/landscape-left)
|
||||
(do
|
||||
(common/set-val-timing rotate "90deg")
|
||||
(common/set-val-timing top-view-y 60)
|
||||
(common/set-val-timing top-view-x (- (/ screen-height 2) top-x))
|
||||
(common/set-val-timing top-view-width screen-height)
|
||||
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
|
||||
(ra/animate rotate "90deg")
|
||||
(ra/animate top-view-y 60)
|
||||
(ra/animate top-view-x (- (/ screen-height 2) top-x))
|
||||
(ra/animate top-view-width screen-height)
|
||||
(ra/animate top-view-bg colors/neutral-100-opa-70))
|
||||
(= result orientation/landscape-right)
|
||||
(do
|
||||
(common/set-val-timing rotate "-90deg")
|
||||
(common/set-val-timing top-view-y (- (- screen-width) 4))
|
||||
(common/set-val-timing top-view-x (+ (/ screen-height -2) top-x))
|
||||
(common/set-val-timing top-view-width screen-height)
|
||||
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
|
||||
(ra/animate rotate "-90deg")
|
||||
(ra/animate top-view-y (- (- screen-width) 4))
|
||||
(ra/animate top-view-x (+ (/ screen-height -2) top-x))
|
||||
(ra/animate top-view-width screen-height)
|
||||
(ra/animate top-view-bg colors/neutral-100-opa-70))
|
||||
(= result orientation/portrait)
|
||||
(do
|
||||
(common/set-val-timing rotate "0deg")
|
||||
(common/set-val-timing top-view-y 0)
|
||||
(common/set-val-timing top-view-x 0)
|
||||
(common/set-val-timing top-view-width screen-width)
|
||||
(common/set-val-timing top-view-bg colors/neutral-100-opa-0)))))
|
||||
(ra/animate rotate "0deg")
|
||||
(ra/animate top-view-y 0)
|
||||
(ra/animate top-view-x 0)
|
||||
(ra/animate top-view-width screen-width)
|
||||
(ra/animate top-view-bg colors/neutral-100-opa-0)))))
|
||||
|
||||
(defn top-view
|
||||
[{:keys [from timestamp]} insets index animations landscape? screen-width]
|
||||
@@ -44,14 +45,14 @@
|
||||
(fn []
|
||||
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
|
||||
bg-color (if landscape? colors/neutral-100-opa-70 colors/neutral-100-opa-0)]
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/top-view-container (:top insets) animations screen-width bg-color)}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn []
|
||||
(common/set-val-timing (:opacity animations) 0)
|
||||
(ra/animate (:opacity animations) 0)
|
||||
(rf/dispatch (if platform/ios?
|
||||
[:chat.ui/exit-lightbox-signal @index]
|
||||
[:navigate-back])))
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.orientation :as orientation]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.chat.lightbox.common :as common]
|
||||
[react-native.reanimated :as ra]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
@@ -20,18 +19,18 @@
|
||||
|
||||
(defn toggle-opacity
|
||||
[opacity-value border-value transparent? index {:keys [small-list-ref]}]
|
||||
(let [opacity (reanimated/get-shared-value opacity-value)]
|
||||
(let [opacity (ra/get-val opacity-value)]
|
||||
(if (= opacity 1)
|
||||
(do
|
||||
(common/set-val-timing opacity-value 0)
|
||||
(ra/animate opacity-value 0)
|
||||
(js/setTimeout #(reset! transparent? (not @transparent?)) 400))
|
||||
(do
|
||||
(reset! transparent? (not @transparent?))
|
||||
(reanimated/animate-shared-value-with-delay-default-easing opacity-value 1 300 50)
|
||||
(ra/animate-delay opacity-value 1 50)
|
||||
(js/setTimeout #(when @small-list-ref
|
||||
(.scrollToIndex ^js @small-list-ref #js {:animated false :index index}))
|
||||
100)))
|
||||
(common/set-val-timing border-value (if (= opacity 1) 0 12))))
|
||||
(ra/animate border-value (if (= opacity 1) 0 12))))
|
||||
|
||||
(defn handle-orientation
|
||||
[result index window animations {:keys [flat-list-ref insets-atom]}]
|
||||
@@ -103,18 +102,19 @@
|
||||
scroll-index (reagent/atom index)
|
||||
transparent? (reagent/atom false)
|
||||
window (rf/sub [:dimensions/window])
|
||||
animations {:border (common/use-val (if platform/ios? 0 12))
|
||||
:opacity (common/use-val 0)
|
||||
:rotate (common/use-val "0deg")
|
||||
:top-layout (common/use-val -10)
|
||||
:bottom-layout (common/use-val 10)
|
||||
:top-view-y (common/use-val 0)
|
||||
:top-view-x (common/use-val 0)
|
||||
:top-view-width (common/use-val (:width window))
|
||||
:top-view-bg (common/use-val colors/neutral-100-opa-0)}
|
||||
animations {:border (ra/use-val (if platform/ios? 0 12))
|
||||
:opacity (ra/use-val 0)
|
||||
:rotate (ra/use-val "0deg")
|
||||
:top-layout (ra/use-val -10)
|
||||
:bottom-layout (ra/use-val 10)
|
||||
:top-view-y (ra/use-val 0)
|
||||
:top-view-x (ra/use-val 0)
|
||||
:top-view-width (ra/use-val (:width window))
|
||||
:top-view-bg (ra/use-val colors/neutral-100-opa-0)}
|
||||
|
||||
callback (fn [e]
|
||||
(on-viewable-items-changed e scroll-index atoms))]
|
||||
(println "aims" (ra/get-val (:opacity animations)))
|
||||
(reset! data messages)
|
||||
(orientation/use-device-orientation-change
|
||||
(fn [result]
|
||||
@@ -131,10 +131,10 @@
|
||||
(.scrollToIndex ^js @(:flat-list-ref atoms)
|
||||
#js {:animated false :index index}))
|
||||
(js/setTimeout (fn []
|
||||
(common/set-val-timing (:opacity animations) 1)
|
||||
(common/set-val-timing (:top-layout animations) 0)
|
||||
(common/set-val-timing (:bottom-layout animations) 0)
|
||||
(common/set-val-timing (:border animations) 12))
|
||||
(ra/animate (:opacity animations) 1)
|
||||
(ra/animate (:top-layout animations) 0)
|
||||
(ra/animate (:bottom-layout animations) 0)
|
||||
(ra/animate (:border animations) 12))
|
||||
(if platform/ios? 250 100))
|
||||
(js/setTimeout #(reset! (:scroll-index-lock? atoms) false) 300)
|
||||
(fn []
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
(ns status-im2.contexts.chat.lightbox.zoomable-image.style
|
||||
(:require
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as ra]))
|
||||
|
||||
(defn container
|
||||
[{:keys [width height]}
|
||||
{:keys [pan-x pan-y pinch-x pinch-y scale]}
|
||||
set-full-height?]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:translateX pan-x}
|
||||
{:translateY pan-y}
|
||||
{:translateX pinch-x}
|
||||
@@ -22,7 +22,7 @@
|
||||
[{:keys [image-width image-height]}
|
||||
{:keys [rotate rotate-scale]}
|
||||
border-radius]
|
||||
(reanimated/apply-animations-to-style
|
||||
(ra/apply-animations-to-style
|
||||
{:transform [{:rotate rotate}
|
||||
{:scale rotate-scale}]
|
||||
:border-radius border-radius}
|
||||
|
||||
@@ -3,10 +3,96 @@
|
||||
[clojure.string :as string]
|
||||
[react-native.orientation :as orientation]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as c]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
;;; Helpers
|
||||
(defn center-x
|
||||
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
|
||||
(let [duration (if exit? 100 c/default-duration)]
|
||||
(ra/animate pinch-x c/init-offset duration)
|
||||
(ra/set-val pinch-x-start c/init-offset)
|
||||
(ra/animate pan-x c/init-offset duration)
|
||||
(ra/set-val pan-x-start c/init-offset)))
|
||||
|
||||
(defn center-y
|
||||
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
|
||||
(let [duration (if exit? 100 c/default-duration)]
|
||||
(ra/animate pinch-y c/init-offset duration)
|
||||
(ra/set-val pinch-y-start c/init-offset)
|
||||
(ra/animate pan-y c/init-offset duration)
|
||||
(ra/set-val pan-y-start c/init-offset)))
|
||||
|
||||
(defn reset-values
|
||||
[exit? animations {:keys [focal-x focal-y]}]
|
||||
(center-x animations exit?)
|
||||
(center-y animations exit?)
|
||||
(reset! focal-x nil)
|
||||
(reset! focal-y nil))
|
||||
|
||||
(defn rescale-image
|
||||
[value
|
||||
exit?
|
||||
{:keys [x-threshold-scale y-threshold-scale]}
|
||||
{:keys [scale saved-scale] :as animations}
|
||||
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
|
||||
(ra/animate scale value (if exit? 100 c/default-duration))
|
||||
(ra/set-val saved-scale value)
|
||||
(when (= value c/min-scale)
|
||||
(reset-values exit? animations props))
|
||||
(reset! pan-x-enabled? (> value x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> value y-threshold-scale))
|
||||
(when platform/android?
|
||||
(rf/dispatch [:chat.ui/lightbox-scale value])))
|
||||
|
||||
;;; Handlers
|
||||
(defn handle-orientation-change
|
||||
[curr-orientation
|
||||
focused?
|
||||
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
|
||||
{:keys [rotate rotate-scale scale] :as animations}
|
||||
{:keys [pan-x-enabled? pan-y-enabled?]}]
|
||||
(let [duration (when focused? c/default-duration)]
|
||||
(cond
|
||||
(= curr-orientation orientation/landscape-left)
|
||||
(do
|
||||
(ra/animate rotate "90deg" duration)
|
||||
(ra/animate rotate-scale landscape-scale-val duration))
|
||||
(= curr-orientation orientation/landscape-right)
|
||||
(do
|
||||
(ra/animate rotate "-90deg" duration)
|
||||
(ra/animate rotate-scale landscape-scale-val duration))
|
||||
(= curr-orientation orientation/portrait)
|
||||
(do
|
||||
(ra/animate rotate c/init-rotation duration)
|
||||
(ra/animate rotate-scale c/min-scale duration)))
|
||||
(center-x animations false)
|
||||
(center-y animations false)
|
||||
(reset! pan-x-enabled? (> (ra/get-val scale) x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> (ra/get-val scale) y-threshold-scale))))
|
||||
|
||||
|
||||
(defn handle-exit-lightbox-signal
|
||||
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
|
||||
doesn't execute properly, so we need to zoom out first"
|
||||
[exit-lightbox-signal index scale rescale set-full-height?]
|
||||
(when (= exit-lightbox-signal index)
|
||||
(reset! set-full-height? false)
|
||||
(if (> scale c/min-scale)
|
||||
(do
|
||||
(rescale c/min-scale true)
|
||||
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
|
||||
|
||||
(defn handle-zoom-out-signal
|
||||
"Zooms out when pressing on another photo from the small bottom list"
|
||||
[zoom-out-signal index scale rescale]
|
||||
(when (and (= zoom-out-signal index) (> scale c/min-scale))
|
||||
(rescale c/min-scale true)))
|
||||
|
||||
;;; Dimensions
|
||||
(defn get-dimensions
|
||||
"Calculates all required dimensions. Dimensions calculations are different on iOS and Android because landscape
|
||||
mode is implemented differently.On Android, we just need to resize the content, and the OS takes care of the
|
||||
@@ -39,25 +125,6 @@
|
||||
:y-threshold-scale (/ screen-height (min screen-height container-height))
|
||||
:landscape-scale-val (/ portrait-image-width portrait-image-height)}))
|
||||
|
||||
(defn handle-exit-lightbox-signal
|
||||
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
|
||||
doesn't execute properly, so we need to zoom out first"
|
||||
[exit-lightbox-signal index scale rescale set-full-height?]
|
||||
(when (= exit-lightbox-signal index)
|
||||
(reset! set-full-height? false)
|
||||
(if (> scale c/min-scale)
|
||||
(do
|
||||
(rescale c/min-scale true)
|
||||
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
|
||||
|
||||
(defn handle-zoom-out-signal
|
||||
"Zooms out when pressing on another photo from the small bottom list"
|
||||
[zoom-out-signal index scale rescale]
|
||||
(when (and (= zoom-out-signal index) (> scale c/min-scale))
|
||||
(rescale c/min-scale true)))
|
||||
|
||||
|
||||
;;; MATH
|
||||
(defn get-max-offset
|
||||
|
||||
@@ -12,98 +12,6 @@
|
||||
[status-im2.contexts.chat.lightbox.zoomable-image.style :as style]
|
||||
[status-im2.contexts.chat.lightbox.zoomable-image.utils :as utils]))
|
||||
|
||||
;;;; Some aliases for reanimated methods, as they are used 10s of times in this file
|
||||
;; TODO: Abstract Reanimated methods in a better way, issue:
|
||||
;; https://github.com/status-im/status-mobile/issues/15176
|
||||
(defn get-val
|
||||
[animation]
|
||||
(reanimated/get-shared-value animation))
|
||||
|
||||
(defn set-val
|
||||
[animation value]
|
||||
(reanimated/set-shared-value animation value))
|
||||
|
||||
(defn use-val
|
||||
[value]
|
||||
(reanimated/use-shared-value value))
|
||||
|
||||
(defn timing
|
||||
([value]
|
||||
(timing value c/default-duration))
|
||||
([value duration]
|
||||
(if (= duration nil)
|
||||
value
|
||||
(reanimated/with-timing-duration value duration))))
|
||||
|
||||
(defn set-val-decay
|
||||
[animation velocity bounds]
|
||||
(reanimated/animate-shared-value-with-decay animation (* velocity c/velocity-factor) bounds))
|
||||
|
||||
;;;; Helpers
|
||||
(defn center-x
|
||||
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
|
||||
(let [duration (if exit? 100 c/default-duration)]
|
||||
(set-val pinch-x (timing c/init-offset duration))
|
||||
(set-val pinch-x-start c/init-offset)
|
||||
(set-val pan-x (timing c/init-offset duration))
|
||||
(set-val pan-x-start c/init-offset)))
|
||||
|
||||
(defn center-y
|
||||
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
|
||||
(let [duration (if exit? 100 c/default-duration)]
|
||||
(set-val pinch-y (timing c/init-offset duration))
|
||||
(set-val pinch-y-start c/init-offset)
|
||||
(set-val pan-y (timing c/init-offset duration))
|
||||
(set-val pan-y-start c/init-offset)))
|
||||
|
||||
(defn reset-values
|
||||
[exit? animations {:keys [focal-x focal-y]}]
|
||||
(center-x animations exit?)
|
||||
(center-y animations exit?)
|
||||
(reset! focal-x nil)
|
||||
(reset! focal-y nil))
|
||||
|
||||
(defn rescale-image
|
||||
[value
|
||||
exit?
|
||||
{:keys [x-threshold-scale y-threshold-scale]}
|
||||
{:keys [scale saved-scale] :as animations}
|
||||
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
|
||||
(set-val scale (timing value (if exit? 100 c/default-duration)))
|
||||
(set-val saved-scale value)
|
||||
(when (= value c/min-scale)
|
||||
(reset-values exit? animations props))
|
||||
(reset! pan-x-enabled? (> value x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> value y-threshold-scale))
|
||||
(when platform/android?
|
||||
(rf/dispatch [:chat.ui/lightbox-scale value])))
|
||||
|
||||
(defn handle-orientation-change
|
||||
[curr-orientation
|
||||
focused?
|
||||
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
|
||||
{:keys [rotate rotate-scale scale] :as animations}
|
||||
{:keys [pan-x-enabled? pan-y-enabled?]}]
|
||||
(let [duration (when focused? c/default-duration)]
|
||||
(cond
|
||||
(= curr-orientation orientation/landscape-left)
|
||||
(do
|
||||
(set-val rotate (timing "90deg" duration))
|
||||
(set-val rotate-scale (timing landscape-scale-val duration)))
|
||||
(= curr-orientation orientation/landscape-right)
|
||||
(do
|
||||
(set-val rotate (timing "-90deg" duration))
|
||||
(set-val rotate-scale (timing landscape-scale-val duration)))
|
||||
(= curr-orientation orientation/portrait)
|
||||
(do
|
||||
(set-val rotate (timing c/init-rotation duration))
|
||||
(set-val rotate-scale (timing c/min-scale duration))))
|
||||
(center-x animations false)
|
||||
(center-y animations false)
|
||||
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale))))
|
||||
|
||||
;;;; Gestures
|
||||
(defn tap-gesture
|
||||
[on-tap]
|
||||
(->
|
||||
@@ -119,15 +27,15 @@
|
||||
(gesture/number-of-taps 2)
|
||||
(gesture/on-start
|
||||
(fn [e]
|
||||
(if (= (get-val scale) c/min-scale)
|
||||
(if (= (reanimated/get-shared-value scale) c/min-scale)
|
||||
(let [translate-x (utils/get-double-tap-offset width screen-width (oget e "x"))
|
||||
translate-y (utils/get-double-tap-offset height screen-height (oget e "y"))]
|
||||
(when (> c/double-tap-scale x-threshold-scale)
|
||||
(set-val pan-x (timing translate-x))
|
||||
(set-val pan-x-start translate-x))
|
||||
(reanimated/set-shared-value pan-x (reanimated/with-timing translate-x))
|
||||
(reanimated/set-shared-value pan-x-start translate-x))
|
||||
(when (> c/double-tap-scale y-threshold-scale)
|
||||
(set-val pan-y (timing translate-y))
|
||||
(set-val pan-y-start translate-y))
|
||||
(reanimated/set-shared-value pan-y (reanimated/with-timing translate-y))
|
||||
(reanimated/set-shared-value pan-y-start translate-y))
|
||||
(rescale c/double-tap-scale))
|
||||
(rescale c/min-scale))))))
|
||||
|
||||
@@ -137,30 +45,30 @@
|
||||
{:keys [saved-scale scale pinch-x pinch-y pinch-x-start pinch-y-start pan-y pan-y-start pan-x
|
||||
pan-x-start]}
|
||||
{:keys [pan-x-enabled? pan-y-enabled?]}]
|
||||
(let [curr-offset-y (+ (get-val pan-y) (get-val pinch-y))
|
||||
max-offset-y (utils/get-max-offset height screen-height (get-val scale))
|
||||
(let [curr-offset-y (+ (reanimated/get-shared-value pan-y) (reanimated/get-shared-value pinch-y))
|
||||
max-offset-y (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
|
||||
max-offset-y (if (neg? curr-offset-y) (- max-offset-y) max-offset-y)
|
||||
curr-offset-x (+ (get-val pan-x) (get-val pinch-x))
|
||||
max-offset-x (utils/get-max-offset width screen-width (get-val scale))
|
||||
curr-offset-x (+ (reanimated/get-shared-value pan-x) (reanimated/get-shared-value pinch-x))
|
||||
max-offset-x (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
|
||||
max-offset-x (if (neg? curr-offset-x) (- max-offset-x) max-offset-x)]
|
||||
(when (and (> (get-val scale) y-threshold-scale)
|
||||
(< (get-val scale) c/max-scale)
|
||||
(when (and (> (reanimated/get-shared-value scale) y-threshold-scale)
|
||||
(< (reanimated/get-shared-value scale) c/max-scale)
|
||||
(> (Math/abs curr-offset-y) (Math/abs max-offset-y)))
|
||||
(set-val pinch-y (timing c/init-offset))
|
||||
(set-val pinch-y-start c/init-offset)
|
||||
(set-val pan-y (timing max-offset-y))
|
||||
(set-val pan-y-start max-offset-y))
|
||||
(when (and (> (get-val scale) x-threshold-scale)
|
||||
(< (get-val scale) c/max-scale)
|
||||
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
|
||||
(reanimated/set-shared-value pinch-y-start c/init-offset)
|
||||
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset-y))
|
||||
(reanimated/set-shared-value pan-y-start max-offset-y))
|
||||
(when (and (> (reanimated/get-shared-value scale) x-threshold-scale)
|
||||
(< (reanimated/get-shared-value scale) c/max-scale)
|
||||
(> (Math/abs curr-offset-x) (Math/abs max-offset-x)))
|
||||
(set-val pinch-x (timing c/init-offset))
|
||||
(set-val pinch-x-start c/init-offset)
|
||||
(set-val pan-x (timing max-offset-x))
|
||||
(set-val pan-x-start max-offset-x))
|
||||
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale))
|
||||
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
|
||||
(reanimated/set-shared-value pinch-x-start c/init-offset)
|
||||
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset-x))
|
||||
(reanimated/set-shared-value pan-x-start max-offset-x))
|
||||
(reset! pan-x-enabled? (> (reanimated/get-shared-value scale) x-threshold-scale))
|
||||
(reset! pan-y-enabled? (> (reanimated/get-shared-value scale) y-threshold-scale))
|
||||
(when platform/android?
|
||||
(rf/dispatch [:chat.ui/lightbox-scale (get-val saved-scale)]))))
|
||||
(rf/dispatch [:chat.ui/lightbox-scale (reanimated/get-shared-value saved-scale)]))))
|
||||
|
||||
(defn pinch-gesture
|
||||
[{:keys [width height screen-height screen-width x-threshold-scale y-threshold-scale] :as dimensions}
|
||||
@@ -178,41 +86,49 @@
|
||||
(when platform/android?
|
||||
(reset! focal-x (utils/get-focal (oget e "focalX") width screen-width))
|
||||
(reset! focal-y (utils/get-focal (oget e "focalY") height screen-height)))))
|
||||
(gesture/on-update (fn [e]
|
||||
(let [new-scale (* (oget e "scale") (get-val saved-scale))
|
||||
scale-diff (utils/get-scale-diff new-scale (get-val saved-scale))
|
||||
new-pinch-x (utils/get-pinch-position scale-diff screen-width @focal-x)
|
||||
new-pinch-y (utils/get-pinch-position scale-diff screen-height @focal-y)]
|
||||
(when (and (>= new-scale c/max-scale) (= (get-val pinch-x-max) js/Infinity))
|
||||
(set-val pinch-x-max (get-val pinch-x))
|
||||
(set-val pinch-y-max (get-val pinch-y)))
|
||||
(set-val pinch-x (+ new-pinch-x (get-val pinch-x-start)))
|
||||
(set-val pinch-y (+ new-pinch-y (get-val pinch-y-start)))
|
||||
(set-val scale new-scale))))
|
||||
(gesture/on-update
|
||||
(fn [e]
|
||||
(let [new-scale (* (oget e "scale") (reanimated/get-shared-value saved-scale))
|
||||
scale-diff (utils/get-scale-diff new-scale (reanimated/get-shared-value saved-scale))
|
||||
new-pinch-x (utils/get-pinch-position scale-diff screen-width @focal-x)
|
||||
new-pinch-y (utils/get-pinch-position scale-diff screen-height @focal-y)]
|
||||
(when (and (>= new-scale c/max-scale)
|
||||
(= (reanimated/get-shared-value pinch-x-max) js/Infinity))
|
||||
(reanimated/set-shared-value pinch-x-max (reanimated/get-shared-value pinch-x))
|
||||
(reanimated/set-shared-value pinch-y-max (reanimated/get-shared-value pinch-y)))
|
||||
(reanimated/set-shared-value pinch-x
|
||||
(+ new-pinch-x (reanimated/get-shared-value pinch-x-start)))
|
||||
(reanimated/set-shared-value pinch-y
|
||||
(+ new-pinch-y (reanimated/get-shared-value pinch-y-start)))
|
||||
(reanimated/set-shared-value scale new-scale))))
|
||||
(gesture/on-end
|
||||
(fn []
|
||||
(cond
|
||||
(< (get-val scale) c/min-scale)
|
||||
(< (reanimated/get-shared-value scale) c/min-scale)
|
||||
(rescale c/min-scale)
|
||||
(> (get-val scale) c/max-scale)
|
||||
(> (reanimated/get-shared-value scale) c/max-scale)
|
||||
(do
|
||||
(set-val pinch-x (timing (get-val pinch-x-max)))
|
||||
(set-val pinch-x-start (get-val pinch-x-max))
|
||||
(set-val pinch-x-max js/Infinity)
|
||||
(set-val pinch-y (timing (get-val pinch-y-max)))
|
||||
(set-val pinch-y-start (get-val pinch-y-max))
|
||||
(set-val pinch-y-max js/Infinity)
|
||||
(set-val scale (timing c/max-scale))
|
||||
(set-val saved-scale c/max-scale))
|
||||
(reanimated/set-shared-value pinch-x
|
||||
(reanimated/with-timing (reanimated/get-shared-value
|
||||
pinch-x-max)))
|
||||
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x-max))
|
||||
(reanimated/set-shared-value pinch-x-max js/Infinity)
|
||||
(reanimated/set-shared-value pinch-y
|
||||
(reanimated/with-timing (reanimated/get-shared-value
|
||||
pinch-y-max)))
|
||||
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y-max))
|
||||
(reanimated/set-shared-value pinch-y-max js/Infinity)
|
||||
(reanimated/set-shared-value scale (reanimated/with-timing c/max-scale))
|
||||
(reanimated/set-shared-value saved-scale c/max-scale))
|
||||
:else
|
||||
(do
|
||||
(set-val saved-scale (get-val scale))
|
||||
(set-val pinch-x-start (get-val pinch-x))
|
||||
(set-val pinch-y-start (get-val pinch-y))
|
||||
(when (< (get-val scale) x-threshold-scale)
|
||||
(center-x animations false))
|
||||
(when (< (get-val scale) y-threshold-scale)
|
||||
(center-y animations false))))
|
||||
(reanimated/set-shared-value saved-scale (reanimated/get-shared-value scale))
|
||||
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x))
|
||||
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y))
|
||||
(when (< (reanimated/get-shared-value scale) x-threshold-scale)
|
||||
(utils/center-x animations false))
|
||||
(when (< (reanimated/get-shared-value scale) y-threshold-scale)
|
||||
(utils/center-y animations false))))
|
||||
(finalize-pinch dimensions animations props)))))
|
||||
|
||||
(defn pan-x-gesture
|
||||
@@ -225,27 +141,33 @@
|
||||
(gesture/enabled @pan-x-enabled?)
|
||||
(gesture/average-touches false)
|
||||
(gesture/on-update (fn [e]
|
||||
(set-val pan-x (+ (get-val pan-x-start) (oget e "translationX")))))
|
||||
(reanimated/set-shared-value pan-x
|
||||
(+ (reanimated/get-shared-value pan-x-start)
|
||||
(oget e "translationX")))))
|
||||
(gesture/on-end
|
||||
(fn [e]
|
||||
(let [curr-offset (+ (get-val pan-x) (get-val pinch-x-start))
|
||||
max-offset (utils/get-max-offset width screen-width (get-val scale))
|
||||
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
|
||||
(let [curr-offset (+ (reanimated/get-shared-value pan-x)
|
||||
(reanimated/get-shared-value pinch-x-start))
|
||||
max-offset (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
|
||||
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
|
||||
velocity (* (oget e "velocityX") c/velocity-factor)]
|
||||
(cond
|
||||
(< (get-val scale) x-threshold-scale)
|
||||
(< (reanimated/get-shared-value scale) x-threshold-scale)
|
||||
(rescale c/min-scale)
|
||||
(> (Math/abs curr-offset) (Math/abs max-offset))
|
||||
(do
|
||||
(set-val pan-x (timing max-offset))
|
||||
(set-val pan-x-start max-offset)
|
||||
(set-val pinch-x (timing c/init-offset))
|
||||
(set-val pinch-x-start c/init-offset))
|
||||
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset))
|
||||
(reanimated/set-shared-value pan-x-start max-offset)
|
||||
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
|
||||
(reanimated/set-shared-value pinch-x-start c/init-offset))
|
||||
:else
|
||||
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-x-start))
|
||||
upper-bound (- (Math/abs max-offset) (get-val pinch-x-start))]
|
||||
(set-val pan-x-start (get-val pan-x))
|
||||
(set-val-decay pan-x (oget e "velocityX") [lower-bound upper-bound])
|
||||
(set-val-decay pan-x-start (oget e "velocityX") [lower-bound upper-bound]))))))))
|
||||
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-x-start))
|
||||
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-x-start))]
|
||||
(reanimated/set-shared-value pan-x-start (reanimated/get-shared-value pan-x))
|
||||
(reanimated/animate-shared-value-with-decay pan-x velocity [lower-bound upper-bound])
|
||||
(reanimated/animate-shared-value-with-decay pan-x-start
|
||||
velocity
|
||||
[lower-bound upper-bound]))))))))
|
||||
|
||||
|
||||
(defn pan-y-gesture
|
||||
@@ -258,30 +180,34 @@
|
||||
(gesture/enabled @pan-y-enabled?)
|
||||
(gesture/average-touches false)
|
||||
(gesture/on-update (fn [e]
|
||||
(set-val pan-y (+ (get-val pan-y-start) (oget e "translationY")))))
|
||||
(reanimated/set-shared-value pan-y
|
||||
(+ (reanimated/get-shared-value pan-y-start)
|
||||
(oget e "translationY")))))
|
||||
(gesture/on-end
|
||||
(fn [e]
|
||||
(let [curr-offset (+ (get-val pan-y) (get-val pinch-y-start))
|
||||
max-offset (utils/get-max-offset height screen-height (get-val scale))
|
||||
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
|
||||
(let [curr-offset (+ (reanimated/get-shared-value pan-y)
|
||||
(reanimated/get-shared-value pinch-y-start))
|
||||
max-offset (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
|
||||
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
|
||||
velocity (* (oget e "velocityY") c/velocity-factor)]
|
||||
(cond
|
||||
(< (get-val scale) y-threshold-scale)
|
||||
(< (reanimated/get-shared-value scale) y-threshold-scale)
|
||||
(rescale c/min-scale)
|
||||
(> (Math/abs curr-offset) (Math/abs max-offset))
|
||||
(do
|
||||
(set-val pan-y (timing max-offset))
|
||||
(set-val pan-y-start max-offset)
|
||||
(set-val pinch-y (timing c/init-offset))
|
||||
(set-val pinch-y-start c/init-offset))
|
||||
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset))
|
||||
(reanimated/set-shared-value pan-y-start max-offset)
|
||||
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
|
||||
(reanimated/set-shared-value pinch-y-start c/init-offset))
|
||||
:else
|
||||
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-y-start))
|
||||
upper-bound (- (Math/abs max-offset) (get-val pinch-y-start))]
|
||||
(set-val pan-y-start (get-val pan-y))
|
||||
(set-val-decay pan-y (oget e "velocityY") [lower-bound upper-bound])
|
||||
(set-val-decay pan-y-start (oget e "velocityY") [lower-bound upper-bound]))))))))
|
||||
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-y-start))
|
||||
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-y-start))]
|
||||
(reanimated/set-shared-value pan-y-start (reanimated/get-shared-value pan-y))
|
||||
(reanimated/animate-shared-value-with-decay pan-y velocity [lower-bound upper-bound])
|
||||
(reanimated/animate-shared-value-with-decay pan-y-start
|
||||
velocity
|
||||
[lower-bound upper-bound]))))))))
|
||||
|
||||
|
||||
;;;; Finally, the component
|
||||
(defn zoomable-image
|
||||
[{:keys [image-width image-height content message-id]} index border-radius on-tap]
|
||||
(let [set-full-height? (reagent/atom false)]
|
||||
@@ -294,37 +220,40 @@
|
||||
curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
|
||||
focused? (= shared-element-id message-id)
|
||||
dimensions (utils/get-dimensions image-width image-height curr-orientation)
|
||||
animations {:scale (use-val initial-scale)
|
||||
:saved-scale (use-val initial-scale)
|
||||
:pan-x-start (use-val c/init-offset)
|
||||
:pan-x (use-val c/init-offset)
|
||||
:pan-y-start (use-val c/init-offset)
|
||||
:pan-y (use-val c/init-offset)
|
||||
:pinch-x-start (use-val c/init-offset)
|
||||
:pinch-x (use-val c/init-offset)
|
||||
:pinch-y-start (use-val c/init-offset)
|
||||
:pinch-y (use-val c/init-offset)
|
||||
:pinch-x-max (use-val js/Infinity)
|
||||
:pinch-y-max (use-val js/Infinity)
|
||||
:rotate (use-val c/init-rotation)
|
||||
:rotate-scale (use-val c/min-scale)}
|
||||
animations {:scale (reanimated/use-shared-value initial-scale)
|
||||
:saved-scale (reanimated/use-shared-value initial-scale)
|
||||
:pan-x-start (reanimated/use-shared-value c/init-offset)
|
||||
:pan-x (reanimated/use-shared-value c/init-offset)
|
||||
:pan-y-start (reanimated/use-shared-value c/init-offset)
|
||||
:pan-y (reanimated/use-shared-value c/init-offset)
|
||||
:pinch-x-start (reanimated/use-shared-value c/init-offset)
|
||||
:pinch-x (reanimated/use-shared-value c/init-offset)
|
||||
:pinch-y-start (reanimated/use-shared-value c/init-offset)
|
||||
:pinch-y (reanimated/use-shared-value c/init-offset)
|
||||
:pinch-x-max (reanimated/use-shared-value js/Infinity)
|
||||
:pinch-y-max (reanimated/use-shared-value js/Infinity)
|
||||
:rotate (reanimated/use-shared-value c/init-rotation)
|
||||
:rotate-scale (reanimated/use-shared-value c/min-scale)}
|
||||
props {:pan-x-enabled? (reagent/atom false)
|
||||
:pan-y-enabled? (reagent/atom false)
|
||||
:focal-x (reagent/atom nil)
|
||||
:focal-y (reagent/atom nil)}
|
||||
rescale (fn [value exit?]
|
||||
(rescale-image value exit? dimensions animations props))]
|
||||
(utils/rescale-image value exit? dimensions animations props))]
|
||||
(rn/use-effect-once (fn []
|
||||
(js/setTimeout #(reset! set-full-height? true) 500)
|
||||
js/undefined))
|
||||
(when platform/ios?
|
||||
(handle-orientation-change curr-orientation focused? dimensions animations props)
|
||||
(utils/handle-orientation-change curr-orientation focused? dimensions animations props)
|
||||
(utils/handle-exit-lightbox-signal exit-lightbox-signal
|
||||
index
|
||||
(get-val (:scale animations))
|
||||
(reanimated/get-shared-value (:scale animations))
|
||||
rescale
|
||||
set-full-height?))
|
||||
(utils/handle-zoom-out-signal zoom-out-signal index (get-val (:scale animations)) rescale)
|
||||
(utils/handle-zoom-out-signal zoom-out-signal
|
||||
index
|
||||
(reanimated/get-shared-value (:scale animations))
|
||||
rescale)
|
||||
[:f>
|
||||
(fn []
|
||||
(let [tap (tap-gesture on-tap)
|
||||
@@ -336,10 +265,9 @@
|
||||
(gesture/simultaneous pinch pan-x pan-y)
|
||||
(gesture/exclusive double-tap tap))]
|
||||
[gesture/gesture-detector {:gesture composed-gestures}
|
||||
[reanimated/view
|
||||
[ra/view
|
||||
{:style (style/container dimensions animations @set-full-height?)}
|
||||
[reanimated/fast-image
|
||||
[ra/fast-image
|
||||
{:source {:uri (:image content)}
|
||||
:native-ID (when focused? :shared-element)
|
||||
:style (style/image dimensions animations border-radius)}]]]))]))]))
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im2.contexts.chat.messages.composer.mentions.view
|
||||
(:require [utils.re-frame :as rf]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]))
|
||||
|
||||
(defn mention-item
|
||||
@@ -13,13 +13,13 @@
|
||||
[{:keys [refs suggestions max-y]} insets]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [translate-y (reanimated/use-shared-value 0)]
|
||||
(let [translate-y (ra/use-val 0)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(reanimated/set-shared-value translate-y
|
||||
(reanimated/with-timing (if (seq suggestions) 0 200)))))
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
(ra/set-val translate-y
|
||||
(ra/with-timing (if (seq suggestions) 0 200)))))
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
{:bottom (or (:bottom insets) 0)
|
||||
:position :absolute
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.composer.style :as style]
|
||||
@@ -43,7 +43,7 @@
|
||||
(gesture/on-start
|
||||
(fn [_]
|
||||
(if keyboard-shown
|
||||
(swap! gesture-values assoc :pan-y (reanimated/get-shared-value translate-y))
|
||||
(swap! gesture-values assoc :pan-y (ra/get-val translate-y))
|
||||
(input/input-focus text-input-ref))))
|
||||
(gesture/on-update
|
||||
(fn [evt]
|
||||
@@ -51,7 +51,7 @@
|
||||
(let [tY (oget evt "translationY")]
|
||||
(swap! gesture-values assoc :dy (- tY (:pdy @gesture-values)))
|
||||
(swap! gesture-values assoc :pdy tY)
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
translate-y
|
||||
(max (min (+ tY (:pan-y @gesture-values)) (- min-y)) (- max-y)))))))
|
||||
(gesture/on-end
|
||||
@@ -129,12 +129,12 @@
|
||||
:bg-bottom bg-bottom
|
||||
:window-height window-height
|
||||
:set-bg-opacity (fn [value]
|
||||
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
|
||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
|
||||
(ra/set-val bg-bottom (if (= value 1) 0 (- window-height)))
|
||||
(ra/set-val bg-opacity (ra/with-timing value)))
|
||||
:set-translate-y (fn [value]
|
||||
(reanimated/set-shared-value translate-y (reanimated/with-timing value)))
|
||||
(ra/set-val translate-y (ra/with-timing value)))
|
||||
:set-parent-height (fn [value]
|
||||
(reanimated/set-shared-value parent-height (reanimated/with-timing value)))})
|
||||
(ra/set-val parent-height (ra/with-timing value)))})
|
||||
|
||||
;; IMPORTANT! PLEASE READ BEFORE MAKING CHANGES
|
||||
|
||||
@@ -165,9 +165,9 @@
|
||||
|
||||
{window-height :height} (rn/use-window-dimensions)
|
||||
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
bg-bottom (reanimated/use-shared-value (- window-height))
|
||||
translate-y (ra/use-val 0)
|
||||
bg-opacity (ra/use-val 0)
|
||||
bg-bottom (ra/use-val (- window-height))
|
||||
|
||||
suggestions? (and (seq suggestions)
|
||||
keyboard-shown
|
||||
@@ -190,7 +190,7 @@
|
||||
(when (or edit reply) 38)
|
||||
(when (seq images) 80))))
|
||||
|
||||
parent-height (reanimated/use-shared-value min-y)
|
||||
parent-height (ra/use-val min-y)
|
||||
max-parent-height (Math/abs (- max-y 110 (:bottom insets)))
|
||||
|
||||
params
|
||||
@@ -201,14 +201,14 @@
|
||||
input-content-change (get-input-content-change params)
|
||||
bottom-sheet-gesture (get-bottom-sheet-gesture params)]
|
||||
(effect! params)
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:height parent-height}
|
||||
{})}
|
||||
;;;;input
|
||||
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/input-bottom-sheet window-height))}
|
||||
[rn/view {:style (style/bottom-sheet-handle)}]
|
||||
@@ -225,8 +225,8 @@
|
||||
[mentions/mentions params insets]
|
||||
[controls/view send-ref params insets chat-id images #(clean-and-minimize params)])
|
||||
;;;;black background
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:opacity bg-opacity
|
||||
:transform [{:translateY bg-bottom}]}
|
||||
(style/bottom-sheet-background window-height))}]]))])))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[quo2.components.animated-header-flatlist.view :as animated-header-list]))
|
||||
|
||||
(def data [0 1 2 3 4 5 6 7 8 9 10])
|
||||
@@ -38,8 +38,8 @@
|
||||
[animation]
|
||||
[:f>
|
||||
(fn []
|
||||
[reanimated/fast-image
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/fast-image
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:width animation
|
||||
:height animation}
|
||||
{:border-radius 72})
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.components.navigation.bottom-nav-tab :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
pass-through? (reagent/cursor state [:pass-through?])]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [icon-color-anim (reanimated/use-shared-value colors/white)]
|
||||
(reanimated/set-shared-value
|
||||
(let [icon-color-anim (ra/use-val colors/white)]
|
||||
(ra/set-val
|
||||
icon-color-anim
|
||||
(get-icon-color @selected? @pass-through?))
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.components.navigation.floating-shell-button :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
@@ -56,7 +56,7 @@
|
||||
{:padding-vertical 60
|
||||
:align-items :center}
|
||||
[quo2/floating-shell-button (mock-data @state)
|
||||
nil (reanimated/use-shared-value 1)]]]])]))
|
||||
nil (ra/use-val 1)]]]])]))
|
||||
|
||||
(defn preview-floating-shell-button
|
||||
[]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im2.contexts.shell.animation
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.async-storage.core :as async-storage] ;;TODO remove when not used anymore
|
||||
[status-im2.contexts.shell.constants :as shell.constants]))
|
||||
@@ -71,12 +71,12 @@
|
||||
;; Shared Values
|
||||
(defn calculate-shared-values
|
||||
[]
|
||||
(let [selected-stack-id-sv (reanimated/use-shared-value
|
||||
(let [selected-stack-id-sv (ra/use-val
|
||||
;; passing keywords or nil is not working with reanimated
|
||||
(name (or @selected-stack-id :communities-stack)))
|
||||
pass-through-sv (reanimated/use-shared-value false)
|
||||
home-stack-state-sv (reanimated/use-shared-value @home-stack-state)
|
||||
animate-home-stack-left (reanimated/use-shared-value (not (home-stack-open?)))
|
||||
pass-through-sv (ra/use-val false)
|
||||
home-stack-state-sv (ra/use-val @home-stack-state)
|
||||
animate-home-stack-left (ra/use-val (not (home-stack-open?)))
|
||||
home-stack-position (calculate-home-stack-position)]
|
||||
(reset! shared-values-atom
|
||||
(reduce
|
||||
@@ -153,10 +153,10 @@
|
||||
(let [home-stack-state-value (if animate?
|
||||
shell.constants/open-with-animation
|
||||
shell.constants/open-without-animation)]
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
(:selected-stack-id @shared-values-atom)
|
||||
(name stack-id))
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
(:home-stack-state @shared-values-atom)
|
||||
home-stack-state-value)
|
||||
(reset! home-stack-state home-stack-state-value)
|
||||
@@ -168,8 +168,8 @@
|
||||
|
||||
(defn change-tab
|
||||
[stack-id]
|
||||
(reanimated/set-shared-value (:animate-home-stack-left @shared-values-atom) false)
|
||||
(reanimated/set-shared-value (:selected-stack-id @shared-values-atom) (name stack-id))
|
||||
(ra/set-val (:animate-home-stack-left @shared-values-atom) false)
|
||||
(ra/set-val (:selected-stack-id @shared-values-atom) (name stack-id))
|
||||
(reset! selected-stack-id stack-id)
|
||||
(async-storage/set-item! :selected-stack-id stack-id))
|
||||
|
||||
@@ -189,10 +189,10 @@
|
||||
(let [home-stack-state-value (if animate?
|
||||
shell.constants/close-with-animation
|
||||
shell.constants/close-without-animation)]
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
(:animate-home-stack-left @shared-values-atom)
|
||||
true)
|
||||
(reanimated/set-shared-value
|
||||
(ra/set-val
|
||||
(:home-stack-state @shared-values-atom)
|
||||
home-stack-state-value)
|
||||
(reset! home-stack-state home-stack-state-value)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [utils.re-frame :as rf]
|
||||
[react-native.core :as rn]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[status-im2.contexts.shell.style :as style]
|
||||
[status-im2.contexts.shell.animation :as animation]
|
||||
[status-im2.contexts.shell.constants :as shell.constants]
|
||||
@@ -36,12 +36,12 @@
|
||||
pass-through? (rf/sub [:shell/shell-pass-through?])
|
||||
shared-values @animation/shared-values-atom
|
||||
original-style (style/bottom-tabs-container pass-through?)
|
||||
animated-style (reanimated/apply-animations-to-style
|
||||
animated-style (ra/apply-animations-to-style
|
||||
{:height (:bottom-tabs-height shared-values)}
|
||||
original-style)]
|
||||
(animation/load-stack @animation/selected-stack-id)
|
||||
(reanimated/set-shared-value (:pass-through? shared-values) pass-through?)
|
||||
[reanimated/view {:style animated-style}
|
||||
(ra/set-val (:pass-through? shared-values) pass-through?)
|
||||
[ra/view {:style animated-style}
|
||||
(when pass-through?
|
||||
[blur/view (blur-overlay-params style/bottom-tabs-blur-overlay)])
|
||||
[rn/view {:style (style/bottom-tabs)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns status-im2.contexts.shell.home-stack
|
||||
(:require [react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.reanimated :as ra]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
||||
[status-im2.contexts.chat.home.view :as chat] ;; TODO move to status-im2
|
||||
@@ -23,8 +23,8 @@
|
||||
(when (load-stack? stack-id)
|
||||
[:f>
|
||||
(fn []
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
[ra/view
|
||||
{:style (ra/apply-animations-to-style
|
||||
{:opacity (get shared-values
|
||||
(get shell.constants/stacks-opacity-keywords stack-id))
|
||||
:pointer-events (get shared-values
|
||||
@@ -49,14 +49,14 @@
|
||||
(fn []
|
||||
(let [shared-values @animation/shared-values-atom
|
||||
home-stack-original-style (styles/home-stack @animation/screen-height)
|
||||
home-stack-animated-style (reanimated/apply-animations-to-style
|
||||
home-stack-animated-style (ra/apply-animations-to-style
|
||||
{:top (:home-stack-top shared-values)
|
||||
:left (:home-stack-left shared-values)
|
||||
:opacity (:home-stack-opacity shared-values)
|
||||
:pointer-events (:home-stack-pointer shared-values)
|
||||
:transform [{:scale (:home-stack-scale shared-values)}]}
|
||||
home-stack-original-style)]
|
||||
[reanimated/view {:style home-stack-animated-style}
|
||||
[ra/view {:style home-stack-animated-style}
|
||||
[rn/view {:margin-top (:top insets) :flex 1}
|
||||
[stack-view :communities-stack shared-values]
|
||||
[stack-view :chats-stack shared-values]
|
||||
|
||||
Reference in New Issue
Block a user