mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-22 13:28:45 +00:00
migrate reagent part6 (#19270)
This commit is contained in:
parent
3164cc6a6c
commit
cfc43be3cc
@ -9,11 +9,10 @@
|
|||||||
[quo.components.tags.status-tags :as status-tags]
|
[quo.components.tags.status-tags :as status-tags]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(defn- activity-reply-text-input
|
(defn- activity-reply-text-input
|
||||||
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input]
|
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input set-reply-input]
|
||||||
[rn/view
|
[rn/view
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style {:margin-top 16
|
{:style {:margin-top 16
|
||||||
@ -26,12 +25,12 @@
|
|||||||
(i18n/label :t/your-answer)]
|
(i18n/label :t/your-answer)]
|
||||||
[text/text
|
[text/text
|
||||||
{:style {:flex-shrink 1
|
{:style {:flex-shrink 1
|
||||||
:color (if (valid-reply? @reply-input)
|
:color (if (valid-reply? reply-input)
|
||||||
colors/neutral-40
|
colors/neutral-40
|
||||||
colors/danger-60)}}
|
colors/danger-60)}}
|
||||||
(str (count @reply-input) "/" max-reply-length)]]
|
(str (count reply-input) "/" max-reply-length)]]
|
||||||
[input/input
|
[input/input
|
||||||
{:on-change-text #(do (reset! reply-input %)
|
{:on-change-text #(do (set-reply-input %)
|
||||||
(when on-update-reply
|
(when on-update-reply
|
||||||
(on-update-reply %)))
|
(on-update-reply %)))
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
@ -136,7 +135,7 @@
|
|||||||
(-> button
|
(-> button
|
||||||
(assoc :size size)
|
(assoc :size size)
|
||||||
(assoc :type subtype)
|
(assoc :type subtype)
|
||||||
(assoc :disabled? (and replying? disable-when (disable-when @reply-input)))
|
(assoc :disabled? (and replying? disable-when (disable-when reply-input)))
|
||||||
(assoc :inner-style
|
(assoc :inner-style
|
||||||
{:justify-content :center
|
{:justify-content :center
|
||||||
:padding-bottom 0
|
:padding-bottom 0
|
||||||
@ -153,17 +152,16 @@
|
|||||||
:blur? blur?}])
|
:blur? blur?}])
|
||||||
|
|
||||||
(defn- footer
|
(defn- footer
|
||||||
[_]
|
[{:keys [replying? items] :as props}]
|
||||||
(let [reply-input (reagent/atom "")]
|
(let [[reply-input set-reply-input] (rn/use-state "")]
|
||||||
(fn [{:keys [replying? items] :as props}]
|
[:<>
|
||||||
[:<>
|
(when replying?
|
||||||
(when replying?
|
[activity-reply-text-input props reply-input set-reply-input])
|
||||||
[activity-reply-text-input props reply-input])
|
(when items
|
||||||
(when items
|
[rn/view style/footer-container
|
||||||
[rn/view style/footer-container
|
(for [item items]
|
||||||
(for [item items]
|
^{:key (:key item)}
|
||||||
^{:key (:key item)}
|
[footer-item-view item replying? reply-input])])]))
|
||||||
[footer-item-view item replying? reply-input])])])))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [icon
|
[{:keys [icon
|
||||||
|
@ -4,8 +4,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.svg :as svg]
|
[react-native.svg :as svg]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- get-path-props
|
(defn- get-path-props
|
||||||
[size stroke-width rotation]
|
[size stroke-width rotation]
|
||||||
@ -49,60 +48,53 @@
|
|||||||
{:color {:dark colors/neutral-80-opa-40
|
{:color {:dark colors/neutral-80-opa-40
|
||||||
:light colors/white-opa-40}})
|
:light colors/white-opa-40}})
|
||||||
|
|
||||||
(defn- circle-timer-internal
|
(defn circle-timer
|
||||||
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time theme]}]
|
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time]}]
|
||||||
(let [rotation (or rotation :clockwise)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
duration (or duration 4)
|
rotation (or rotation :clockwise)
|
||||||
stroke-width (or stroke-width 1)
|
duration (or duration 4)
|
||||||
size (or size 9)
|
stroke-width (or stroke-width 1)
|
||||||
max-stroke-width (max stroke-width 0)
|
size (or size 9)
|
||||||
{:keys [path path-length]} (get-path-props size max-stroke-width rotation)
|
max-stroke-width (max stroke-width 0)
|
||||||
start-at (get-start-at duration initial-remaining-time)
|
{:keys [path path-length]} (get-path-props size max-stroke-width rotation)
|
||||||
elapsed-time (reagent/atom 0)
|
start-at (get-start-at duration initial-remaining-time)
|
||||||
prev-frame-time (reagent/atom nil)
|
elapsed-time (rn/use-ref-atom 0)
|
||||||
frame-request (reagent/atom nil)
|
prev-frame-time (rn/use-ref-atom nil)
|
||||||
display-time (reagent/atom start-at)
|
frame-request (rn/use-ref-atom nil)
|
||||||
;; get elapsed frame time
|
[display-time set-display-time] (rn/use-state start-at)
|
||||||
swap-elapsed-time-each-frame (fn swap-elapsed-time-each-frame [frame-time]
|
swap-elapsed-time-each-frame (fn swap-elapsed-time-each-frame [frame-time]
|
||||||
(if (nil? @prev-frame-time)
|
(if (nil? @prev-frame-time)
|
||||||
(do (reset! prev-frame-time frame-time)
|
(do (reset! prev-frame-time frame-time)
|
||||||
(reset! frame-request (js/requestAnimationFrame
|
(reset! frame-request (js/requestAnimationFrame
|
||||||
swap-elapsed-time-each-frame)))
|
swap-elapsed-time-each-frame)))
|
||||||
(let [delta (- (/ frame-time 1000)
|
(let [delta (- (/ frame-time 1000)
|
||||||
(/ @prev-frame-time 1000))
|
(/ @prev-frame-time 1000))
|
||||||
current-elapsed (swap! elapsed-time + delta)
|
current-elapsed (swap! elapsed-time + delta)
|
||||||
current-display-time (+ start-at current-elapsed)
|
current-display-time (+ start-at current-elapsed)
|
||||||
completed? (>= current-display-time duration)]
|
completed? (>= current-display-time
|
||||||
(reset! display-time (if completed?
|
duration)]
|
||||||
duration
|
(set-display-time
|
||||||
current-display-time))
|
(if completed? duration current-display-time))
|
||||||
(when-not completed?
|
(when-not completed?
|
||||||
(reset! prev-frame-time frame-time)
|
(reset! prev-frame-time frame-time)))))]
|
||||||
(reset! frame-request (js/requestAnimationFrame
|
(rn/use-effect #(reset! frame-request (js/requestAnimationFrame swap-elapsed-time-each-frame)))
|
||||||
swap-elapsed-time-each-frame))))))]
|
(rn/use-unmount #(js/cancelAnimationFrame @frame-request))
|
||||||
(reagent/create-class
|
[rn/view
|
||||||
{:component-will-unmount #(js/cancelAnimationFrame @frame-request)
|
{:style {:position :relative
|
||||||
:reagent-render
|
:width size
|
||||||
(fn []
|
:height size}}
|
||||||
(reset! frame-request (js/requestAnimationFrame swap-elapsed-time-each-frame))
|
[svg/svg
|
||||||
[rn/view
|
{:view-box (str "0 0 " size " " size)
|
||||||
{:style {:position :relative
|
:width size
|
||||||
:width size
|
:height size}
|
||||||
:height size}}
|
[svg/path
|
||||||
[svg/svg
|
{:d path :fill :none :stroke (or trail-color :transparent) :stroke-width stroke-width}]
|
||||||
{:view-box (str "0 0 " size " " size)
|
(when-not (= display-time duration)
|
||||||
:width size
|
[svg/path
|
||||||
:height size}
|
{:d path
|
||||||
[svg/path
|
:fill :none
|
||||||
{:d path :fill :none :stroke (or trail-color :transparent) :stroke-width stroke-width}]
|
:stroke (or color (get-in themes [:color theme]))
|
||||||
(when-not (= @display-time duration)
|
:stroke-linecap :square
|
||||||
[svg/path
|
:stroke-width stroke-width
|
||||||
{:d path
|
:stroke-dasharray path-length
|
||||||
:fill :none
|
:stroke-dashoffset (linear-ease display-time 0 path-length duration)}])]]))
|
||||||
:stroke (or color (get-in themes [:color theme]))
|
|
||||||
:stroke-linecap :square
|
|
||||||
:stroke-width stroke-width
|
|
||||||
:stroke-dasharray path-length
|
|
||||||
:stroke-dashoffset (linear-ease @display-time 0 path-length duration)}])]])})))
|
|
||||||
|
|
||||||
(def circle-timer (quo.theme/with-theme circle-timer-internal))
|
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
[rn/touchable-highlight
|
[rn/touchable-highlight
|
||||||
{:on-press on-press
|
{:on-press on-press
|
||||||
:underlay-color :transparent}
|
:underlay-color :transparent}
|
||||||
[into
|
(into
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge (style/action-container theme) style)}]
|
{:style (merge (style/action-container theme) style)}]
|
||||||
children]])
|
children)])
|
||||||
|
|
||||||
(defn toast-undo-action-internal
|
(defn toast-undo-action-internal
|
||||||
[{:keys [undo-duration undo-on-press theme]}]
|
[{:keys [undo-duration undo-on-press theme]}]
|
||||||
|
@ -3,23 +3,20 @@
|
|||||||
[quo.components.icon :as icon]
|
[quo.components.icon :as icon]
|
||||||
[quo.components.selectors.filter.style :as style]
|
[quo.components.selectors.filter.style :as style]
|
||||||
[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 view-internal
|
(defn view
|
||||||
[initial-props]
|
[{:keys [blur? customization-color on-press-out pressed?]}]
|
||||||
(let [pressed? (reagent/atom (:pressed? initial-props))]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
(fn [{:keys [blur? customization-color theme on-press-out]}]
|
[pressed? set-pressed] (rn/use-state pressed?)
|
||||||
[rn/touchable-without-feedback
|
on-press-out (fn []
|
||||||
{:accessibility-label :selector-filter
|
(set-pressed (not pressed?))
|
||||||
:on-press-out (fn []
|
(when on-press-out (on-press-out pressed?)))]
|
||||||
(swap! pressed? not)
|
[rn/touchable-without-feedback
|
||||||
(when on-press-out
|
{:accessibility-label :selector-filter
|
||||||
(on-press-out @pressed?)))}
|
:on-press-out on-press-out}
|
||||||
[rn/view {:style (style/container-outer customization-color @pressed? theme)}
|
[rn/view {:style (style/container-outer customization-color pressed? theme)}
|
||||||
[rn/view {:style (style/container-inner @pressed? blur? theme)}
|
[rn/view {:style (style/container-inner pressed? blur? theme)}
|
||||||
[icon/icon :i/unread
|
[icon/icon :i/unread
|
||||||
{:color (style/icon-color @pressed? theme)
|
{:color (style/icon-color pressed? theme)
|
||||||
:size 20}]]]])))
|
:size 20}]]]]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
@ -2,23 +2,20 @@
|
|||||||
(:require
|
(:require
|
||||||
[quo.components.selectors.reaction-resource :as reactions.resource]
|
[quo.components.selectors.reaction-resource :as reactions.resource]
|
||||||
[quo.components.selectors.reactions-selector.style :as style]
|
[quo.components.selectors.reactions-selector.style :as style]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [start-pressed?]}]
|
[{:keys [emoji container-style on-press
|
||||||
(let [pressed? (reagent/atom start-pressed?)]
|
accessibility-label start-pressed?]
|
||||||
(fn [{:keys [emoji container-style on-press
|
:or {accessibility-label :reaction}}]
|
||||||
accessibility-label]
|
(let [[pressed? set-pressed] (rn/use-state start-pressed?)
|
||||||
:or {accessibility-label :reaction}}]
|
on-press (fn [e]
|
||||||
[rn/pressable
|
(set-pressed (not pressed?))
|
||||||
{:accessibility-label accessibility-label
|
(when on-press (on-press e)))]
|
||||||
:allow-multiple-presses? true
|
[rn/pressable
|
||||||
:style (merge (style/container @pressed?)
|
{:accessibility-label accessibility-label
|
||||||
container-style)
|
:allow-multiple-presses? true
|
||||||
:on-press (fn [e]
|
:style (merge (style/container pressed?)
|
||||||
(swap! pressed? not)
|
container-style)
|
||||||
(when on-press
|
:on-press on-press}
|
||||||
(on-press e)))}
|
[rn/text (reactions.resource/system-emojis emoji)]]))
|
||||||
[rn/text
|
|
||||||
(reactions.resource/system-emojis emoji)]])))
|
|
||||||
|
@ -3,47 +3,47 @@
|
|||||||
[quo.components.icon :as icons]
|
[quo.components.icon :as icons]
|
||||||
[quo.components.selectors.selectors.style :as style]
|
[quo.components.selectors.selectors.style :as style]
|
||||||
[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- handle-press
|
|
||||||
[on-change checked-atom checked?]
|
|
||||||
(when checked-atom (swap! checked-atom not))
|
|
||||||
(when on-change (on-change (not checked?))))
|
|
||||||
|
|
||||||
(defn- base-selector
|
(defn- base-selector
|
||||||
[{:keys [default-checked? checked?]}]
|
[{:keys [default-checked? checked? disabled? blur? customization-color on-change container-style
|
||||||
(let [controlled-component? (some? checked?)
|
label-prefix outer-style-fn inner-style-fn icon-style-fn theme]
|
||||||
internal-checked? (when-not controlled-component?
|
:or {customization-color :blue}}]
|
||||||
(reagent/atom (or default-checked? false)))]
|
(let [controlled-component? (some? checked?)
|
||||||
(fn [{:keys [checked? disabled? blur? customization-color on-change container-style
|
[internal-checked?
|
||||||
label-prefix outer-style-fn inner-style-fn icon-style-fn theme]
|
set-internal-checked?] (rn/use-state (when-not controlled-component?
|
||||||
:or {customization-color :blue}}]
|
(or default-checked? false)))
|
||||||
(let [actual-checked? (if controlled-component? checked? @internal-checked?)
|
actual-checked? (if controlled-component? checked? internal-checked?)
|
||||||
accessibility-label (str label-prefix "-" (if actual-checked? "on" "off"))
|
accessibility-label (str label-prefix "-" (if actual-checked? "on" "off"))
|
||||||
test-id (str label-prefix "-component")
|
test-id (str label-prefix "-component")
|
||||||
outer-styles (outer-style-fn {:checked? actual-checked?
|
outer-styles (outer-style-fn {:checked? actual-checked?
|
||||||
:disabled? disabled?
|
:disabled? disabled?
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:container-style container-style
|
:container-style container-style
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:theme theme})]
|
:theme theme})
|
||||||
[rn/pressable
|
on-press (rn/use-callback
|
||||||
(when-not disabled?
|
(fn []
|
||||||
{:on-press #(handle-press on-change internal-checked? actual-checked?)
|
(when-not (nil? internal-checked?)
|
||||||
:allow-multiple-presses? true})
|
(set-internal-checked? (not internal-checked?)))
|
||||||
[rn/view
|
(when on-change (on-change (not actual-checked?))))
|
||||||
{:style outer-styles
|
[internal-checked? actual-checked? on-change])]
|
||||||
:needs-offscreen-alpha-compositing true
|
[rn/pressable
|
||||||
:accessibility-label accessibility-label
|
(when-not disabled?
|
||||||
:testID test-id}
|
{:on-press on-press
|
||||||
[rn/view
|
:allow-multiple-presses? true})
|
||||||
{:style (inner-style-fn {:theme theme
|
[rn/view
|
||||||
:checked? actual-checked?
|
{:style outer-styles
|
||||||
:blur? blur?
|
:needs-offscreen-alpha-compositing true
|
||||||
:customization-color customization-color})}
|
:accessibility-label accessibility-label
|
||||||
(when (and icon-style-fn actual-checked?)
|
:testID test-id}
|
||||||
[icons/icon :i/check-small (icon-style-fn actual-checked? blur? theme)])]]]))))
|
[rn/view
|
||||||
|
{:style (inner-style-fn {:theme theme
|
||||||
|
:checked? actual-checked?
|
||||||
|
:blur? blur?
|
||||||
|
:customization-color customization-color})}
|
||||||
|
(when (and icon-style-fn actual-checked?)
|
||||||
|
[icons/icon :i/check-small (icon-style-fn actual-checked? blur? theme)])]]]))
|
||||||
|
|
||||||
(defn- toggle
|
(defn- toggle
|
||||||
[props]
|
[props]
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
[:options {:optional true} [:maybe [:enum :add :hold]]]
|
[:options {:optional true} [:maybe [:enum :add :hold]]]
|
||||||
[:size {:optional true} [:maybe [:enum :size-24 :size-32]]]
|
[:size {:optional true} [:maybe [:enum :size-24 :size-32]]]
|
||||||
[:blur? {:optional true} [:maybe :boolean]]
|
[:blur? {:optional true} [:maybe :boolean]]
|
||||||
[:theme :schema.common/theme]
|
|
||||||
[:collectible-img-src :schema.common/image-source]
|
[:collectible-img-src :schema.common/image-source]
|
||||||
[:collectible-name :string]
|
[:collectible-name :string]
|
||||||
[:collectible-id :string]]]]
|
[:collectible-id :string]]]]
|
||||||
|
@ -8,52 +8,49 @@
|
|||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.hole-view :as hole-view]
|
[react-native.hole-view :as hole-view]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[schema.core :as schema]))
|
[schema.core :as schema]))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[]
|
[{:keys [options blur? collectible-img-src collectible-name collectible-id] :as props}]
|
||||||
(let [container-width (reagent/atom 0)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
on-layout #(->> (oops/oget % :nativeEvent :layout :width)
|
[container-width
|
||||||
(reset! container-width))]
|
set-container-width] (rn/use-state 0)
|
||||||
(fn [{:keys [options blur? theme collectible-img-src collectible-name collectible-id] :as props}]
|
on-layout (rn/use-callback
|
||||||
(let [size (or (:size props) :size-24)]
|
#(set-container-width (oops/oget % :nativeEvent :layout :width)))
|
||||||
[rn/view
|
size (or (:size props) :size-24)]
|
||||||
{:on-layout on-layout}
|
[rn/view {:on-layout on-layout}
|
||||||
[hole-view/hole-view
|
[hole-view/hole-view
|
||||||
{:holes (if options
|
{:holes (if options
|
||||||
[{:x (- @container-width
|
[{:x (- container-width
|
||||||
(case size
|
(case size
|
||||||
:size-24 10
|
:size-24 10
|
||||||
:size-32 12
|
:size-32 12
|
||||||
nil))
|
nil))
|
||||||
:y (case size
|
:y (case size
|
||||||
:size-24 -6
|
:size-24 -6
|
||||||
:size-32 -4
|
:size-32 -4
|
||||||
nil)
|
nil)
|
||||||
:width 16
|
:width 16
|
||||||
:height 16
|
:height 16
|
||||||
:borderRadius 8}]
|
:borderRadius 8}]
|
||||||
[])}
|
[])}
|
||||||
[rn/view {:style (style/container size options blur? theme)}
|
[rn/view {:style (style/container size options blur? theme)}
|
||||||
[rn/image {:style (style/collectible-img size) :source collectible-img-src}]
|
[rn/image {:style (style/collectible-img size) :source collectible-img-src}]
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:style (style/label theme)}
|
:style (style/label theme)}
|
||||||
collectible-name]
|
collectible-name]
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:margin-left 5
|
:margin-left 5
|
||||||
:style (style/label theme)}
|
:style (style/label theme)}
|
||||||
collectible-id]]]
|
collectible-id]]]
|
||||||
(when options
|
(when options
|
||||||
[rn/view {:style (style/options-icon size)}
|
[rn/view {:style (style/options-icon size)}
|
||||||
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
||||||
{:size 20
|
{:size 20
|
||||||
:no-color true}]])]))))
|
:no-color true}]])]))
|
||||||
|
|
||||||
(def view
|
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||||
(quo.theme/with-theme
|
|
||||||
(schema/instrument #'view-internal component-schema/?schema)))
|
|
||||||
|
@ -50,128 +50,131 @@
|
|||||||
- `fade-end-percentage` Percentage where fading starts relative to the total
|
- `fade-end-percentage` Percentage where fading starts relative to the total
|
||||||
layout width of the `flat-list` data."
|
layout width of the `flat-list` data."
|
||||||
|
|
||||||
[{:keys [default-active fade-end-percentage]
|
[{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-event-throttle
|
||||||
:or {fade-end-percentage 0.8}}]
|
scrollable?
|
||||||
(let [active-tab-id (reagent/atom default-active)
|
scroll-on-press? size type labelled? disabled? blurred? icon-color]
|
||||||
fading (reagent/atom {:fade-end-percentage fade-end-percentage})
|
:or {fade-end-percentage 0.8
|
||||||
flat-list-ref (atom nil)]
|
fade-end? false
|
||||||
(fn
|
scroll-event-throttle 64
|
||||||
[{:keys [data
|
scrollable? false
|
||||||
fade-end-percentage
|
scroll-on-press? false
|
||||||
fade-end?
|
size default-tab-size}
|
||||||
on-change
|
:as props}]
|
||||||
on-scroll
|
(let [[active-tab-id
|
||||||
scroll-event-throttle
|
set-active-tab-id] (rn/use-state default-active)
|
||||||
scrollable?
|
[fading set-fading] (rn/use-state {:fade-end-percentage fade-end-percentage})
|
||||||
scroll-on-press?
|
flat-list-ref (rn/use-ref-atom nil)
|
||||||
size
|
maybe-mask-wrapper (rn/use-memo
|
||||||
type
|
(fn []
|
||||||
labelled?
|
(if fade-end?
|
||||||
disabled?
|
|
||||||
blurred?
|
|
||||||
icon-color]
|
|
||||||
:or {fade-end-percentage fade-end-percentage
|
|
||||||
fade-end? false
|
|
||||||
scroll-event-throttle 64
|
|
||||||
scrollable? false
|
|
||||||
scroll-on-press? false
|
|
||||||
size default-tab-size}
|
|
||||||
:as props}]
|
|
||||||
(let [maybe-mask-wrapper (if fade-end?
|
|
||||||
[masked-view/masked-view
|
[masked-view/masked-view
|
||||||
{:mask-element (reagent/as-element
|
{:mask-element (reagent/as-element
|
||||||
[linear-gradient/linear-gradient
|
[linear-gradient/linear-gradient
|
||||||
{:colors [:black :transparent]
|
{:colors [:black :transparent]
|
||||||
:locations [(get @fading :fade-end-percentage)
|
:locations [(get fading :fade-end-percentage)
|
||||||
1]
|
1]
|
||||||
:start {:x 0 :y 0}
|
:start {:x 0 :y 0}
|
||||||
:end {:x 1 :y 0}
|
:end {:x 1 :y 0}
|
||||||
:pointer-events :none
|
:pointer-events :none
|
||||||
:style {:width "100%"
|
:style {:width "100%"
|
||||||
:height "100%"}}])}]
|
:height "100%"}}])}]
|
||||||
[:<>])]
|
[:<>]))
|
||||||
(if scrollable?
|
[fade-end? fading])
|
||||||
(conj
|
on-scroll (rn/use-context
|
||||||
maybe-mask-wrapper
|
(fn [^js e]
|
||||||
[rn/flat-list
|
(when fade-end?
|
||||||
(merge
|
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
||||||
(dissoc props
|
content-width (oget e "nativeEvent.contentSize.width")
|
||||||
:default-active
|
layout-width (oget e "nativeEvent.layoutMeasurement.width")
|
||||||
:fade-end-percentage
|
new-percentage (calculate-fade-end-percentage
|
||||||
:fade-end?
|
{:offset-x offset-x
|
||||||
:on-change
|
:content-width content-width
|
||||||
:scroll-on-press?
|
:layout-width layout-width
|
||||||
:size)
|
:max-fade-percentage fade-end-percentage})]
|
||||||
(when scroll-on-press?
|
;; Avoid unnecessary re-rendering.
|
||||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
(when (not= new-percentage (get fading :fade-end-percentage))
|
||||||
{:ref #(reset! flat-list-ref %)
|
(set-fading (assoc fading :fade-end-percentage new-percentage)))))
|
||||||
:extra-data (str @active-tab-id)
|
(when on-scroll
|
||||||
:horizontal true
|
(on-scroll e)))
|
||||||
:scroll-event-throttle scroll-event-throttle
|
[fade-end? fading fade-end-percentage])
|
||||||
:shows-horizontal-scroll-indicator false
|
data-count (count data)
|
||||||
:data data
|
style-padding-left (get-in props [:style :padding-left])
|
||||||
:key-fn (comp str :id)
|
render-fn (rn/use-callback
|
||||||
:on-scroll (fn [^js e]
|
(fn [{:keys [id label resource]} index]
|
||||||
(when fade-end?
|
[rn/view
|
||||||
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
{:style {:margin-right (if (= size default-tab-size) 12 8)
|
||||||
content-width (oget e "nativeEvent.contentSize.width")
|
:padding-right (when (= index (dec data-count))
|
||||||
layout-width (oget e "nativeEvent.layoutMeasurement.width")
|
style-padding-left)}}
|
||||||
new-percentage (calculate-fade-end-percentage
|
|
||||||
{:offset-x offset-x
|
[tag/tag
|
||||||
:content-width content-width
|
{:id id
|
||||||
:layout-width layout-width
|
:size size
|
||||||
:max-fade-percentage fade-end-percentage})]
|
:active (= id active-tab-id)
|
||||||
;; Avoid unnecessary re-rendering.
|
:resource resource
|
||||||
(when (not= new-percentage (get @fading :fade-end-percentage))
|
:blurred? blurred?
|
||||||
(swap! fading assoc :fade-end-percentage new-percentage))))
|
:icon-color icon-color
|
||||||
(when on-scroll
|
:disabled? disabled?
|
||||||
(on-scroll e)))
|
:label (if labelled?
|
||||||
:render-fn (fn [{:keys [id label resource]} index]
|
label
|
||||||
[rn/view
|
(when (= type :label) label))
|
||||||
{:style {:margin-right (if (= size default-tab-size) 12 8)
|
:type type
|
||||||
:padding-right (when (= index (dec (count data)))
|
:labelled? labelled?
|
||||||
(get-in props [:style :padding-left]))}}
|
:on-press (fn [id]
|
||||||
[tag/tag
|
(set-active-tab-id id)
|
||||||
{:id id
|
(when scroll-on-press?
|
||||||
:size size
|
(.scrollToIndex ^js @flat-list-ref
|
||||||
:active (= id @active-tab-id)
|
#js
|
||||||
:resource resource
|
{:animated true
|
||||||
:blurred? blurred?
|
:index index
|
||||||
:icon-color icon-color
|
:viewPosition 0.5}))
|
||||||
:disabled? disabled?
|
(when on-change
|
||||||
:label (if labelled?
|
(on-change id)))}]])
|
||||||
label
|
[size default-tab-size data-count style-padding-left active-tab-id blurred?
|
||||||
(when (= type :label) label))
|
icon-color disabled? labelled? type scroll-on-press? on-change])
|
||||||
:type type
|
on-press (rn/use-callback #(do (set-active-tab-id %) (when on-change (on-change %)))
|
||||||
:labelled? labelled?
|
[on-change])
|
||||||
:on-press (fn [id]
|
key-fn (rn/use-callback (comp str :id))
|
||||||
(reset! active-tab-id id)
|
ref (rn/use-callback #(reset! flat-list-ref %))
|
||||||
(when scroll-on-press?
|
clean-props (dissoc props
|
||||||
(.scrollToIndex ^js @flat-list-ref
|
:default-active
|
||||||
#js
|
:fade-end-percentage
|
||||||
{:animated true
|
:fade-end?
|
||||||
:index index
|
:on-change
|
||||||
:viewPosition 0.5}))
|
:scroll-on-press?
|
||||||
(when on-change
|
:size)]
|
||||||
(on-change id)))}]])})])
|
(if scrollable?
|
||||||
[rn/view {:style {:flex-direction :row}}
|
(conj
|
||||||
(for [{:keys [id label resource]} data]
|
maybe-mask-wrapper
|
||||||
^{:key id}
|
[rn/flat-list
|
||||||
[rn/view {:style {:margin-right 8}}
|
(merge
|
||||||
[tag/tag
|
clean-props
|
||||||
(merge {:id id
|
(when scroll-on-press?
|
||||||
:size size
|
{:initial-scroll-index (utils.collection/first-index #(= active-tab-id (:id %)) data)})
|
||||||
:type type
|
{:ref ref
|
||||||
:label (if labelled?
|
:extra-data (str active-tab-id)
|
||||||
label
|
:horizontal true
|
||||||
(when (= type :label) label))
|
:scroll-event-throttle scroll-event-throttle
|
||||||
:active (= id active-tab-id)
|
:shows-horizontal-scroll-indicator false
|
||||||
:disabled? disabled?
|
:data data
|
||||||
:blurred? blurred?
|
:key-fn key-fn
|
||||||
:icon-color icon-color
|
:on-scroll on-scroll
|
||||||
:labelled? (if (= type :label) true labelled?)
|
:render-fn render-fn})])
|
||||||
:resource (if (= type :icon)
|
|
||||||
:i/placeholder
|
[rn/view {:style {:flex-direction :row}}
|
||||||
resource)
|
(for [{:keys [id label resource]} data]
|
||||||
:on-press #(do (reset! active-tab-id %)
|
^{:key id}
|
||||||
(when on-change (on-change %)))})]])])))))
|
[rn/view {:style {:margin-right 8}}
|
||||||
|
[tag/tag
|
||||||
|
{:id id
|
||||||
|
:size size
|
||||||
|
:type type
|
||||||
|
:label (if labelled?
|
||||||
|
label
|
||||||
|
(when (= type :label) label))
|
||||||
|
:active (= id active-tab-id)
|
||||||
|
:disabled? disabled?
|
||||||
|
:blurred? blurred?
|
||||||
|
:icon-color icon-color
|
||||||
|
:labelled? (if (= type :label) true labelled?)
|
||||||
|
:resource (if (= type :icon) :i/placeholder resource)
|
||||||
|
:on-press on-press}]])])))
|
||||||
|
@ -7,10 +7,9 @@
|
|||||||
[quo.components.utilities.token.view :as token]
|
[quo.components.utilities.token.view :as token]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.hole-view :as hole-view]
|
[react-native.hole-view :as hole-view]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
"Options:
|
"Options:
|
||||||
- :options - false / :add / :hold (default false)
|
- :options - false / :add / :hold (default false)
|
||||||
- :size - :size-24 / :size-32 (default :size-24)
|
- :size - :size-24 / :size-32 (default :size-24)
|
||||||
@ -18,45 +17,44 @@
|
|||||||
- :theme - :light / :dark
|
- :theme - :light / :dark
|
||||||
- :token-value - string - token value
|
- :token-value - string - token value
|
||||||
- :token-symbol - string"
|
- :token-symbol - string"
|
||||||
[]
|
[{:keys [options size blur? token-value token-img-src token-symbol]
|
||||||
(let [container-width (reagent/atom 0)]
|
:or {size :size-24}}]
|
||||||
(fn [{:keys [options size blur? theme token-value token-img-src token-symbol]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
:or {size :size-24}}]
|
[container-width
|
||||||
[rn/view
|
set-container-width] (rn/use-state 0)
|
||||||
{:on-layout #(reset! container-width
|
on-layout (rn/use-callback #(set-container-width
|
||||||
(oget % :nativeEvent :layout :width))}
|
(oget % :nativeEvent :layout :width)))]
|
||||||
[hole-view/hole-view
|
[rn/view {:on-layout on-layout}
|
||||||
{:holes (if options
|
[hole-view/hole-view
|
||||||
[{:x (- @container-width
|
{:holes (if options
|
||||||
(case size
|
[{:x (- container-width
|
||||||
:size-24 10
|
(case size
|
||||||
:size-32 12
|
:size-24 10
|
||||||
nil))
|
:size-32 12
|
||||||
:y (case size
|
nil))
|
||||||
:size-24 -6
|
:y (case size
|
||||||
:size-32 -4
|
:size-24 -6
|
||||||
nil)
|
:size-32 -4
|
||||||
:width 16
|
nil)
|
||||||
:height 16
|
:width 16
|
||||||
:borderRadius 8}]
|
:height 16
|
||||||
[])}
|
:borderRadius 8}]
|
||||||
[rn/view {:style (style/container size options blur? theme)}
|
[])}
|
||||||
[token/view
|
[rn/view {:style (style/container size options blur? theme)}
|
||||||
{:style (style/token-img size)
|
[token/view
|
||||||
:token token-symbol
|
{:style (style/token-img size)
|
||||||
:size (case size
|
:token token-symbol
|
||||||
:size-24 :size-20
|
:size (case size
|
||||||
:size-32 :size-28)
|
:size-24 :size-20
|
||||||
:image-source token-img-src}]
|
:size-32 :size-28)
|
||||||
[text/text
|
:image-source token-img-src}]
|
||||||
{:size :paragraph-2
|
[text/text
|
||||||
:weight :medium
|
{:size :paragraph-2
|
||||||
:style (style/label theme)}
|
:weight :medium
|
||||||
(str token-value " " token-symbol)]]]
|
:style (style/label theme)}
|
||||||
(when options
|
(str token-value " " token-symbol)]]]
|
||||||
[rn/view {:style (style/options-icon size)}
|
(when options
|
||||||
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
[rn/view {:style (style/options-icon size)}
|
||||||
{:size 20
|
[icons/icon (if (= options :hold) :i/hold :i/add-token)
|
||||||
:no-color true}]])])))
|
{:size 20
|
||||||
|
:no-color true}]])]))
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
@ -61,4 +61,4 @@
|
|||||||
(->> (rf/sub [:toasts])
|
(->> (rf/sub [:toasts])
|
||||||
:ordered
|
:ordered
|
||||||
(into [rn/view {:style (style/outmost-transparent-container)}]
|
(into [rn/view {:style (style/outmost-transparent-container)}]
|
||||||
(map #(with-meta [:f> f-container %] {:key %})))))
|
(map #(with-meta [f-container %] {:key %})))))
|
||||||
|
@ -54,7 +54,6 @@
|
|||||||
|
|
||||||
(defn screen
|
(defn screen
|
||||||
[screen-key]
|
[screen-key]
|
||||||
|
|
||||||
(reagent.core/reactify-component
|
(reagent.core/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
(let [screen-details (get (if js/goog.DEBUG
|
(let [screen-details (get (if js/goog.DEBUG
|
||||||
@ -110,7 +109,7 @@
|
|||||||
sheet])]]))
|
sheet])]]))
|
||||||
functional-compiler))
|
functional-compiler))
|
||||||
|
|
||||||
(def toasts (reagent/reactify-component toasts/toasts))
|
(def toasts (reagent/reactify-component toasts/toasts functional-compiler))
|
||||||
|
|
||||||
(def alert-banner
|
(def alert-banner
|
||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
|
Loading…
x
Reference in New Issue
Block a user