Merge pull request #582 from status-im/bug/#561

Carousel calculation fixes (#561)
This commit is contained in:
Roman Volosovskyi 2016-12-27 13:30:41 +02:00 committed by GitHub
commit 3258df51c8
5 changed files with 66 additions and 32 deletions

View File

@ -1,5 +1,6 @@
(ns status-im.components.carousel.carousel (ns status-im.components.carousel.carousel
(:require [status-im.components.react :refer [view (:require [reagent.impl.component :as rc]
[status-im.components.react :refer [view
scroll-view scroll-view
touchable-without-feedback touchable-without-feedback
text]] text]]
@ -19,14 +20,17 @@
(defn get-active-page [data] (defn get-active-page [data]
(get data :activePage 0)) (get data :activePage 0))
(defn get-sneak [{:keys [sneak count] }] (defn get-sneak [{:keys [sneak gap count]}]
(if (> (or count 2) 1) (if (> (or count 2) 1)
(or sneak (:sneak defaults)) (or sneak (:sneak defaults))
0)) gap))
(defn get-gap [data] (defn get-gap [data]
(get data :gap (:gap defaults))) (get data :gap (:gap defaults)))
(defn get-count [data]
(get data :count))
(defn compute-page-width (defn compute-page-width
([gap sneak] ([gap sneak]
(compute-page-width (window-page-width) gap sneak)) (compute-page-width (window-page-width) gap sneak))
@ -47,11 +51,16 @@
(let [sneak (get-sneak props) (let [sneak (get-sneak props)
page-width (get-page-width props) page-width (get-page-width props)
style (get-page-style props) style (get-page-style props)
gap (quot (- (- (window-page-width) (* 2 sneak)) page-width) 2)] gap (quot (- (window-page-width)
(* 2 sneak)
page-width)
2)
count (get-count props)]
(reagent.core/set-state component {:sneak sneak (reagent.core/set-state component {:sneak sneak
:pageWidth page-width :pageWidth page-width
:pageStyle style :pageStyle style
:gap gap}))) :gap gap
:count count})))
(defn scroll-to [component x y] (defn scroll-to [component x y]
(.scrollTo (.-scrollView component) (clj->js {:y y (.scrollTo (.-scrollView component) (clj->js {:y y
@ -60,14 +69,29 @@
(defn get-current-position [event] (defn get-current-position [event]
(.-x (.-contentOffset (.-nativeEvent event)))) (.-x (.-contentOffset (.-nativeEvent event))))
(defn get-page-position [state page]
(let [page-width (get-page-width state)
gap (get-gap state)
sneak (get-sneak state)
count (get-count state)
addition (condp = page
0 gap
(dec count) (- (* 3 gap) (* sneak 2))
(- sneak (* gap 2)))]
(+ (* page page-width)
(* (dec page) gap)
addition)))
(defn go-to-page [component page] (defn go-to-page [component page]
(let [props (reagent.core/props component) (let [props (reagent.core/props component)
state (reagent.core/state component) state (reagent.core/state component)
page-width (get-page-width state) page-width (get-page-width state)
gap (get-gap state) gap (get-gap state)
page-position (+ (* page page-width) (* (- page 1) gap))] page-position (get-page-position state page)]
(log/debug "go-to-page: props-page-width=" page-width "; gap=" gap (log/debug "go-to-page: props-page-width=" page-width "; gap=" gap
"; page-position=" page-position) "; page-position=" page-position "; page: " page)
(reagent.core/set-state component {:scrolling? true})
(js/setTimeout #(reagent.core/set-state component {:scrolling? false}) 200)
(scroll-to component page-position 0) (scroll-to component page-position 0)
(reagent.core/set-state component {:activePage page}) (reagent.core/set-state component {:activePage page})
(when (:onPageChange props) (when (:onPageChange props)
@ -79,22 +103,23 @@
scroll-threshold (get-scroll-threshold props) scroll-threshold (get-scroll-threshold props)
current-page (get-active-page state) current-page (get-active-page state)
current-position (get-current-position event) current-position (get-current-position event)
page-count (get-count state)
direction (cond direction (cond
(> current-position (+ starting-position scroll-threshold)) 1 (> current-position (+ starting-position scroll-threshold)) 1
(< current-position (- starting-position scroll-threshold)) -1 (< current-position (- starting-position scroll-threshold)) -1
:else 0) :else 0)
new-page (+ current-page direction) new-page (+ current-page direction)]
]
(log/debug state "on-scroll-end: starting position=" starting-position (log/debug state "on-scroll-end: starting position=" starting-position
"; current-position=" current-position "; direction=" direction "; current-position=" current-position "; direction=" direction
"; current-page=" current-page "; new-page=" new-page) "; current-page=" current-page "; new-page=" new-page)
(if (not= current-page new-page) (if (and (not= current-page new-page)
(< -1 new-page page-count))
(go-to-page component new-page) (go-to-page component new-page)
(scroll-to component starting-position 0)))) (scroll-to component starting-position 0))))
(defn component-will-mount [component new-args] (defn component-will-mount [component new-args]
(let [props (reagent.core/props component)] (let [props (reagent.core/props component)]
(log/debug "component-will-mount: new-args="new-args) (log/debug "component-will-mount: new-args=" new-args)
(apply-props component props))) (apply-props component props)))
(defn component-did-mount [component] (defn component-did-mount [component]
@ -111,15 +136,18 @@
(log/debug "component-did-update")) (log/debug "component-did-update"))
(defn component-will-receive-props [component new-argv] (defn component-will-receive-props [component new-argv]
(log/debug "component-will-receive-props: new-argv=" new-argv) (let [props (rc/extract-props new-argv)]
(apply-props component new-argv)) (log/debug "component-will-receive-props: props=" props)
(apply-props component props)))
(defn get-event-width [event] (defn get-event-width [event]
(.-width (.-layout (.-nativeEvent event)))) (.-width (.-layout (.-nativeEvent event))))
(defn on-layout-change [event component] (defn on-layout-change [event component]
(let [state (reagent.core/state component) (let [state (reagent.core/state component)
page-width (compute-page-width (get-event-width event) (get-gap state) (get-sneak state)) page-width (compute-page-width (get-event-width event)
(get-gap state)
(get-sneak state))
state-page-width (get-page-width state) state-page-width (get-page-width state)
active-page (get-active-page state) active-page (get-active-page state)
gap (get-gap state) gap (get-gap state)
@ -128,21 +156,21 @@
(if (not= page-width state-page-width) (if (not= page-width state-page-width)
(do (do
(reagent.core/set-state component {:pageWidth page-width}) (reagent.core/set-state component {:pageWidth page-width})
(.setState component {:layout (.-layout (.-nativeEvent event))}) (.setState component {:layout (.-layout (.-nativeEvent event))}))
)
(scroll-to component page-position 0)))) (scroll-to component page-position 0))))
(defn get-pages [component data children] (defn get-pages [component data children]
(let [page-width (get-page-width data) (let [page-width (get-page-width data)
page-style (get-page-style data) page-style (get-page-style data)
gap (get-gap data) gap (get-gap data)
margin (quot gap 2)] sneak (get-sneak data)
count (get-count data)]
(doall (map-indexed (fn [index child] (doall (map-indexed (fn [index child]
(let [page-index index (let [page-index index
touchable-data {:key index touchable-data {:key index
:onPress #(go-to-page component page-index)}] :onPress #(go-to-page component page-index)}]
[touchable-without-feedback touchable-data [touchable-without-feedback touchable-data
[view {:style [(st/page page-width margin) [view {:style [(st/page index count page-width gap)
page-style] page-style]
:onLayout #(log/debug "view onLayout" %)} :onLayout #(log/debug "view onLayout" %)}
@ -162,6 +190,7 @@
:decelerationRate 0.9 :decelerationRate 0.9
:horizontal true :horizontal true
:onLayout #(on-layout-change % component) :onLayout #(on-layout-change % component)
:scrollEnabled (not (get state :scrolling?))
:onScrollBeginDrag #(reset! starting-position (get-current-position %)) :onScrollBeginDrag #(reset! starting-position (get-current-position %))
:onScrollEndDrag #(on-scroll-end % component @starting-position) :onScrollEndDrag #(on-scroll-end % component @starting-position)
:showsHorizontalScrollIndicator false :showsHorizontalScrollIndicator false

View File

@ -4,11 +4,16 @@
{:flex 1}) {:flex 1})
(defn content-container [sneak gap] (defn content-container [sneak gap]
{:paddingLeft (+ 0 (quot gap 2)) {:paddingLeft (quot gap 2)
:paddingRight (+ sneak (quot gap 2))}) :paddingRight (quot gap 2)})
(defn page [page-width margin] (defn page [index count page-width gap]
{:width page-width (let [margin (quot gap 2)
:justifyContent :center left-spacing (if (zero? index) gap 0)
:marginLeft margin right-spacing (if (and (= index (dec count))
:marginRight margin}) (> count 1))
gap 0)]
{:width page-width
:justifyContent :center
:marginLeft (+ margin left-spacing)
:marginRight (+ margin right-spacing)}))

View File

@ -51,8 +51,9 @@
[title :t/popular-tags false] [title :t/popular-tags false]
(if (pos? (count popular-tags)) (if (pos? (count popular-tags))
[carousel {:pageStyle st/carousel-page-style [carousel {:pageStyle st/carousel-page-style
:gap 0 :gap 8
:sneak (if (> (count popular-tags) 1) 16 8)} :sneak 16
:count (count popular-tags)}
(for [{:keys [name]} popular-tags] (for [{:keys [name]} popular-tags]
[discover-popular-list {:tag name [discover-popular-list {:tag name
:contacts contacts :contacts contacts

View File

@ -69,9 +69,8 @@
(def popular-list-container (def popular-list-container
{:flex 1 {:flex 1
:background-color :white :background-color :white
:margin-left 16 :padding-top 18
:padding-left 16 :padding-left 16})
:padding-top 18})
(def popular-list-item (def popular-list-item
{:flex-direction :row {:flex-direction :row

View File

@ -42,8 +42,8 @@
:handler #(dispatch [:accept-transactions password])}]}] :handler #(dispatch [:accept-transactions password])}]}]
[view st/carousel-container [view st/carousel-container
[carousel {:pageStyle st/carousel-page-style [carousel {:pageStyle st/carousel-page-style
:gap 16 :gap 8
:sneak 20 :sneak 16
:count (count transactions)} :count (count transactions)}
(when transactions (when transactions
(for [transaction transactions] (for [transaction transactions]