From 66b1495e2dcbb1223059ab721da9e941c8b7a1b5 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Sun, 24 Apr 2016 15:22:24 +0300 Subject: [PATCH] implemented carousel component Former-commit-id: 0c88c0556ed207e2a636b6e3de0f58e38ed6b74a --- .re-natal | 1 - package.json | 1 - src/syng_im/components/carousel.cljs | 143 +++++++++++++++++- .../components/discovery/discovery.cljs | 2 +- .../discovery/discovery_popular.cljs | 27 ++-- .../discovery/discovery_popular_list.cljs | 4 +- src/syng_im/components/react.cljs | 1 + 7 files changed, 154 insertions(+), 25 deletions(-) diff --git a/.re-natal b/.re-natal index 8a8e33774a..282fd17ebb 100644 --- a/.re-natal +++ b/.re-natal @@ -14,7 +14,6 @@ "react-native-vector-icons/Ionicons", "react-native-circle-checkbox", "react-native-randombytes", - "react-native-carousel-control" ], "imageDirs": [ "images" diff --git a/package.json b/package.json index bb1a49ac6a..f069c032a4 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "awesome-phonenumber": "^1.0.12", "react-native": "^0.22.0", "react-native-action-button": "^1.1.3", - "react-native-carousel-control": "^1.0.1", "react-native-circle-checkbox": "^0.1.3", "react-native-contacts": "^0.2.1", "react-native-i18n": "0.0.8", diff --git a/src/syng_im/components/carousel.cljs b/src/syng_im/components/carousel.cljs index 5a6eb07019..127c06048c 100644 --- a/src/syng_im/components/carousel.cljs +++ b/src/syng_im/components/carousel.cljs @@ -1,15 +1,146 @@ -(ns syng-im.components.carousel) - -(set! js/Carousel (.-default (js/require "react-native-carousel-control"))) +(ns syng-im.components.carousel + (:require [syng-im.components.react :refer [android? + view + scroll-view + touchable-without-feedback + text]] + [syng-im.utils.debug :refer [log]])) -(defn carousel [opts & children] - (apply js/React.createElement js/Carousel (clj->js opts) children)) +(defn page-width [] + (.-width (.get (.. js/React -Dimensions) "window"))) + +(def defaults {:gap 10 + :sneak 10 + :pageWidth (- (page-width) 50)}) +(defn get-gap [data] + (get data :gap (:gap defaults))) + +(defn get-sneak [data] + (get data :sneak (:sneak defaults))) + +(defn get-page-width [data] + (get data :pageWidth (:pageWidth defaults))) + + +(defn calculate-gap [component props] + (let [prop-page-width (:pageWidth props) + sneak (get-sneak props) + _ (log "calculate-gap") + _ (log component) + _ (log props) + _ (log prop-page-width) + _ (log sneak)] + (if (> prop-page-width (page-width)) + (println "Invalid pageWidth")) + (reagent.core/set-state component {:gap (/ (- (- (page-width) (* 2 sneak)) prop-page-width) 2)}) + )) + +(defn scroll-to [component x y] + (.scrollTo (.-scrollView component) (clj->js {:y y + :x x}))) + +(defn on-scroll-end [event component] + (let [_ (log "on-scroll-end") + _ (log event) + _ (log component) + props (reagent.core/props component) + _ (log props) + state (reagent.core/state component) + _ (log state) + prop-page-width (get-page-width props) + _ (log (str "prop-page-width: " prop-page-width)) + sneak (get-sneak props) + _ (log (str "sneak: " sneak)) + gap (get-gap state) + _ (log (str "gap: " gap)) + page-offset (+ prop-page-width gap) + _ (log (str "page-offset: " page-offset)) + current-position (+ (.-x (.-contentOffset (.-nativeEvent event))) (/ (page-width) 2)) + _ (log (str "current-position: " current-position)) + current-page (quot current-position page-offset) + _ (log (str "current-page: " current-page)) + ] + (scroll-to component (* current-page page-offset) 0) + (reagent.core/set-state component {:activePage current-page}) + (if (:onPageChange props) + ((:onPageChange props) current-page)))) + +(defn go-to-page [component position] + (let [_ (log "go-to-page") + props (reagent.core/props component) + state (reagent.core/state component) + props-page-width (get-page-width props) + _ (log (str "props page width: " props-page-width)) + gap (get-gap state) + _ (log (str "gap: " gap)) + page-position (* position (+ props-page-width gap)) + _ (log (str "page position: " page-position))] + (scroll-to component page-position 0))) + +(defn carousel [data children] + (let [_ (log "Creating carousel component: ") + _ (log data) + _ (log children)] + (reagent.core/create-class {:component-did-mount (fn [this] + (let [_ (log this)] + (if (> (.-initialPage (.-props this)) 0) + (go-to-page this (.-initialPage (.-props this)))))) + + :component-will-mount (fn [this] + (let [_ (log "component-will-mount") + _ (log this)] + (calculate-gap this (reagent.core/props this)))) + :component-will-receive-props (fn [this new-argv] + (let [_ (log "component-will-receive-props-mount") + _ (log this) + _ (log new-argv)] + (calculate-gap this new-argv))) + :display-name "carousel1" + :reagent-render (fn [data children] + (let [_ (log "reagent-render") + _ (log data) + _ (log children) + component (reagent.core/current-component) + props-page-width (get-page-width data) + sneak (get-sneak data) + gap (get-gap data) + page-style (get data :pageStyle {}) + pages (map-indexed (fn [index child] + (let [page-index index + _ (log (str "page index" index "-" page-index)) + _ (log child)] + [touchable-without-feedback {:key index + :onPress (fn [a b c] + (let [_ (log "touchable pressed") + _ (log (.-target a)) + _ (log component) + _ (log page-index)] + (go-to-page component page-index))) + } + [view {:style [{:width props-page-width + :justifyContent "center" + :marginLeft (/ gap 2) + :marginRight (/ gap 2)} + page-style]} + child]])) children)] + + [view {:style {:flex 1}} + [scroll-view {:contentContainerStyle {:paddingLeft (+ sneak (/ gap 2)) + :paddingRight (+ sneak (/ gap 2))} + :automaticallyAdjustContentInsets false + :bounces false + :decelerationRate 0.9 + :horizontal true + :onScrollEndDrag (fn [event] (on-scroll-end event component)) + :showsHorizontalScrollIndicator false + :ref (fn [c] (set! (.-scrollView component) c)) + } + pages]]))}))) (comment - ) \ No newline at end of file diff --git a/src/syng_im/components/discovery/discovery.cljs b/src/syng_im/components/discovery/discovery.cljs index bee5873a69..f3e464b840 100644 --- a/src/syng_im/components/discovery/discovery.cljs +++ b/src/syng_im/components/discovery/discovery.cljs @@ -30,7 +30,7 @@ :style {:backgroundColor "#eef2f5" :justifyContent "center" :height 56 - :elevation 2} + :elevation 0} :onIconClicked (fn [] (realm/write (fn [] (let [number (rand-int 30)] diff --git a/src/syng_im/components/discovery/discovery_popular.cljs b/src/syng_im/components/discovery/discovery_popular.cljs index b452cb9b18..418d60603c 100644 --- a/src/syng_im/components/discovery/discovery_popular.cljs +++ b/src/syng_im/components/discovery/discovery_popular.cljs @@ -14,20 +14,19 @@ (defn discovery-popular [] (let [popular-tags (subscribe [:get-popular-tags 3]) _ (log "Got popular tags: ") - _ (log @popular-tags) - popular-lists (mapv #(discovery-popular-list (.-name %)) @popular-tags)] - (if (> (count popular-lists) 0) - (apply carousel {:pageStyle {:borderRadius 1 - :shadowColor "black" - :shadowRadius 1 - :shadowOpacity 0.8 - :elevation 2 - :marginBottom 10} - :pageWidth (- (page-width) 60) - - } - popular-lists - ) + _ (log @popular-tags)] + (if (> (count @popular-tags) 0) + [carousel {:pageStyle {:borderRadius 1 + :shadowColor "black" + :shadowRadius 1 + :shadowOpacity 0.8 + :elevation 2 + :marginBottom 10} + :pageWidth (- (page-width) 60) + :sneak 20} + (for [tag @popular-tags] + (discovery-popular-list (.-name tag))) + ] [text "None"] ) ) diff --git a/src/syng_im/components/discovery/discovery_popular_list.cljs b/src/syng_im/components/discovery/discovery_popular_list.cljs index 0a1274eecc..fdb8199120 100644 --- a/src/syng_im/components/discovery/discovery_popular_list.cljs +++ b/src/syng_im/components/discovery/discovery_popular_list.cljs @@ -32,7 +32,7 @@ (let [discoveries (subscribe [:get-discoveries-by-tag tag 3]) _ (log (str "Got discoveries for tag (" tag "): ") @discoveries) _ (log @discoveries)] - (r/as-element [view {:style {:flex 1 + [view {:style {:flex 1 :backgroundColor "white" :paddingLeft 10 :paddingTop 10}} @@ -52,7 +52,7 @@ :renderRow render-row :renderSeparator render-separator :style {:backgroundColor "white"}}] - ]))) + ])) (comment list-view {:dataSource elements diff --git a/src/syng_im/components/react.cljs b/src/syng_im/components/react.cljs index 020f657e7a..ff84d907d8 100644 --- a/src/syng_im/components/react.cljs +++ b/src/syng_im/components/react.cljs @@ -13,6 +13,7 @@ (def list-view (r/adapt-react-class (.-ListView js/React))) (def text-input (r/adapt-react-class (.-TextInput js/React))) (def scroll-view (r/adapt-react-class (.-ScrollView js/React))) +(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback js/React))) (def platform (.. js/React -Platform -OS))