* Fix `->` style in emoji-picker.data * Make `temp-empty-symbol` component code safer to avoid app crashing * fix `->` style in `emoji-picker.utils` * Pass sheet-animating? ratom to bottom-sheet's content component * Improve emoji picker performance
This commit is contained in:
parent
4f9544d20c
commit
5fa9c0cab6
|
@ -46,7 +46,10 @@
|
||||||
:border-color :grey}
|
:border-color :grey}
|
||||||
size)}
|
size)}
|
||||||
[quo/text {:style {:color :grey}}
|
[quo/text {:style {:color :grey}}
|
||||||
(string/capitalize (first (name token)))]])
|
(some-> token
|
||||||
|
name
|
||||||
|
first
|
||||||
|
string/capitalize)]])
|
||||||
|
|
||||||
(defn view-internal
|
(defn view-internal
|
||||||
"Render a token image.
|
"Render a token image.
|
||||||
|
|
|
@ -2,8 +2,15 @@
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
|
[react-native.platform :as platform]
|
||||||
[react-native.reanimated :as reanimated]))
|
[react-native.reanimated :as reanimated]))
|
||||||
|
|
||||||
|
(defn container
|
||||||
|
[{:keys [top] :as _insets}]
|
||||||
|
(let [padding-top (if platform/ios? top (+ top 10))]
|
||||||
|
{:flex 1
|
||||||
|
:padding-top padding-top}))
|
||||||
|
|
||||||
(defn background
|
(defn background
|
||||||
[opacity]
|
[opacity]
|
||||||
(reanimated/apply-animations-to-style
|
(reanimated/apply-animations-to-style
|
||||||
|
|
|
@ -15,29 +15,26 @@
|
||||||
(def ^:const drag-threshold 200)
|
(def ^:const drag-threshold 200)
|
||||||
|
|
||||||
(defn drag-gesture
|
(defn drag-gesture
|
||||||
[translate-y opacity scroll-enabled curr-scroll close]
|
[{:keys [translate-y opacity scroll-enabled curr-scroll close reset-open-sheet set-animating-true]}]
|
||||||
(->
|
(-> (gesture/gesture-pan)
|
||||||
(gesture/gesture-pan)
|
(gesture/on-start (fn [e]
|
||||||
(gesture/on-start (fn [e]
|
(set-animating-true)
|
||||||
(when (< (oops/oget e "velocityY") 0)
|
(when (< (oops/oget e "velocityY") 0)
|
||||||
(reset! scroll-enabled true))))
|
(reset! scroll-enabled true))))
|
||||||
(gesture/on-update (fn [e]
|
(gesture/on-update (fn [e]
|
||||||
(let [translation (oops/oget e "translationY")
|
(let [translation (oops/oget e "translationY")
|
||||||
progress (Math/abs (/ translation drag-threshold))]
|
progress (Math/abs (/ translation drag-threshold))]
|
||||||
(when (pos? translation)
|
(when (pos? translation)
|
||||||
(reanimated/set-shared-value translate-y translation)
|
(reanimated/set-shared-value translate-y translation)
|
||||||
(reanimated/set-shared-value opacity (- 1 (/ progress 5)))))))
|
(reanimated/set-shared-value opacity (- 1 (/ progress 5)))))))
|
||||||
(gesture/on-end (fn [e]
|
(gesture/on-end (fn [e]
|
||||||
(if (> (oops/oget e "translationY") drag-threshold)
|
(if (> (oops/oget e "translationY") drag-threshold)
|
||||||
(close)
|
(close)
|
||||||
(do
|
(reset-open-sheet))))
|
||||||
(reanimated/animate translate-y 0 300)
|
(gesture/on-finalize (fn [e]
|
||||||
(reanimated/animate opacity 1 300)
|
(when (and (>= (oops/oget e "velocityY") 0)
|
||||||
(reset! scroll-enabled true)))))
|
(<= @curr-scroll (if platform/ios? -1 0)))
|
||||||
(gesture/on-finalize (fn [e]
|
(reset! scroll-enabled false))))))
|
||||||
(when (and (>= (oops/oget e "velocityY") 0)
|
|
||||||
(<= @curr-scroll (if platform/ios? -1 0)))
|
|
||||||
(reset! scroll-enabled false))))))
|
|
||||||
|
|
||||||
(defn on-scroll
|
(defn on-scroll
|
||||||
[e curr-scroll]
|
[e curr-scroll]
|
||||||
|
@ -46,40 +43,54 @@
|
||||||
|
|
||||||
(defn- f-view
|
(defn- f-view
|
||||||
[_]
|
[_]
|
||||||
(let [scroll-enabled (reagent/atom true)
|
(let [scroll-enabled (reagent/atom true)
|
||||||
curr-scroll (reagent/atom 0)]
|
curr-scroll (reagent/atom 0)
|
||||||
|
animating? (reagent/atom true)
|
||||||
|
set-animating-true #(reset! animating? true)
|
||||||
|
set-animating-false (fn [ms]
|
||||||
|
(js/setTimeout #(reset! animating? false) ms))]
|
||||||
(fn [{:keys [content skip-background? theme]}]
|
(fn [{:keys [content skip-background? theme]}]
|
||||||
(let [insets (safe-area/get-insets)
|
(let [insets (safe-area/get-insets)
|
||||||
{:keys [height]} (rn/get-window)
|
{:keys [height]} (rn/get-window)
|
||||||
padding-top (:top insets)
|
|
||||||
padding-top (if platform/ios? padding-top (+ padding-top 10))
|
|
||||||
opacity (reanimated/use-shared-value 0)
|
opacity (reanimated/use-shared-value 0)
|
||||||
translate-y (reanimated/use-shared-value height)
|
translate-y (reanimated/use-shared-value height)
|
||||||
close (fn []
|
close (fn []
|
||||||
|
(set-animating-true)
|
||||||
(reanimated/animate translate-y height 300)
|
(reanimated/animate translate-y height 300)
|
||||||
(reanimated/animate opacity 0 300)
|
(reanimated/animate opacity 0 300)
|
||||||
(rf/dispatch [:navigate-back]))]
|
(rf/dispatch [:navigate-back]))
|
||||||
|
reset-open-sheet (fn []
|
||||||
|
(reanimated/animate translate-y 0 300)
|
||||||
|
(reanimated/animate opacity 1 300)
|
||||||
|
(set-animating-false 300)
|
||||||
|
(reset! scroll-enabled true))]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(reanimated/animate translate-y 0 300)
|
(reanimated/animate translate-y 0 300)
|
||||||
(reanimated/animate opacity 1 300)))
|
(reanimated/animate opacity 1 300)
|
||||||
|
(set-animating-false 300)))
|
||||||
(hooks/use-back-handler close)
|
(hooks/use-back-handler close)
|
||||||
[rn/view
|
[rn/view {:style (style/container insets)}
|
||||||
{:style {:flex 1
|
|
||||||
:padding-top padding-top}}
|
|
||||||
(when-not skip-background?
|
(when-not skip-background?
|
||||||
[reanimated/view {:style (style/background opacity)}])
|
[reanimated/view {:style (style/background opacity)}])
|
||||||
[gesture/gesture-detector
|
[gesture/gesture-detector
|
||||||
{:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll close)}
|
{:gesture (drag-gesture {:translate-y translate-y
|
||||||
|
:opacity opacity
|
||||||
|
:scroll-enabled scroll-enabled
|
||||||
|
:curr-scroll curr-scroll
|
||||||
|
:close close
|
||||||
|
:reset-open-sheet reset-open-sheet
|
||||||
|
:set-animating-true set-animating-true})}
|
||||||
[reanimated/view {:style (style/main-view translate-y theme)}
|
[reanimated/view {:style (style/main-view translate-y theme)}
|
||||||
[rn/view {:style style/handle-container}
|
[rn/view {:style style/handle-container}
|
||||||
[rn/view {:style (style/handle theme)}]]
|
[rn/view {:style (style/handle theme)}]]
|
||||||
[content
|
[content
|
||||||
{:insets insets
|
{:insets insets
|
||||||
:close close
|
:close close
|
||||||
:scroll-enabled scroll-enabled
|
:scroll-enabled scroll-enabled
|
||||||
:current-scroll curr-scroll
|
:current-scroll curr-scroll
|
||||||
:on-scroll #(on-scroll % curr-scroll)}]]]]))))
|
:on-scroll #(on-scroll % curr-scroll)
|
||||||
|
:sheet-animating? animating?}]]]]))))
|
||||||
|
|
||||||
(defn- internal-view
|
(defn- internal-view
|
||||||
[params]
|
[params]
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
(def ^:private categorized-and-partitioned
|
(def ^:private categorized-and-partitioned
|
||||||
(->> emoji-data
|
(->> emoji-data
|
||||||
(reduce (fn [acc {:keys [group] :as emoji}]
|
(reduce (fn [acc {:keys [group] :as emoji}]
|
||||||
(update-in acc [(-> (emoji-group->category group) :index) :data] conj emoji))
|
(update-in acc [(-> group emoji-group->category :index) :data] conj emoji))
|
||||||
categories)
|
categories)
|
||||||
(reduce (fn [acc {:keys [data] :as item}]
|
(reduce (fn [acc {:keys [data] :as item}]
|
||||||
(conj acc (assoc item :data (partition-all constants/emojis-per-row data))))
|
(conj acc (assoc item :data (partition-all constants/emojis-per-row data))))
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
(defn search-emoji
|
(defn search-emoji
|
||||||
[search-query]
|
[search-query]
|
||||||
(let [cleaned-query (string/lower-case (string/trim search-query))]
|
(let [cleaned-query (string/lower-case (string/trim search-query))]
|
||||||
(->> (filter (fn [{:keys [label tags emoticon]}]
|
(->> emoji-data
|
||||||
|
(filter (fn [{:keys [label tags emoticon]}]
|
||||||
(or (string/includes? label cleaned-query)
|
(or (string/includes? label cleaned-query)
|
||||||
(when emoticon
|
(when emoticon
|
||||||
(if (vector? emoticon)
|
(if (vector? emoticon)
|
||||||
(some #(string/includes? (string/lower-case %) cleaned-query) emoticon)
|
(some #(string/includes? (string/lower-case %) cleaned-query) emoticon)
|
||||||
(string/includes? (string/lower-case emoticon) cleaned-query)))
|
(string/includes? (string/lower-case emoticon) cleaned-query)))
|
||||||
(some #(string/includes? % cleaned-query) tags)))
|
(some #(string/includes? % cleaned-query) tags))))
|
||||||
emoji-data)
|
|
||||||
(partition-all constants/emojis-per-row))))
|
(partition-all constants/emojis-per-row))))
|
||||||
|
|
||||||
(defn random-emoji
|
(defn random-emoji
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
[status-im.contexts.emoji-picker.utils :as emoji-picker.utils]
|
[status-im.contexts.emoji-picker.utils :as emoji-picker.utils]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]))
|
||||||
[utils.transforms :as transforms]))
|
|
||||||
|
|
||||||
(defn- on-press-category
|
(defn- on-press-category
|
||||||
[{:keys [id index active-category scroll-ref]}]
|
[{:keys [id index active-category scroll-ref]}]
|
||||||
|
@ -30,16 +29,14 @@
|
||||||
(defn- handle-on-viewable-items-changed
|
(defn- handle-on-viewable-items-changed
|
||||||
[{:keys [event active-category should-update-active-category?]}]
|
[{:keys [event active-category should-update-active-category?]}]
|
||||||
(when should-update-active-category?
|
(when should-update-active-category?
|
||||||
(let [viewable-item (-> (oops/oget event "viewableItems")
|
(let [viewable-item (some-> event
|
||||||
transforms/js->clj
|
(oops/oget "viewableItems")
|
||||||
first
|
(aget 0)
|
||||||
:item)
|
(oops/oget "item"))
|
||||||
header? (and (map? viewable-item) (:header? viewable-item))
|
header? (and (map? viewable-item) (:header? viewable-item))
|
||||||
section-key (if header?
|
section-key (if header?
|
||||||
(:id viewable-item)
|
(:id viewable-item)
|
||||||
(:id (emoji-picker.data/emoji-group->category (-> viewable-item
|
(-> viewable-item first :group emoji-picker.data/emoji-group->category :id))]
|
||||||
first
|
|
||||||
:group))))]
|
|
||||||
(when (and (some? section-key) (not= @active-category section-key))
|
(when (and (some? section-key) (not= @active-category section-key))
|
||||||
(reset! active-category section-key)))))
|
(reset! active-category section-key)))))
|
||||||
|
|
||||||
|
@ -77,11 +74,10 @@
|
||||||
(defn- emoji-row
|
(defn- emoji-row
|
||||||
[row-data {:keys [on-select close]}]
|
[row-data {:keys [on-select close]}]
|
||||||
(into [rn/view {:style style/emoji-row-container}]
|
(into [rn/view {:style style/emoji-row-container}]
|
||||||
(map-indexed
|
(map-indexed (fn [col-index {:keys [hexcode] :as emoji}]
|
||||||
(fn [col-index {:keys [hexcode] :as emoji}]
|
^{:key hexcode}
|
||||||
^{:key hexcode}
|
[emoji-item emoji col-index on-select close]))
|
||||||
[emoji-item emoji col-index on-select close])
|
row-data))
|
||||||
row-data)))
|
|
||||||
|
|
||||||
(defn- render-item
|
(defn- render-item
|
||||||
[item _ _ render-data]
|
[item _ _ render-data]
|
||||||
|
@ -98,30 +94,30 @@
|
||||||
:container-style style/empty-results}])
|
:container-style style/empty-results}])
|
||||||
|
|
||||||
(defn- render-list
|
(defn- render-list
|
||||||
[{:keys [theme filtered-data on-viewable-items-changed scroll-enabled on-scroll on-select
|
[{:keys [theme filtered-data on-viewable-items-changed scroll-enabled on-scroll
|
||||||
set-scroll-ref close]}]
|
on-select set-scroll-ref close sheet-animating?]}]
|
||||||
(let [data (if filtered-data filtered-data emoji-picker.data/flatten-data)]
|
[gesture/flat-list
|
||||||
[gesture/flat-list
|
{:ref set-scroll-ref
|
||||||
{:ref set-scroll-ref
|
:scroll-enabled @scroll-enabled
|
||||||
:scroll-enabled @scroll-enabled
|
:data (or filtered-data emoji-picker.data/flatten-data)
|
||||||
:data data
|
:initial-num-to-render 14
|
||||||
:initial-num-to-render 20
|
:max-to-render-per-batch 10
|
||||||
:max-to-render-per-batch 20
|
:render-fn render-item
|
||||||
:render-fn render-item
|
:get-item-layout get-item-layout
|
||||||
:get-item-layout get-item-layout
|
:keyboard-dismiss-mode :on-drag
|
||||||
:keyboard-dismiss-mode :on-drag
|
:keyboard-should-persist-taps :handled
|
||||||
:keyboard-should-persist-taps :handled
|
:shows-vertical-scroll-indicator false
|
||||||
:shows-vertical-scroll-indicator false
|
:on-scroll-to-index-failed identity
|
||||||
:on-scroll-to-index-failed identity
|
:empty-component [empty-result]
|
||||||
:empty-component [empty-result]
|
:on-scroll on-scroll
|
||||||
:on-scroll on-scroll
|
:render-data {:close close
|
||||||
:render-data {:close close
|
:theme theme
|
||||||
:theme theme
|
:on-select on-select}
|
||||||
:on-select on-select}
|
:content-container-style style/list-container
|
||||||
:content-container-style style/list-container
|
:viewability-config {:item-visible-percent-threshold 100
|
||||||
:viewability-config {:item-visible-percent-threshold 100
|
:minimum-view-time 200}
|
||||||
:minimum-view-time 200}
|
:on-viewable-items-changed on-viewable-items-changed
|
||||||
:on-viewable-items-changed on-viewable-items-changed}]))
|
:window-size (if @sheet-animating? 1 10)}])
|
||||||
|
|
||||||
(defn- footer
|
(defn- footer
|
||||||
[{:keys [theme active-category scroll-ref]}]
|
[{:keys [theme active-category scroll-ref]}]
|
||||||
|
@ -152,12 +148,9 @@
|
||||||
(reset! search-text ""))
|
(reset! search-text ""))
|
||||||
|
|
||||||
(defn f-view
|
(defn f-view
|
||||||
[{:keys [render-emojis? search-text on-change-text clear-states active-category scroll-ref theme]
|
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
|
||||||
:as sheet-opts}]
|
:as sheet-opts}]
|
||||||
(let [search-active? (pos? (count @search-text))]
|
(let [search-active? (pos? (count @search-text))]
|
||||||
;; rendering emojis is heavy on the UI thread, we need to delay rendering until the navigation
|
|
||||||
;; animation completes. 250 is based on the default 300ms navigation duration.
|
|
||||||
(rn/use-effect #(js/setTimeout (fn [] (reset! render-emojis? true)) 250))
|
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/flex-spacer
|
{:style style/flex-spacer
|
||||||
:keyboard-vertical-offset 8}
|
:keyboard-vertical-offset 8}
|
||||||
|
@ -171,8 +164,7 @@
|
||||||
:on-change-text on-change-text
|
:on-change-text on-change-text
|
||||||
:clearable? search-active?
|
:clearable? search-active?
|
||||||
:on-clear clear-states}]]
|
:on-clear clear-states}]]
|
||||||
(when @render-emojis?
|
[render-list sheet-opts]
|
||||||
[render-list sheet-opts])
|
|
||||||
(when-not search-active?
|
(when-not search-active?
|
||||||
[footer
|
[footer
|
||||||
{:theme theme
|
{:theme theme
|
||||||
|
@ -186,7 +178,6 @@
|
||||||
set-scroll-ref #(reset! scroll-ref %)
|
set-scroll-ref #(reset! scroll-ref %)
|
||||||
search-text (reagent/atom "")
|
search-text (reagent/atom "")
|
||||||
filtered-data (reagent/atom nil)
|
filtered-data (reagent/atom nil)
|
||||||
render-emojis? (reagent/atom false)
|
|
||||||
active-category (reagent/atom constants/default-category)
|
active-category (reagent/atom constants/default-category)
|
||||||
clear-states #(clear {:active-category active-category
|
clear-states #(clear {:active-category active-category
|
||||||
:filtered-data filtered-data
|
:filtered-data filtered-data
|
||||||
|
@ -210,17 +201,15 @@
|
||||||
:should-update-active-category? (nil? @filtered-data)}))]
|
:should-update-active-category? (nil? @filtered-data)}))]
|
||||||
(fn [sheet-opts]
|
(fn [sheet-opts]
|
||||||
[:f> f-view
|
[:f> f-view
|
||||||
(merge sheet-opts
|
(assoc sheet-opts
|
||||||
{:render-emojis? render-emojis?
|
:search-text search-text
|
||||||
:search-text search-text
|
:on-change-text on-change-text
|
||||||
:on-change-text on-change-text
|
:clear-states clear-states
|
||||||
:clear-states clear-states
|
:filtered-data @filtered-data
|
||||||
:filtered-data @filtered-data
|
:set-scroll-ref set-scroll-ref
|
||||||
:set-scroll-ref set-scroll-ref
|
:on-select on-select
|
||||||
:on-select on-select
|
:on-viewable-items-changed on-viewable-items-changed
|
||||||
:on-viewable-items-changed on-viewable-items-changed
|
:active-category active-category
|
||||||
:active-category active-category
|
:scroll-ref scroll-ref)])))
|
||||||
:scroll-ref scroll-ref})])))
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
(def view (quo.theme/with-theme view-internal))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue