rework swiper
This commit is contained in:
parent
03a37b34ec
commit
6e2e14dfea
|
@ -35,10 +35,6 @@
|
||||||
:border-bottom-width 2
|
:border-bottom-width 2
|
||||||
:border-bottom-color styles/color-white})
|
:border-bottom-color styles/color-white})
|
||||||
|
|
||||||
(def tab-title-wrapper
|
|
||||||
{:min-width 60
|
|
||||||
:margin-top 3})
|
|
||||||
|
|
||||||
(defnstyle tab-title [active? text-only?]
|
(defnstyle tab-title [active? text-only?]
|
||||||
{:ios {:font-size (if text-only? 15 11)}
|
{:ios {:font-size (if text-only? 15 11)}
|
||||||
:android {:font-size (if text-only? 14 12)}
|
:android {:font-size (if text-only? 14 12)}
|
||||||
|
|
|
@ -1,33 +1,25 @@
|
||||||
(ns status-im.components.tabs.views
|
(ns status-im.components.tabs.views
|
||||||
(:require-macros [status-im.utils.views :refer [defview]]
|
(:require [re-frame.core :refer [dispatch]]
|
||||||
[cljs.core.async.macros :as am])
|
|
||||||
(:require [cljs.core.async :as async]
|
|
||||||
[reagent.core :as r]
|
|
||||||
[re-frame.core :refer [subscribe dispatch]]
|
|
||||||
[status-im.components.react :as react]
|
|
||||||
[status-im.components.icons.vector-icons :as vi]
|
[status-im.components.icons.vector-icons :as vi]
|
||||||
|
[status-im.components.react :as react]
|
||||||
[status-im.components.tabs.styles :as tabs.styles]
|
[status-im.components.tabs.styles :as tabs.styles]
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform])
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]]))
|
||||||
|
|
||||||
(defn- tab [{:keys [view-id title title-fn icon-active icon-inactive style-active selected-view-id on-press]
|
(defn- tab [{:keys [view-id title icon-active icon-inactive style-active selected-view-id on-press]}]
|
||||||
:or {title-fn react/text}}]
|
|
||||||
(let [active? (= view-id selected-view-id)
|
(let [active? (= view-id selected-view-id)
|
||||||
text-only? (nil? icon-active)]
|
text-only? (nil? icon-active)]
|
||||||
[react/touchable-highlight {:style (merge tabs.styles/tab
|
[react/touchable-highlight {:style (merge tabs.styles/tab (if (and active? style-active) style-active))
|
||||||
(when (and active? style-active)
|
|
||||||
style-active))
|
|
||||||
:disabled active?
|
:disabled active?
|
||||||
:on-press #(if on-press
|
:on-press #(if on-press (on-press view-id) (dispatch [:navigate-to-tab view-id]))}
|
||||||
(on-press view-id)
|
|
||||||
(dispatch [:navigate-to-tab view-id]))}
|
|
||||||
[react/view {:style tabs.styles/tab-container}
|
[react/view {:style tabs.styles/tab-container}
|
||||||
(when-let [icon (if active? icon-active icon-inactive)]
|
(when-let [icon (if active? icon-active icon-inactive)]
|
||||||
[react/view
|
[react/view
|
||||||
[vi/icon icon (tabs.styles/tab-icon active?)]])
|
[vi/icon icon (tabs.styles/tab-icon active?)]])
|
||||||
[react/view {:style tabs.styles/tab-title-wrapper}
|
[react/view
|
||||||
(title-fn {:uppercase? (and text-only? (get-in platform/platform-specific [:uppercase?]))
|
[react/text (merge (if text-only? {:uppercase? (get-in platform/platform-specific [:uppercase?])})
|
||||||
:style (tabs.styles/tab-title active? text-only?)}
|
{:style (tabs.styles/tab-title active? text-only?)})
|
||||||
title)]]]))
|
title]]]]))
|
||||||
|
|
||||||
(defn- create-tab [index data selected-view-id on-press style-active]
|
(defn- create-tab [index data selected-view-id on-press style-active]
|
||||||
(let [data (merge data {:key index
|
(let [data (merge data {:key index
|
||||||
|
@ -48,76 +40,3 @@
|
||||||
(into
|
(into
|
||||||
[react/view tabs.styles/tabs-inner-container]
|
[react/view tabs.styles/tabs-inner-container]
|
||||||
(map-indexed #(create-tab %1 %2 selected-view-id on-press style-tab-active) tab-list))])
|
(map-indexed #(create-tab %1 %2 selected-view-id on-press style-tab-active) tab-list))])
|
||||||
|
|
||||||
;; Swipable tabs
|
|
||||||
|
|
||||||
(defn- tab->index [tabs] (reduce #(assoc %1 (:view-id %2) (count %1)) {} tabs))
|
|
||||||
|
|
||||||
(defn get-tab-index [tabs view-id]
|
|
||||||
(get (tab->index tabs) view-id 0))
|
|
||||||
|
|
||||||
(defn index->tab [tabs] (clojure.set/map-invert (tab->index tabs)))
|
|
||||||
|
|
||||||
(defn scroll-to [tab-list prev-view-id view-id]
|
|
||||||
(let [p (get-tab-index tab-list prev-view-id)
|
|
||||||
n (get-tab-index tab-list view-id)]
|
|
||||||
(- n p)))
|
|
||||||
|
|
||||||
(defonce scrolling? (atom false))
|
|
||||||
|
|
||||||
(defn on-scroll-end [on-view-change tabs swiped? scroll-ended view-id]
|
|
||||||
(fn [_ state]
|
|
||||||
(when @scrolling?
|
|
||||||
(async/put! scroll-ended true))
|
|
||||||
(let [{:strs [index]} (js->clj state)
|
|
||||||
new-view-id ((index->tab tabs) index)]
|
|
||||||
(if new-view-id
|
|
||||||
(when-not (= @view-id new-view-id)
|
|
||||||
(reset! swiped? true)
|
|
||||||
(on-view-change new-view-id))))))
|
|
||||||
|
|
||||||
(defn start-scrolling-loop
|
|
||||||
"Loop that synchronizes tabs scrolling to avoid an inconsistent state."
|
|
||||||
[scroll-start scroll-ended]
|
|
||||||
(am/go-loop [[swiper to] (async/<! scroll-start)]
|
|
||||||
;; start scrolling
|
|
||||||
(reset! scrolling? true)
|
|
||||||
(.scrollBy swiper to)
|
|
||||||
;; lock loop until scroll ends
|
|
||||||
(async/alts! [scroll-ended (async/timeout 2000)])
|
|
||||||
(reset! scrolling? false)
|
|
||||||
(recur (async/<! scroll-start))))
|
|
||||||
|
|
||||||
(defn swipable-tabs [{:keys [style style-tabs style-tab-active on-view-change]} tab-list prev-view-id view-id]
|
|
||||||
(let [swiped? (r/atom false)
|
|
||||||
main-swiper (r/atom nil)
|
|
||||||
scroll-start (async/chan 10)
|
|
||||||
scroll-ended (async/chan 10)]
|
|
||||||
(r/create-class
|
|
||||||
{:component-did-mount
|
|
||||||
#(start-scrolling-loop scroll-start scroll-ended)
|
|
||||||
:component-will-update
|
|
||||||
(fn []
|
|
||||||
(if @swiped?
|
|
||||||
(reset! swiped? false)
|
|
||||||
(when @main-swiper
|
|
||||||
(let [to (scroll-to tab-list @prev-view-id @view-id)]
|
|
||||||
(async/put! scroll-start [@main-swiper to])))))
|
|
||||||
:display-name "swipable-tabs"
|
|
||||||
:reagent-render
|
|
||||||
(fn []
|
|
||||||
[react/view {:style style}
|
|
||||||
[tabs {:selected-view-id @view-id
|
|
||||||
:tab-list tab-list
|
|
||||||
:style style-tabs
|
|
||||||
:style-tab-active style-tab-active
|
|
||||||
:on-press on-view-change}]
|
|
||||||
[react/swiper (merge tabs.styles/swiper
|
|
||||||
{:index (get-tab-index tab-list @view-id)
|
|
||||||
:ref #(reset! main-swiper %)
|
|
||||||
:loop false
|
|
||||||
:on-momentum-scroll-end (on-scroll-end on-view-change tab-list swiped? scroll-ended view-id)})
|
|
||||||
(doall
|
|
||||||
(map-indexed (fn [index {screen :screen}]
|
|
||||||
(with-meta screen {:key index}))
|
|
||||||
tab-list))]])})))
|
|
||||||
|
|
|
@ -141,3 +141,8 @@
|
||||||
:wallet/discard-unsigned-transaction
|
:wallet/discard-unsigned-transaction
|
||||||
(fn [_ [_ transaction-id]]
|
(fn [_ [_ transaction-id]]
|
||||||
{:discard-transaction transaction-id}))
|
{:discard-transaction transaction-id}))
|
||||||
|
|
||||||
|
(handlers/register-handler-db
|
||||||
|
:change-tab
|
||||||
|
(fn [db [_ current-tab]]
|
||||||
|
(assoc-in db [:wallet :current-tab] current-tab)))
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
(defmethod navigation/preload-data! :wallet
|
(defmethod navigation/preload-data! :wallet
|
||||||
[db _]
|
[db _]
|
||||||
(re-frame/dispatch [:update-wallet])
|
(re-frame/dispatch [:update-wallet])
|
||||||
db)
|
(assoc-in db [:wallet :current-tab] 0))
|
||||||
|
|
||||||
(defmethod navigation/preload-data! :wallet-transactions
|
(defmethod navigation/preload-data! :wallet-transactions
|
||||||
[db _]
|
[db _]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
(ns status-im.ui.screens.wallet.transactions.styles
|
(ns status-im.ui.screens.wallet.transactions.styles
|
||||||
(:require [status-im.components.styles :as styles]))
|
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||||
|
(:require [status-im.components.styles :as styles]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(def error-container
|
(def error-container
|
||||||
{:align-self :center
|
{:align-self :center
|
||||||
|
@ -19,13 +21,32 @@
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:background-color styles/color-white})
|
:background-color styles/color-white})
|
||||||
|
|
||||||
(def tabs
|
(def tab-height (if platform/ios? 51 55))
|
||||||
{:border-bottom-width 1
|
|
||||||
:border-bottom-color styles/color-gray10-transparent})
|
|
||||||
|
|
||||||
(def tab-active
|
(def tabs-container
|
||||||
{:border-bottom-width 2
|
{:flexDirection :row})
|
||||||
:border-bottom-color styles/color-blue4})
|
|
||||||
|
(defnstyle tab [active?]
|
||||||
|
{:flex 1
|
||||||
|
:height tab-height
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
|
:border-bottom-width (if active? 2 1)
|
||||||
|
:border-bottom-color (if active?
|
||||||
|
styles/color-blue4
|
||||||
|
styles/color-gray10-transparent)})
|
||||||
|
|
||||||
|
(defnstyle tab-title [active?]
|
||||||
|
{:ios {:font-size 15}
|
||||||
|
:android {:font-size 14}
|
||||||
|
:text-align :center
|
||||||
|
:color (if active?
|
||||||
|
styles/color-blue4
|
||||||
|
styles/color-black)})
|
||||||
|
|
||||||
|
(def tab-unsigned-transactions-count
|
||||||
|
(merge (tab-title false)
|
||||||
|
{:color styles/color-gray10}))
|
||||||
|
|
||||||
(def forward
|
(def forward
|
||||||
{:color styles/color-gray7})
|
{:color styles/color-gray7})
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
(fn [wallet]
|
(fn [wallet]
|
||||||
(get-in wallet [:errors :transactions-update])))
|
(get-in wallet [:errors :transactions-update])))
|
||||||
|
|
||||||
|
(reg-sub :wallet.transactions/current-tab
|
||||||
|
:<- [:wallet]
|
||||||
|
(fn [wallet]
|
||||||
|
(get wallet :current-tab 0)))
|
||||||
|
|
||||||
(reg-sub :wallet.transactions/transactions
|
(reg-sub :wallet.transactions/transactions
|
||||||
:<- [:wallet]
|
:<- [:wallet]
|
||||||
(fn [wallet]
|
(fn [wallet]
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
(ns status-im.ui.screens.wallet.transactions.views
|
(ns status-im.ui.screens.wallet.transactions.views
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.components.button.view :as button]
|
[status-im.components.button.view :as button]
|
||||||
[status-im.components.checkbox.view :as checkbox]
|
[status-im.components.checkbox.view :as checkbox]
|
||||||
[status-im.components.list.views :as list]
|
[status-im.components.list.views :as list]
|
||||||
[status-im.components.react :as react]
|
[status-im.components.react :as react]
|
||||||
[status-im.components.status-bar :as status-bar]
|
[status-im.components.status-bar :as status-bar]
|
||||||
[status-im.components.styles :as styles]
|
[status-im.components.styles :as styles]
|
||||||
[status-im.components.tabs.views :as tabs]
|
|
||||||
[status-im.components.toolbar-new.actions :as actions]
|
[status-im.components.toolbar-new.actions :as actions]
|
||||||
[status-im.components.toolbar-new.view :as toolbar]
|
[status-im.components.toolbar-new.view :as toolbar]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
|
@ -40,17 +38,14 @@
|
||||||
{:icon :icons/filter
|
{:icon :icons/filter
|
||||||
:handler #(utils/show-popup "TODO" "Not implemented") #_(re-frame/dispatch [:navigate-to-modal :wallet-transactions-sign-all])})
|
:handler #(utils/show-popup "TODO" "Not implemented") #_(re-frame/dispatch [:navigate-to-modal :wallet-transactions-sign-all])})
|
||||||
|
|
||||||
(defn toolbar-view [view-id unsigned-transactions-count]
|
(defn toolbar-view [current-tab unsigned-transactions-count]
|
||||||
[toolbar/toolbar2 {:flat? true}
|
[toolbar/toolbar2 {:flat? true}
|
||||||
toolbar/default-nav-back
|
toolbar/default-nav-back
|
||||||
[toolbar/content-title (i18n/label :t/transactions)]
|
[toolbar/content-title (i18n/label :t/transactions)]
|
||||||
(case @view-id
|
(case current-tab
|
||||||
:wallet-transactions-unsigned
|
0 [toolbar/actions [history-action]]
|
||||||
nil ;; TODO (andrey) implement [unsigned-action unsigned-transactions-count]
|
1 nil ;; TODO (andrey) implement [unsigned-action unsigned-transactions-count]
|
||||||
|
)])
|
||||||
:wallet-transactions-history
|
|
||||||
[toolbar/actions
|
|
||||||
[history-action]])])
|
|
||||||
|
|
||||||
(defn action-buttons [{:keys [id to value] :as transaction}]
|
(defn action-buttons [{:keys [id to value] :as transaction}]
|
||||||
[react/view {:style transactions.styles/action-buttons}
|
[react/view {:style transactions.styles/action-buttons}
|
||||||
|
@ -120,26 +115,6 @@
|
||||||
:render-fn render-transaction
|
:render-fn render-transaction
|
||||||
:empty-component (empty-text (i18n/label :t/transactions-unsigned-empty))}]]))
|
:empty-component (empty-text (i18n/label :t/transactions-unsigned-empty))}]]))
|
||||||
|
|
||||||
(defn unsigned-transactions-title [{:keys [uppercase? style]} title]
|
|
||||||
(let [unsigned-transactions-count (re-frame/subscribe [:wallet.transactions/unsigned-transactions-count])]
|
|
||||||
[react/view {:flex-direction :row}
|
|
||||||
[react/text {:style style
|
|
||||||
:uppercase? uppercase?}
|
|
||||||
(i18n/label :t/transactions-unsigned)]
|
|
||||||
(when (pos? @unsigned-transactions-count)
|
|
||||||
[react/text {:style (merge
|
|
||||||
style
|
|
||||||
{:color styles/color-gray10})}
|
|
||||||
(str " " @unsigned-transactions-count)])]))
|
|
||||||
|
|
||||||
(defn- tab-list [unsigned-transactions-count]
|
|
||||||
[{:view-id :wallet-transactions-history
|
|
||||||
:title (i18n/label :t/transactions-history)
|
|
||||||
:screen [history-list]}
|
|
||||||
{:view-id :wallet-transactions-unsigned
|
|
||||||
:title-fn unsigned-transactions-title
|
|
||||||
:screen [unsigned-list]}])
|
|
||||||
|
|
||||||
;; Filter history
|
;; Filter history
|
||||||
|
|
||||||
(defn- item-tokens [{:keys [symbol label checked?]}]
|
(defn- item-tokens [{:keys [symbol label checked?]}]
|
||||||
|
@ -181,26 +156,53 @@
|
||||||
[react/view {:style styles/flex}
|
[react/view {:style styles/flex}
|
||||||
[list/section-list {:sections filter-data}]]])
|
[list/section-list {:sections filter-data}]]])
|
||||||
|
|
||||||
(defn- main-section [view-id tabs]
|
(defn transactions-history-tab [{:keys [active?]}]
|
||||||
(let [prev-view-id (reagent/atom @view-id)]
|
[react/text {:uppercase? true
|
||||||
[tabs/swipable-tabs {:style transactions.styles/main-section
|
:style (transactions.styles/tab-title active?)}
|
||||||
:style-tabs transactions.styles/tabs
|
(i18n/label :t/transactions-history)])
|
||||||
:style-tab-active transactions.styles/tab-active
|
|
||||||
:on-view-change #(do (reset! prev-view-id @view-id)
|
|
||||||
(reset! view-id %))}
|
|
||||||
tabs prev-view-id view-id]))
|
|
||||||
|
|
||||||
;; TODO(yenda) must reflect selected wallet
|
(defview unsigned-transactions-tab [{:keys [active?]}]
|
||||||
|
(letsubs [unsigned-transactions-count [:wallet.transactions/unsigned-transactions-count]]
|
||||||
|
[react/view {:flex-direction :row}
|
||||||
|
[react/text {:style (transactions.styles/tab-title active?)
|
||||||
|
:uppercase? true}
|
||||||
|
(i18n/label :t/transactions-unsigned)]
|
||||||
|
(when (pos? unsigned-transactions-count)
|
||||||
|
[react/text {:style transactions.styles/tab-unsigned-transactions-count}
|
||||||
|
(str " " unsigned-transactions-count)])]))
|
||||||
|
|
||||||
|
(defview tab [scroll-to index content]
|
||||||
|
(letsubs [current-tab [:wallet.transactions/current-tab]]
|
||||||
|
(let [active? (= index current-tab)]
|
||||||
|
[react/view (transactions.styles/tab active?)
|
||||||
|
[react/touchable-highlight {:on-press #(scroll-to index)}
|
||||||
|
[react/view
|
||||||
|
[content {:active? active?}]]]])))
|
||||||
|
|
||||||
|
(defn swipable-tabs [current-tab]
|
||||||
|
(let [swiper (atom nil)]
|
||||||
|
(fn [current-tab]
|
||||||
|
(let [scroll-to (fn [index]
|
||||||
|
(.scrollBy @swiper (- index current-tab)))]
|
||||||
|
[react/view transactions.styles/main-section
|
||||||
|
[react/view transactions.styles/tabs-container
|
||||||
|
[tab scroll-to 0 transactions-history-tab]
|
||||||
|
[tab scroll-to 1 unsigned-transactions-tab]]
|
||||||
|
[react/swiper {:loop false
|
||||||
|
:shows-pagination false
|
||||||
|
:index current-tab
|
||||||
|
:ref #(reset! swiper %)
|
||||||
|
:on-index-changed #(re-frame/dispatch [:change-tab %])}
|
||||||
|
[history-list]
|
||||||
|
[unsigned-list]]]))))
|
||||||
|
|
||||||
(defview transactions []
|
(defview transactions []
|
||||||
(letsubs [unsigned-transactions-count [:wallet.transactions/unsigned-transactions-count]]
|
(letsubs [unsigned-transactions-count [:wallet.transactions/unsigned-transactions-count]
|
||||||
(let [tabs (tab-list unsigned-transactions-count)
|
current-tab [:wallet.transactions/current-tab]]
|
||||||
default-view (get-in tabs [0 :view-id])
|
|
||||||
view-id (reagent/atom default-view)]
|
|
||||||
[react/view {:style styles/flex}
|
[react/view {:style styles/flex}
|
||||||
[status-bar/status-bar]
|
[status-bar/status-bar]
|
||||||
[toolbar-view view-id unsigned-transactions-count]
|
[toolbar-view current-tab unsigned-transactions-count]
|
||||||
[main-section view-id tabs]])))
|
[swipable-tabs current-tab]]))
|
||||||
|
|
||||||
(defn- pretty-print-asset [symbol amount]
|
(defn- pretty-print-asset [symbol amount]
|
||||||
(case symbol
|
(case symbol
|
||||||
|
|
Loading…
Reference in New Issue