migrating to react state. step 1 (#18901)
This commit is contained in:
parent
acc6a3c072
commit
047e45d2a3
|
@ -6,8 +6,7 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn remove-http-https-www
|
(defn remove-http-https-www
|
||||||
[value]
|
[value]
|
||||||
|
@ -68,28 +67,49 @@
|
||||||
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
|
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
|
||||||
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
|
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[{:keys [default-value]
|
[{:keys [disabled? blur? on-change-text customization-color
|
||||||
:or {default-value ""}}]
|
on-clear on-focus on-blur get-ref locked?
|
||||||
(let [state (reagent/atom :default)
|
favicon favicon-color favicon-size default-value]
|
||||||
value (reagent/atom default-value)
|
:or {default-value ""}
|
||||||
set-active #(reset! state :active)
|
|
||||||
set-default #(reset! state :default)
|
|
||||||
set-value #(reset! value %)
|
|
||||||
ref (atom nil)
|
|
||||||
clear-input (fn []
|
|
||||||
(.clear ^js @ref)
|
|
||||||
(reset! value ""))
|
|
||||||
focus-input (fn []
|
|
||||||
(set-active)
|
|
||||||
(.focus ^js @ref))]
|
|
||||||
(fn [{:keys [disabled? blur? on-change-text customization-color
|
|
||||||
on-clear on-focus on-blur theme get-ref locked?
|
|
||||||
favicon favicon-color favicon-size]
|
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [clean-props (apply dissoc props props-to-remove)]
|
(let [ref (rn/use-ref-atom nil)
|
||||||
|
on-ref (rn/use-callback
|
||||||
|
(fn [r]
|
||||||
|
(reset! ref r)
|
||||||
|
(when get-ref (get-ref r)))
|
||||||
|
[get-ref])
|
||||||
|
theme (quo.theme/use-theme)
|
||||||
|
[state set-state] (rn/use-state :default)
|
||||||
|
[value set-value] (rn/use-state default-value)
|
||||||
|
on-clear (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(.clear ^js @ref)
|
||||||
|
(set-value "")
|
||||||
|
(when on-clear (on-clear)))
|
||||||
|
[on-clear])
|
||||||
|
focus-input (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :active)
|
||||||
|
(.focus ^js @ref)))
|
||||||
|
on-blur (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :default)
|
||||||
|
(when on-blur (on-blur)))
|
||||||
|
[on-blur])
|
||||||
|
on-change-text (rn/use-callback
|
||||||
|
(fn [new-text]
|
||||||
|
(set-value new-text)
|
||||||
|
(when on-change-text (on-change-text new-text)))
|
||||||
|
[on-change-text])
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :active)
|
||||||
|
(when on-focus (on-focus)))
|
||||||
|
[on-focus])
|
||||||
|
clean-props (apply dissoc props props-to-remove)]
|
||||||
[rn/view {:style style/root-container}
|
[rn/view {:style style/root-container}
|
||||||
(when (and (seq @value) (= @state :default))
|
(when (and (seq value) (= state :default))
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:style style/default-container
|
{:style style/default-container
|
||||||
:on-press focus-input}
|
:on-press focus-input}
|
||||||
|
@ -101,12 +121,11 @@
|
||||||
:size favicon-size}])
|
:size favicon-size}])
|
||||||
[rn/text
|
[rn/text
|
||||||
{:accessibility-label :browser-input-label
|
{:accessibility-label :browser-input-label
|
||||||
:style (style/text)} (remove-http-https-www @value)]
|
:style (style/text)}
|
||||||
|
(remove-http-https-www value)]
|
||||||
(when locked?
|
(when locked?
|
||||||
[lock-icon
|
[lock-icon {:blur? blur? :theme theme}])])
|
||||||
{:blur? blur?
|
[rn/view {:style (style/active-container (or (empty? value) (= state :active)))}
|
||||||
:theme theme}])])
|
|
||||||
[rn/view {:style (style/active-container (or (empty? @value) (= @state :active)))}
|
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
(merge
|
(merge
|
||||||
clean-props
|
clean-props
|
||||||
|
@ -117,29 +136,17 @@
|
||||||
:editable (not disabled?)
|
:editable (not disabled?)
|
||||||
:keyboard-appearance (colors/theme-colors :light :dark theme)
|
:keyboard-appearance (colors/theme-colors :light :dark theme)
|
||||||
:keyboard-type :web-search
|
:keyboard-type :web-search
|
||||||
:on-blur (fn []
|
:on-blur on-blur
|
||||||
(set-default)
|
:on-change-text on-change-text
|
||||||
(when on-blur (on-blur)))
|
:on-focus on-focus
|
||||||
:on-change-text (fn [new-text]
|
:placeholder-text-color (placeholder-color state blur? theme)
|
||||||
(set-value new-text)
|
:ref on-ref
|
||||||
(when on-change-text (on-change-text new-text)))
|
|
||||||
:on-focus (fn []
|
|
||||||
(set-active)
|
|
||||||
(when on-focus (on-focus)))
|
|
||||||
:placeholder-text-color (placeholder-color @state blur? theme)
|
|
||||||
:ref (fn [r]
|
|
||||||
(reset! ref r)
|
|
||||||
(when get-ref (get-ref r)))
|
|
||||||
:selection-color (when platform/ios?
|
:selection-color (when platform/ios?
|
||||||
(cursor-color customization-color theme))
|
(cursor-color customization-color theme))
|
||||||
:select-text-on-focus true
|
:select-text-on-focus true
|
||||||
:style (style/input disabled?)})]
|
:style (style/input disabled?)})]
|
||||||
(when (seq @value)
|
(when (seq value)
|
||||||
[clear-button
|
[clear-button
|
||||||
{:blur? blur?
|
{:blur? blur?
|
||||||
:on-press (fn []
|
:on-press on-clear
|
||||||
(clear-input)
|
:theme theme}])]]))
|
||||||
(when on-clear (on-clear)))
|
|
||||||
:theme theme}])]]))))
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
[quo.foundations.customization-colors :as customization-colors]
|
[quo.foundations.customization-colors :as customization-colors]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[react-native.blur :as blur]
|
[react-native.blur :as blur]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- button-internal
|
(defn button
|
||||||
"with label
|
"with label
|
||||||
[button opts \"label\"]
|
[button opts \"label\"]
|
||||||
opts
|
opts
|
||||||
|
@ -29,34 +28,37 @@
|
||||||
:theme :light/:dark
|
:theme :light/:dark
|
||||||
only icon
|
only icon
|
||||||
[button {:icon-only? true} :i/close-circle]"
|
[button {:icon-only? true} :i/close-circle]"
|
||||||
[_ _]
|
|
||||||
(let [pressed-state? (reagent/atom false)]
|
|
||||||
(fn
|
|
||||||
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
|
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
|
||||||
customization-color theme accessibility-label icon-only? container-style inner-style
|
customization-color accessibility-label icon-only? container-style inner-style
|
||||||
pressed? on-press-in on-press-out allow-multiple-presses?]
|
pressed? on-press-in on-press-out allow-multiple-presses?]
|
||||||
:or {type :primary
|
:or {type :primary
|
||||||
size 40
|
size 40
|
||||||
customization-color (if (= type :primary) :blue nil)}}
|
customization-color (if (= type :primary) :blue nil)}}
|
||||||
children]
|
children]
|
||||||
(let [{:keys [icon-color background-color label-color border-color blur-type
|
(let [[pressed-state? set-pressed-state] (rn/use-state false)
|
||||||
|
theme (theme/use-theme-value)
|
||||||
|
{:keys [icon-color background-color label-color border-color blur-type
|
||||||
blur-overlay-color border-radius overlay-customization-color]}
|
blur-overlay-color border-radius overlay-customization-color]}
|
||||||
(button-properties/get-values {:customization-color customization-color
|
(button-properties/get-values {:customization-color customization-color
|
||||||
:background background
|
:background background
|
||||||
:type type
|
:type type
|
||||||
:theme theme
|
:theme theme
|
||||||
:pressed? (if pressed? pressed? @pressed-state?)
|
:pressed? (if pressed? pressed? pressed-state?)
|
||||||
:icon-only? icon-only?})
|
:icon-only? icon-only?})
|
||||||
icon-size (when (= 24 size) 12)]
|
icon-size (when (= 24 size) 12)
|
||||||
|
on-press-in-cb (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-pressed-state true)
|
||||||
|
(when on-press-in (on-press-in))))
|
||||||
|
on-press-out-cb (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-pressed-state nil)
|
||||||
|
(when on-press-out (on-press-out))))]
|
||||||
[rn/touchable-without-feedback
|
[rn/touchable-without-feedback
|
||||||
{:disabled disabled?
|
{:disabled disabled?
|
||||||
:accessibility-label accessibility-label
|
:accessibility-label accessibility-label
|
||||||
:on-press-in (fn []
|
:on-press-in on-press-in-cb
|
||||||
(reset! pressed-state? true)
|
:on-press-out on-press-out-cb
|
||||||
(when on-press-in (on-press-in)))
|
|
||||||
:on-press-out (fn []
|
|
||||||
(reset! pressed-state? nil)
|
|
||||||
(when on-press-out (on-press-out)))
|
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:allow-multiple-presses? allow-multiple-presses?
|
:allow-multiple-presses? allow-multiple-presses?
|
||||||
:on-long-press on-long-press}
|
:on-long-press on-long-press}
|
||||||
|
@ -80,7 +82,7 @@
|
||||||
[customization-colors/overlay
|
[customization-colors/overlay
|
||||||
{:customization-color overlay-customization-color
|
{:customization-color overlay-customization-color
|
||||||
:theme theme
|
:theme theme
|
||||||
:pressed? (if pressed? pressed? @pressed-state?)}])
|
:pressed? (if pressed? pressed? pressed-state?)}])
|
||||||
(when (= background :photo)
|
(when (= background :photo)
|
||||||
[blur/view
|
[blur/view
|
||||||
{:blur-radius 20
|
{:blur-radius 20
|
||||||
|
@ -125,6 +127,4 @@
|
||||||
:icon-size icon-size})}
|
:icon-size icon-size})}
|
||||||
[quo.icons/icon icon-right
|
[quo.icons/icon icon-right
|
||||||
{:color icon-color
|
{:color icon-color
|
||||||
:size icon-size}]])]]]))))
|
:size icon-size}]])]]]))
|
||||||
|
|
||||||
(def button (theme/with-theme button-internal))
|
|
||||||
|
|
|
@ -3,28 +3,24 @@
|
||||||
[quo.components.buttons.composer-button.style :as style]
|
[quo.components.buttons.composer-button.style :as style]
|
||||||
[quo.components.icon :as quo.icons]
|
[quo.components.icon :as quo.icons]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[_ _]
|
[{:keys [on-press on-long-press disabled? blur? icon accessibility-label container-style]}]
|
||||||
(let [pressed? (reagent/atom false)]
|
(let [[pressed? set-pressed] (rn/use-state false)
|
||||||
(fn
|
theme (theme/use-theme-value)
|
||||||
[{:keys [on-press on-long-press disabled? theme blur? icon accessibility-label container-style]}]
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
|
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:accessibility-label (or accessibility-label :composer-button)
|
{:accessibility-label (or accessibility-label :composer-button)
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:on-press-in #(reset! pressed? true)
|
:on-press-in on-press-in
|
||||||
:on-press-out #(reset! pressed? nil)
|
:on-press-out on-press-out
|
||||||
:on-long-press on-long-press
|
:on-long-press on-long-press
|
||||||
:disabled disabled?
|
:disabled disabled?
|
||||||
:style (merge (style/main {:pressed? @pressed?
|
:style (merge (style/main {:pressed? pressed?
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:theme theme
|
:theme theme
|
||||||
:disabled? disabled?})
|
:disabled? disabled?})
|
||||||
container-style)}
|
container-style)}
|
||||||
[quo.icons/icon icon
|
[quo.icons/icon icon {:color (style/get-label-color {:blur? blur? :theme theme})}]]))
|
||||||
{:color (style/get-label-color {:blur? blur?
|
|
||||||
:theme theme})}]])))
|
|
||||||
|
|
||||||
(def view (theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- get-button-color
|
(defn- get-button-color
|
||||||
[{:keys [type pressed? customization-color theme]}]
|
[{:keys [type pressed? customization-color theme]}]
|
||||||
|
@ -45,19 +44,25 @@
|
||||||
:color (get-icon-and-text-color type theme)
|
:color (get-icon-and-text-color type theme)
|
||||||
:container-style (style/container type)}])
|
:container-style (style/container type)}])
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
"[dynamic-button opts]
|
"[dynamic-button opts]
|
||||||
opts
|
opts
|
||||||
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
|
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
|
||||||
:on-press fn
|
:on-press fn
|
||||||
:count mentions or notifications count
|
:count mentions or notifications count
|
||||||
:customization-color customize jump-to and mention button color}"
|
:customization-color customize jump-to and mention button color}"
|
||||||
[_]
|
[{:keys [type label on-press customization-color style] :as args}]
|
||||||
(let [pressed? (reagent/atom false)]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
(fn [{:keys [type label on-press customization-color style theme] :as args}]
|
[pressed? set-pressed] (rn/use-state false)
|
||||||
|
button-color (get-button-color {:type type
|
||||||
|
:pressed? pressed?
|
||||||
|
:customization-color (or customization-color :primary)
|
||||||
|
:theme theme})
|
||||||
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
|
on-press-out (rn/use-callback #(set-pressed false))]
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:on-press-in #(reset! pressed? true)
|
{:on-press-in on-press-in
|
||||||
:on-press-out #(reset! pressed? false)
|
:on-press-out on-press-out
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:active-opacity 1
|
:active-opacity 1
|
||||||
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
|
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
|
||||||
|
@ -69,11 +74,7 @@
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:height 24
|
:height 24
|
||||||
:border-radius 12
|
:border-radius 12
|
||||||
:background-color (get-button-color {:type type
|
:background-color button-color}
|
||||||
:pressed? @pressed?
|
|
||||||
:customization-color (or customization-color
|
|
||||||
:primary)
|
|
||||||
:theme theme})}
|
|
||||||
style)}
|
style)}
|
||||||
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
|
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
|
||||||
[icon-view type])
|
[icon-view type])
|
||||||
|
@ -87,6 +88,4 @@
|
||||||
:search-with-label label
|
:search-with-label label
|
||||||
(:mention :notification-down :notification-up) (str (:count args)))])
|
(:mention :notification-down :notification-up) (str (:count args)))])
|
||||||
(when (#{:jump-to :notification-down :notification-up} type)
|
(when (#{:jump-to :notification-down :notification-up} type)
|
||||||
[icon-view type theme])]])))
|
[icon-view type theme])]]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -6,16 +6,14 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[_]
|
[{:keys [on-press on-long-press disabled? container-style]}]
|
||||||
(let [pressed? (reagent/atom false)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
on-press-in #(reset! pressed? true)
|
[pressed? set-pressed] (rn/use-state false)
|
||||||
on-press-out #(reset! pressed? nil)]
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
(fn
|
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||||
[{:keys [on-press on-long-press disabled? theme container-style]}]
|
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:accessibility-label :log-out-button
|
{:accessibility-label :log-out-button
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
|
@ -23,12 +21,10 @@
|
||||||
:on-press-out on-press-out
|
:on-press-out on-press-out
|
||||||
:on-long-press on-long-press
|
:on-long-press on-long-press
|
||||||
:disabled disabled?
|
:disabled disabled?
|
||||||
:style (merge (style/main {:pressed? @pressed?
|
:style (merge (style/main {:pressed? pressed?
|
||||||
:theme theme
|
:theme theme
|
||||||
:disabled? disabled?})
|
:disabled? disabled?})
|
||||||
container-style)}
|
container-style)}
|
||||||
[icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}]
|
[icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}]
|
||||||
[text/text {:weight :medium :size :paragraph-1}
|
[text/text {:weight :medium :size :paragraph-1}
|
||||||
(i18n/label :t/logout)]])))
|
(i18n/label :t/logout)]]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
(ns quo.components.buttons.slide-button.animations
|
(ns quo.components.buttons.slide-button.animations
|
||||||
(:require
|
(:require [react-native.reanimated :as reanimated]))
|
||||||
[oops.core :as oops]
|
|
||||||
[quo.components.buttons.slide-button.utils :as utils]
|
|
||||||
[react-native.gesture :as gesture]
|
|
||||||
[react-native.reanimated :as reanimated]))
|
|
||||||
|
|
||||||
(def ^:private extrapolation
|
(def ^:private extrapolation
|
||||||
{:extrapolateLeft "clamp"
|
{:extrapolateLeft "clamp"
|
||||||
|
@ -66,36 +62,6 @@
|
||||||
:damping 30
|
:damping 30
|
||||||
:stiffness 400}))
|
:stiffness 400}))
|
||||||
|
|
||||||
(defn- complete-animation
|
|
||||||
[sliding-complete?]
|
|
||||||
(reset! sliding-complete? true))
|
|
||||||
|
|
||||||
(defn reset-track-position
|
(defn reset-track-position
|
||||||
[x-pos]
|
[x-pos]
|
||||||
(animate-spring x-pos 0))
|
(animate-spring x-pos 0))
|
||||||
|
|
||||||
;; Gestures
|
|
||||||
(defn drag-gesture
|
|
||||||
[x-pos
|
|
||||||
gestures-disabled?
|
|
||||||
disabled?
|
|
||||||
track-width
|
|
||||||
sliding-complete?]
|
|
||||||
(let [gestures-enabled? (not (or disabled? @gestures-disabled?))]
|
|
||||||
(-> (gesture/gesture-pan)
|
|
||||||
(gesture/with-test-ID :slide-button-gestures)
|
|
||||||
(gesture/enabled gestures-enabled?)
|
|
||||||
(gesture/min-distance 0)
|
|
||||||
(gesture/on-update (fn [event]
|
|
||||||
(let [x-translation (oops/oget event "translationX")
|
|
||||||
clamped-x (utils/clamp-value x-translation 0 track-width)
|
|
||||||
reached-end? (>= clamped-x track-width)]
|
|
||||||
(reanimated/set-shared-value x-pos clamped-x)
|
|
||||||
(when (and reached-end? (not @sliding-complete?))
|
|
||||||
(reset! gestures-disabled? true)
|
|
||||||
(complete-animation sliding-complete?)))))
|
|
||||||
(gesture/on-end (fn [event]
|
|
||||||
(let [x-translation (oops/oget event "translationX")
|
|
||||||
reached-end? (>= x-translation track-width)]
|
|
||||||
(when (not reached-end?)
|
|
||||||
(reset-track-position x-pos))))))))
|
|
||||||
|
|
|
@ -11,54 +11,83 @@
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- f-slider
|
(defn drag-gesture
|
||||||
[{:keys [disabled?]}]
|
[x-pos gestures-disabled? set-gestures-disabled disabled? track-width sliding-complete?
|
||||||
(let [track-width (reagent/atom nil)
|
set-sliding-complete
|
||||||
sliding-complete? (reagent/atom false)
|
on-complete reset-fn]
|
||||||
gestures-disabled? (reagent/atom disabled?)
|
(let [gestures-enabled? (not (or disabled? gestures-disabled?))]
|
||||||
on-track-layout (fn [evt]
|
(-> (gesture/gesture-pan)
|
||||||
(let [width (oops/oget evt "nativeEvent.layout.width")]
|
(gesture/with-test-ID :slide-button-gestures)
|
||||||
(reset! track-width width)))]
|
(gesture/enabled gestures-enabled?)
|
||||||
(fn [{:keys [on-reset
|
(gesture/min-distance 0)
|
||||||
on-complete
|
(gesture/on-update (fn [event]
|
||||||
track-text
|
(let [x-translation (oops/oget event "translationX")
|
||||||
track-icon
|
clamped-x (utils/clamp-value x-translation 0 track-width)
|
||||||
disabled?
|
reached-end? (>= clamped-x track-width)]
|
||||||
customization-color
|
(reanimated/set-shared-value x-pos clamped-x)
|
||||||
size
|
(when (and reached-end? (not sliding-complete?))
|
||||||
container-style
|
(set-gestures-disabled true)
|
||||||
theme
|
(set-sliding-complete true)
|
||||||
type
|
(when on-complete (on-complete reset-fn))))))
|
||||||
blur?]}]
|
(gesture/on-end (fn [event]
|
||||||
(let [x-pos (reanimated/use-shared-value 0)
|
(let [x-translation (oops/oget event "translationX")
|
||||||
dimensions (partial utils/get-dimensions
|
reached-end? (>= x-translation track-width)]
|
||||||
(or @track-width constants/default-width)
|
(when (not reached-end?)
|
||||||
|
(animations/reset-track-position x-pos))))))))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
"Options
|
||||||
|
- `on-complete` Callback called when the sliding is complete, returns reset fn as a parameter
|
||||||
|
- `disabled?` Boolean that disables the button
|
||||||
|
(_and gestures_)
|
||||||
|
- `size` :size/s-40`/`:size/s-48`
|
||||||
|
- `track-text` Text that is shown on the track
|
||||||
|
- `track-icon` Key of the icon shown on the track
|
||||||
|
(e.g. `:face-id`)
|
||||||
|
- `customization-color` Customization color
|
||||||
|
"
|
||||||
|
[{:keys [on-complete track-text track-icon disabled? customization-color size
|
||||||
|
container-style type blur?]}]
|
||||||
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
x-pos (reanimated/use-shared-value 0)
|
||||||
|
[track-width set-track-width] (rn/use-state nil)
|
||||||
|
[sliding-complete?
|
||||||
|
set-sliding-complete] (rn/use-state false)
|
||||||
|
[gestures-disabled?
|
||||||
|
set-gestures-disabled] (rn/use-state disabled?)
|
||||||
|
on-track-layout (rn/use-callback
|
||||||
|
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
|
||||||
|
reset-fn (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-sliding-complete false)
|
||||||
|
(set-gestures-disabled false)
|
||||||
|
(animations/reset-track-position x-pos)))
|
||||||
|
dimensions (rn/use-callback
|
||||||
|
(partial utils/get-dimensions
|
||||||
|
(or track-width constants/default-width)
|
||||||
size)
|
size)
|
||||||
interpolate-track (partial animations/interpolate-track
|
[track-width])
|
||||||
|
interpolate-track (rn/use-callback
|
||||||
|
(partial animations/interpolate-track
|
||||||
x-pos
|
x-pos
|
||||||
(dimensions :usable-track)
|
(dimensions :usable-track)
|
||||||
(dimensions :thumb))
|
(dimensions :thumb))
|
||||||
custom-color (if (= type :danger) :danger customization-color)]
|
[dimensions])
|
||||||
(rn/use-effect (fn []
|
custom-color (if (= type :danger) :danger customization-color)
|
||||||
(when @sliding-complete?
|
gesture (rn/use-memo #(drag-gesture x-pos
|
||||||
(on-complete)))
|
|
||||||
[@sliding-complete?])
|
|
||||||
(rn/use-effect (fn []
|
|
||||||
(when on-reset
|
|
||||||
(reset! sliding-complete? false)
|
|
||||||
(reset! gestures-disabled? false)
|
|
||||||
(animations/reset-track-position x-pos)
|
|
||||||
(on-reset)))
|
|
||||||
[on-reset])
|
|
||||||
[gesture/gesture-detector
|
|
||||||
{:gesture (animations/drag-gesture x-pos
|
|
||||||
gestures-disabled?
|
gestures-disabled?
|
||||||
|
set-gestures-disabled
|
||||||
disabled?
|
disabled?
|
||||||
(dimensions :usable-track)
|
(dimensions :usable-track)
|
||||||
sliding-complete?)}
|
sliding-complete?
|
||||||
|
set-sliding-complete
|
||||||
|
on-complete
|
||||||
|
reset-fn)
|
||||||
|
[gestures-disabled? sliding-complete? disabled?])]
|
||||||
|
[gesture/gesture-detector
|
||||||
|
{:gesture gesture}
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:test-ID :slide-button-track
|
{:test-ID :slide-button-track
|
||||||
:style (merge (style/track {:disabled? disabled?
|
:style (merge (style/track {:disabled? disabled?
|
||||||
|
@ -66,10 +95,9 @@
|
||||||
:height (dimensions :track-height)
|
:height (dimensions :track-height)
|
||||||
:blur? blur?})
|
:blur? blur?})
|
||||||
container-style)
|
container-style)
|
||||||
:on-layout (when-not (some? @track-width)
|
:on-layout on-track-layout}
|
||||||
on-track-layout)}
|
|
||||||
[reanimated/view {:style (style/track-cover interpolate-track)}
|
[reanimated/view {:style (style/track-cover interpolate-track)}
|
||||||
[rn/view {:style (style/track-cover-text-container @track-width)}
|
[rn/view {:style (style/track-cover-text-container track-width)}
|
||||||
[icon/icon track-icon
|
[icon/icon track-icon
|
||||||
{:color (utils/text-color custom-color theme blur?)
|
{:color (utils/text-color custom-color theme blur?)
|
||||||
:size 20}]
|
:size 20}]
|
||||||
|
@ -90,25 +118,7 @@
|
||||||
{:color colors/white
|
{:color colors/white
|
||||||
:size 20}]]
|
:size 20}]]
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/action-icon interpolate-track
|
{:style (style/action-icon interpolate-track (dimensions :thumb))}
|
||||||
(dimensions :thumb))}
|
|
||||||
[icon/icon track-icon
|
[icon/icon track-icon
|
||||||
{:color colors/white
|
{:color colors/white
|
||||||
:size 20}]]]]]))))
|
:size 20}]]]]]))
|
||||||
|
|
||||||
(defn- view-internal
|
|
||||||
"Options
|
|
||||||
- `on-complete` Callback called when the sliding is complete
|
|
||||||
- `disabled?` Boolean that disables the button
|
|
||||||
(_and gestures_)
|
|
||||||
- `size` :size/s-40`/`:size/s-48`
|
|
||||||
- `track-text` Text that is shown on the track
|
|
||||||
- `track-icon` Key of the icon shown on the track
|
|
||||||
(e.g. `:face-id`)
|
|
||||||
- `customization-color` Customization color
|
|
||||||
- `on-reset` A callback which can be used to reset the component and run required functionality
|
|
||||||
"
|
|
||||||
[props]
|
|
||||||
[:f> f-slider props])
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -4,26 +4,24 @@
|
||||||
[quo.components.icon :as quo.icons]
|
[quo.components.icon :as quo.icons]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[]
|
[{:keys [on-press on-long-press disabled? icon accessibility-label container-style]}]
|
||||||
(let [pressed? (reagent/atom false)]
|
(let [theme (theme/use-theme-value)
|
||||||
(fn
|
[pressed? set-pressed] (rn/use-state false)
|
||||||
[{:keys [on-press on-long-press disabled? icon accessibility-label container-style theme]}]
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
|
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:accessibility-label (or accessibility-label :wallet-button)
|
{:accessibility-label (or accessibility-label :wallet-button)
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:on-press-in #(reset! pressed? true)
|
:on-press-in on-press-in
|
||||||
:on-press-out #(reset! pressed? nil)
|
:on-press-out on-press-out
|
||||||
:on-long-press on-long-press
|
:on-long-press on-long-press
|
||||||
:disabled disabled?
|
:disabled disabled?
|
||||||
:style (merge (style/main {:pressed? @pressed?
|
:style (merge (style/main {:pressed? pressed?
|
||||||
:theme theme
|
:theme theme
|
||||||
:disabled? disabled?})
|
:disabled? disabled?})
|
||||||
container-style)}
|
container-style)}
|
||||||
[quo.icons/icon icon
|
[quo.icons/icon icon
|
||||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)}]])))
|
{:color (colors/theme-colors colors/neutral-100 colors/white theme)}]]))
|
||||||
|
|
||||||
(def view (theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[react-native.hooks :as hooks]
|
[react-native.hooks :as hooks]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.common.bottom-sheet.style :as style]
|
[status-im.common.bottom-sheet.style :as style]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -57,15 +56,15 @@
|
||||||
(show translate-y bg-opacity)
|
(show translate-y bg-opacity)
|
||||||
(hide translate-y bg-opacity window-height on-close))))))
|
(hide translate-y bg-opacity window-height on-close))))))
|
||||||
|
|
||||||
(defn- f-view
|
(defn view
|
||||||
[_ _]
|
[{:keys [hide? insets]}
|
||||||
(let [sheet-height (reagent/atom 0)
|
|
||||||
item-height (reagent/atom 0)]
|
|
||||||
(fn [{:keys [hide? insets theme]}
|
|
||||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||||
gradient-cover? customization-color hide-handle? blur-radius]
|
gradient-cover? customization-color hide-handle? blur-radius]
|
||||||
:or {border-radius 12}}]
|
:or {border-radius 12}}]
|
||||||
(let [{window-height :height} (rn/get-window)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
sheet-height (rn/use-ref-atom 0)
|
||||||
|
item-height (rn/use-ref-atom 0)
|
||||||
|
{window-height :height} (rn/get-window)
|
||||||
bg-opacity (reanimated/use-shared-value 0)
|
bg-opacity (reanimated/use-shared-value 0)
|
||||||
translate-y (reanimated/use-shared-value window-height)
|
translate-y (reanimated/use-shared-value window-height)
|
||||||
sheet-gesture (get-sheet-gesture translate-y
|
sheet-gesture (get-sheet-gesture translate-y
|
||||||
|
@ -130,10 +129,4 @@
|
||||||
:opacity 0.4}]])
|
:opacity 0.4}]])
|
||||||
(when-not hide-handle?
|
(when-not hide-handle?
|
||||||
[quo/drawer-bar])
|
[quo/drawer-bar])
|
||||||
[content]]]]]))))
|
[content]]]]]))
|
||||||
|
|
||||||
(defn- internal-view
|
|
||||||
[args sheet]
|
|
||||||
[:f> f-view args sheet])
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme internal-view))
|
|
||||||
|
|
|
@ -3,45 +3,32 @@
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.common.standard-authentication.standard-auth.authorize :as authorize]
|
[status-im.common.standard-authentication.standard-auth.authorize :as authorize]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[_]
|
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
||||||
(let [reset-slider? (reagent/atom false)
|
auth-button-icon-left size blur? container-style]
|
||||||
on-close (fn []
|
|
||||||
(js/setTimeout
|
|
||||||
#(reset! reset-slider? true)
|
|
||||||
200))
|
|
||||||
auth-method (rf/sub [:auth-method])
|
|
||||||
biometric-auth? (= auth-method constants/auth-method-biometric)]
|
|
||||||
(fn [{:keys [track-text
|
|
||||||
customization-color
|
|
||||||
auth-button-label
|
|
||||||
on-auth-success
|
|
||||||
on-auth-fail
|
|
||||||
auth-button-icon-left
|
|
||||||
size
|
|
||||||
theme
|
|
||||||
blur?
|
|
||||||
container-style]
|
|
||||||
:or {container-style {:flex 1}}}]
|
:or {container-style {:flex 1}}}]
|
||||||
[rn/view {:style container-style}
|
(let [theme (quo.theme/use-theme-value)
|
||||||
[quo/slide-button
|
auth-method (rf/sub [:auth-method])
|
||||||
{:size size
|
biometric-auth? (= auth-method constants/auth-method-biometric)
|
||||||
:customization-color customization-color
|
on-complete (rn/use-callback
|
||||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
(fn [reset]
|
||||||
:on-complete #(authorize/authorize {:on-close on-close
|
(authorize/authorize {:on-close #(js/setTimeout reset 200)
|
||||||
:auth-button-icon-left auth-button-icon-left
|
:auth-button-icon-left auth-button-icon-left
|
||||||
:theme theme
|
:theme theme
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:biometric-auth? biometric-auth?
|
:biometric-auth? biometric-auth?
|
||||||
:on-auth-success on-auth-success
|
:on-auth-success on-auth-success
|
||||||
:on-auth-fail on-auth-fail
|
:on-auth-fail on-auth-fail
|
||||||
:auth-button-label auth-button-label})
|
:auth-button-label auth-button-label}))
|
||||||
|
[theme])]
|
||||||
|
[quo/slide-button
|
||||||
|
{:container-style container-style
|
||||||
|
:size size
|
||||||
|
:customization-color customization-color
|
||||||
|
:on-complete on-complete
|
||||||
:track-icon (if biometric-auth? :i/face-id :password)
|
:track-icon (if biometric-auth? :i/face-id :password)
|
||||||
:track-text track-text}]])))
|
:track-text track-text}]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
:disabled? (:disabled? @state)
|
:disabled? (:disabled? @state)
|
||||||
:blur? @blur?
|
:blur? @blur?
|
||||||
:type (:type @state)
|
:type (:type @state)
|
||||||
:on-complete (fn []
|
:on-complete (fn [_]
|
||||||
(js/setTimeout (fn [] (reset! complete? true))
|
(js/setTimeout (fn [] (reset! complete? true))
|
||||||
1000)
|
1000)
|
||||||
(js/alert "I don't wanna slide anymore"))}]
|
(js/alert "I don't wanna slide anymore"))}]
|
||||||
|
|
Loading…
Reference in New Issue