[#7589] Stickers packs horizontal scrolling
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
82493e2742
commit
4c2054afd4
|
@ -3,10 +3,10 @@
|
|||
|
||||
(def stickers-panel {:flex 1 :margin 5 :flex-direction :row :justify-content :flex-start :flex-wrap :wrap})
|
||||
|
||||
(defn pack-icon [background-color icon-size]
|
||||
(defn pack-icon [background-color icon-size icon-horizontal-margin]
|
||||
{:background-color background-color
|
||||
:margin-vertical 5
|
||||
:margin-horizontal 8
|
||||
:margin-horizontal icon-horizontal-margin
|
||||
:height icon-size
|
||||
:width icon-size
|
||||
:border-radius (/ icon-size 2)
|
||||
|
|
|
@ -6,7 +6,15 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.chat.stickers.styles :as styles]
|
||||
[status-im.ui.components.animation :as anim]))
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def icon-size 28)
|
||||
(def icon-horizontal-margin 8)
|
||||
(def indicator-width 16)
|
||||
(def dx (- (+ icon-horizontal-margin (/ icon-size 2)) (/ indicator-width 2)))
|
||||
(def icon-container (+ (* icon-horizontal-margin 2) icon-size))
|
||||
(def scroll-x (reagent/atom 0))
|
||||
|
||||
(defn button [show-stickers?]
|
||||
[react/touchable-highlight
|
||||
|
@ -27,33 +35,65 @@
|
|||
[react/text {:style {:font-size 15 :color colors/blue}}
|
||||
(i18n/label :t/get-stickers)]]]])
|
||||
|
||||
(defn- stickers-panel [stickers]
|
||||
[react/scroll-view {:style {:flex 1} :condtent-container-style {:flex 1}}
|
||||
[react/view {:style styles/stickers-panel}
|
||||
(for [{:keys [uri] :as sticker} stickers]
|
||||
^{:key uri}
|
||||
[react/touchable-highlight {:style {:height 75 :width 75 :margin 5}
|
||||
:on-press #(re-frame/dispatch [:chat/send-sticker sticker])}
|
||||
[react/image {:style {:resize-mode :cover :width "100%" :height "100%"} :source {:uri uri}}]])]])
|
||||
(defn- stickers-panel [stickers window-width]
|
||||
[react/view {:width window-width :flex 1}
|
||||
[react/scroll-view
|
||||
[react/view {:style styles/stickers-panel}
|
||||
(for [{:keys [uri] :as sticker} stickers]
|
||||
^{:key uri}
|
||||
[react/touchable-highlight {:style {:height 75 :width 75 :margin 5}
|
||||
:on-press #(re-frame/dispatch [:chat/send-sticker sticker])}
|
||||
[react/image {:style {:resize-mode :cover :width "100%" :height "100%"} :source {:uri uri}}]])]]])
|
||||
|
||||
(defview recent-stickers-panel []
|
||||
(defview recent-stickers-panel [window-width]
|
||||
(letsubs [stickers [:stickers/recent]]
|
||||
(if (seq stickers)
|
||||
[stickers-panel stickers]
|
||||
[react/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[stickers-panel stickers window-width]
|
||||
[react/view {:style {:flex 1 :align-items :center :justify-content :center :width window-width}}
|
||||
[vector-icons/icon :stickers-icons/stickers-big {:color colors/gray}]
|
||||
[react/text {:style {:margin-top 8 :font-size 17}} (i18n/label :t/recently-used-stickers)]])))
|
||||
|
||||
(def icon-size 28)
|
||||
(defn update-scroll-position [ref installed-packs selected-pack window-width]
|
||||
(when ref
|
||||
(let [x (if (= selected-pack :recent)
|
||||
0
|
||||
(* (inc (some #(when (= selected-pack (:id (second %))) (first %))
|
||||
(map-indexed vector installed-packs)))
|
||||
window-width))]
|
||||
(.scrollTo ref (clj->js {:x x :animated true})))))
|
||||
|
||||
(defn pack-icon [{:keys [id on-press selected? background-color]
|
||||
(defn on-scroll [e installed-packs window-width]
|
||||
(let [num (/ (.-nativeEvent.contentOffset.x e) window-width)
|
||||
pack-id (if (zero? num)
|
||||
:recent
|
||||
(get-in (vec installed-packs) [(dec num) :id]))]
|
||||
(when pack-id
|
||||
(re-frame/dispatch [:stickers/select-pack pack-id]))))
|
||||
|
||||
(defview stickers-paging-panel [installed-packs selected-pack]
|
||||
(letsubs [ref (atom nil)
|
||||
window-width [:dimensions/window-width]]
|
||||
{:component-will-update (fn [_ [_ installed-packs selected-pack]]
|
||||
(update-scroll-position @ref installed-packs selected-pack window-width))
|
||||
:component-did-mount #(update-scroll-position @ref installed-packs selected-pack window-width)}
|
||||
[react/scroll-view {:style {:flex 1} :horizontal true :paging-enabled true
|
||||
:ref #(reset! ref %)
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:on-momentum-scroll-end #(on-scroll % installed-packs window-width)
|
||||
:scrollEventThrottle 8
|
||||
:on-scroll #(reset! scroll-x (.-nativeEvent.contentOffset.x %))}
|
||||
^{:key "recent"}
|
||||
[recent-stickers-panel window-width]
|
||||
(for [{:keys [stickers id]} installed-packs]
|
||||
^{:key (str "sticker" id)}
|
||||
[stickers-panel (map #(assoc % :pack id) stickers) window-width])]))
|
||||
|
||||
(defn pack-icon [{:keys [id on-press background-color]
|
||||
:or {on-press #(re-frame/dispatch [:stickers/select-pack id])}} icon]
|
||||
[react/touchable-highlight {:on-press on-press}
|
||||
[react/view {:style {:align-items :center}}
|
||||
[react/view {:style (styles/pack-icon background-color icon-size)}
|
||||
icon]
|
||||
[react/view {:style {:margin-bottom 5 :height 2 :width 16 :border-radius 1
|
||||
:background-color (if selected? colors/blue colors/white)}}]]])
|
||||
[react/view {:style (styles/pack-icon background-color icon-size icon-horizontal-margin)}
|
||||
icon]]])
|
||||
|
||||
(defn pack-stickers [packs pack-id]
|
||||
(let [{:keys [stickers id]} (some #(when (= pack-id (:id %)) %) packs)]
|
||||
|
@ -67,6 +107,12 @@
|
|||
(anim/timing alpha-value {:toValue 1
|
||||
:duration 500})])))
|
||||
|
||||
(defview scroll-indicator []
|
||||
(letsubs [window-width [:dimensions/window-width]]
|
||||
[react/view {:style {:margin-bottom 5 :height 2 :width indicator-width :border-radius 1
|
||||
:margin-left (+ dx (* icon-container (/ @scroll-x window-width)))
|
||||
:background-color colors/blue}}]))
|
||||
|
||||
(defview stickers-view []
|
||||
(letsubs [selected-pack [:stickers/selected-pack]
|
||||
installed-packs [:stickers/installed-packs-vals]
|
||||
|
@ -81,10 +127,9 @@
|
|||
[react/animated-view {:style {:background-color :white :height (if input-focused? 0 bottom-anim-value)
|
||||
:opacity alpha-value}}
|
||||
(cond
|
||||
(= selected-pack :recent) [recent-stickers-panel]
|
||||
(= selected-pack :recent) [stickers-paging-panel installed-packs selected-pack]
|
||||
(not (seq installed-packs)) [no-stickers-yet-panel]
|
||||
(nil? selected-pack) [recent-stickers-panel]
|
||||
:else [stickers-panel (pack-stickers installed-packs selected-pack)])
|
||||
:else [stickers-paging-panel installed-packs selected-pack])
|
||||
[react/view {:style {:flex-direction :row :padding-horizontal 4}}
|
||||
[pack-icon {:on-press #(do
|
||||
(re-frame/dispatch [:stickers/load-packs])
|
||||
|
@ -93,11 +138,13 @@
|
|||
[vector-icons/icon :main-icons/add {:width 20 :height 20 :color colors/white}]]
|
||||
[react/view {:width 2}]
|
||||
[react/scroll-view {:horizontal true :style {:padding-left 2}}
|
||||
[pack-icon {:id :recent :selected? (or (= :recent selected-pack) (and (nil? selected-pack) (seq installed-packs)))
|
||||
:background-color colors/white}
|
||||
[vector-icons/icon :stickers-icons/recent {:color colors/gray}]]
|
||||
(for [{:keys [id thumbnail]} installed-packs]
|
||||
^{:key id}
|
||||
[pack-icon {:id id :selected? (= id selected-pack)}
|
||||
[react/image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:source {:uri thumbnail}}]])]]]))
|
||||
[react/view
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[pack-icon {:id :recent :background-color colors/white}
|
||||
[vector-icons/icon :stickers-icons/recent {:color colors/gray}]]
|
||||
(for [{:keys [id thumbnail]} installed-packs]
|
||||
^{:key id}
|
||||
[pack-icon {:id id}
|
||||
[react/image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:source {:uri thumbnail}}]])]
|
||||
[scroll-indicator]]]]]))
|
||||
|
|
|
@ -388,5 +388,6 @@
|
|||
(hex-to-value val type)))))
|
||||
|
||||
(defn decode [bytes types]
|
||||
(let [offsets (get-offsets types)]
|
||||
(map (dec-type bytes) offsets types)))
|
||||
(when-not (empty? bytes)
|
||||
(let [offsets (get-offsets types)]
|
||||
(map (dec-type bytes) offsets types))))
|
||||
|
|
Loading…
Reference in New Issue