reworked main tabs using svg icons [#1748
This commit is contained in:
parent
1a6bfd06a6
commit
f88c3feaf6
|
@ -1,5 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
<g fill="none" fill-rule="evenodd">
|
|
||||||
<path fill="#939BA1" fill-rule="nonzero" d="M6,5.99539757 L6,14.0046024 C6,14.5443356 6.44661595,15 6.99754465,15 L15,15 L19,18 L19,5.99539757 C19,5.4556644 18.5529553,5 18.0014977,5 L6.99850233,5 C6.44748943,5 6,5.44565467 6,5.99539757 Z M6.99754465,17 C5.34334703,17 4,15.6502334 4,14.0046024 L4,5.99539757 C4,4.33970333 5.34429545,3 6.99850233,3 L18.0014977,3 C19.6557893,3 21,4.34933905 21,5.99539757 L21,18 C21,19.7818097 18.8457162,20.6741433 17.5857864,19.4142136 L14.1715729,17 L6.99754465,17 Z M10,11.5 C10.8284271,11.5 11.5,10.8284271 11.5,10 C11.5,9.17157288 10.8284271,8.5 10,8.5 C9.17157288,8.5 8.5,9.17157288 8.5,10 C8.5,10.8284271 9.17157288,11.5 10,11.5 Z M15,11.5 C15.8284271,11.5 16.5,10.8284271 16.5,10 C16.5,9.17157288 15.8284271,8.5 15,8.5 C14.1715729,8.5 13.5,9.17157288 13.5,10 C13.5,10.8284271 14.1715729,11.5 15,11.5 Z"/>
|
<path fill="#939BA1" fill-rule="nonzero" d="M6,5.99539757 L6,14.0046024 C6,14.5443356 6.44661595,15 6.99754465,15 L15,15 L19,18 L19,5.99539757 C19,5.4556644 18.5529553,5 18.0014977,5 L6.99850233,5 C6.44748943,5 6,5.44565467 6,5.99539757 Z M6.99754465,17 C5.34334703,17 4,15.6502334 4,14.0046024 L4,5.99539757 C4,4.33970333 5.34429545,3 6.99850233,3 L18.0014977,3 C19.6557893,3 21,4.34933905 21,5.99539757 L21,18 C21,19.7818097 18.8457162,20.6741433 17.5857864,19.4142136 L14.1715729,17 L6.99754465,17 Z M10,11.5 C10.8284271,11.5 11.5,10.8284271 11.5,10 C11.5,9.17157288 10.8284271,8.5 10,8.5 C9.17157288,8.5 8.5,9.17157288 8.5,10 C8.5,10.8284271 9.17157288,11.5 10,11.5 Z M15,11.5 C15.8284271,11.5 16.5,10.8284271 16.5,10 C16.5,9.17157288 15.8284271,8.5 15,8.5 C14.1715729,8.5 13.5,9.17157288 13.5,10 C13.5,10.8284271 14.1715729,11.5 15,11.5 Z"/>
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 940 B |
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.chat.views.input.animations.expandable
|
(ns status-im.chat.views.input.animations.expandable
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require [reagent.core :as r]
|
(:require [reagent.core :as r]
|
||||||
[reagent.impl.component :as rc]
|
[reagent.impl.component :as rc]
|
||||||
[re-frame.core :refer [dispatch subscribe]]
|
[re-frame.core :refer [dispatch subscribe]]
|
||||||
|
@ -45,12 +45,12 @@
|
||||||
:tension 60}))))))
|
:tension 60}))))))
|
||||||
|
|
||||||
(defview overlay-view []
|
(defview overlay-view []
|
||||||
[max-height (subscribe [:get-max-container-area-height])
|
(letsubs [max-height [:get-max-container-area-height]
|
||||||
layout-height (subscribe [:get :layout-height])
|
layout-height [:get :layout-height]
|
||||||
view-height-to (subscribe [:get :expandable-view-height-to-value])]
|
view-height-to [:get :expandable-view-height-to-value]]
|
||||||
(let [related-height (/ @view-height-to @max-height)]
|
(let [related-height (/ view-height-to max-height)]
|
||||||
(when (> related-height 0.6)
|
(when (> related-height 0.6)
|
||||||
[animated-view {:style (style/result-box-overlay @layout-height (- related-height (/ 0.4 related-height)))}])))
|
[animated-view {:style (style/result-box-overlay layout-height (- related-height (/ 0.4 related-height)))}]))))
|
||||||
|
|
||||||
(defn expandable-view [{:keys [key height hide-overlay?]} & _]
|
(defn expandable-view [{:keys [key height hide-overlay?]} & _]
|
||||||
(let [anim-value (anim/create-value 0)
|
(let [anim-value (anim/create-value 0)
|
||||||
|
|
|
@ -81,6 +81,8 @@
|
||||||
(concat
|
(concat
|
||||||
[svg (merge default-viewbox style)]
|
[svg (merge default-viewbox style)]
|
||||||
(icon-fn
|
(icon-fn
|
||||||
|
(cond
|
||||||
|
(keyword? color)
|
||||||
(case color
|
(case color
|
||||||
:dark st/icon-dark-color
|
:dark st/icon-dark-color
|
||||||
:gray st/icon-gray-color
|
:gray st/icon-gray-color
|
||||||
|
@ -88,6 +90,10 @@
|
||||||
:active st/color-blue4
|
:active st/color-blue4
|
||||||
:white st/color-white
|
:white st/color-white
|
||||||
:red st/icon-red-color
|
:red st/icon-red-color
|
||||||
|
st/icon-dark-color)
|
||||||
|
(string? color)
|
||||||
|
color
|
||||||
|
:else
|
||||||
st/icon-dark-color))))
|
st/icon-dark-color))))
|
||||||
(throw (js/Error. (str "Unknown icon: " name))))]))
|
(throw (js/Error. (str "Unknown icon: " name))))]))
|
||||||
|
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
(ns status-im.components.main-tabs
|
|
||||||
(:require-macros [status-im.utils.views :refer [defview]]
|
|
||||||
[cljs.core.async.macros :as am])
|
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
|
||||||
[reagent.core :as r]
|
|
||||||
[status-im.components.react :refer [view swiper]]
|
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
|
||||||
[status-im.components.drawer.view :refer [drawer-view]]
|
|
||||||
[status-im.components.tabs.bottom-shadow :refer [bottom-shadow-view]]
|
|
||||||
[status-im.ui.screens.chats-list.views :refer [chats-list]]
|
|
||||||
[status-im.ui.screens.discover.views :refer [discover]]
|
|
||||||
[status-im.ui.screens.contacts.views :refer [contact-groups-list]]
|
|
||||||
[status-im.ui.screens.wallet.main.views :refer [wallet]]
|
|
||||||
[status-im.components.tabs.views :refer [tabs]]
|
|
||||||
[status-im.components.tabs.styles :as st]
|
|
||||||
[status-im.components.styles :as common-st]
|
|
||||||
[status-im.i18n :refer [label]]
|
|
||||||
[cljs.core.async :as a]))
|
|
||||||
|
|
||||||
(def tab-list
|
|
||||||
[{:view-id :wallet
|
|
||||||
:title (label :t/wallet)
|
|
||||||
:screen wallet
|
|
||||||
:icon-inactive :icon_wallet_gray
|
|
||||||
:icon-active :icon_wallet_active}
|
|
||||||
{:view-id :chat-list
|
|
||||||
:title (label :t/chats)
|
|
||||||
:screen chats-list
|
|
||||||
:icon-inactive :icon_chats
|
|
||||||
:icon-active :icon_chats_active}
|
|
||||||
{:view-id :discover
|
|
||||||
:title (label :t/discover)
|
|
||||||
:screen discover
|
|
||||||
:icon-inactive :icon_discover
|
|
||||||
:icon-active :icon_discover_active}
|
|
||||||
{:view-id :contact-list
|
|
||||||
:title (label :t/contacts)
|
|
||||||
:screen contact-groups-list
|
|
||||||
:icon-inactive :icon_contacts
|
|
||||||
:icon-active :icon_contacts_active}])
|
|
||||||
|
|
||||||
(def tab->index (reduce #(assoc %1 (:view-id %2) (count %1)) {} tab-list))
|
|
||||||
|
|
||||||
(def index->tab (clojure.set/map-invert tab->index))
|
|
||||||
|
|
||||||
(defn get-tab-index [view-id]
|
|
||||||
(get tab->index view-id 0))
|
|
||||||
|
|
||||||
(defn scroll-to [prev-view-id view-id]
|
|
||||||
(let [p (get-tab-index prev-view-id)
|
|
||||||
n (get-tab-index view-id)]
|
|
||||||
(- n p)))
|
|
||||||
|
|
||||||
(defonce scrolling? (atom false))
|
|
||||||
|
|
||||||
(defn on-scroll-end [swiped? scroll-ended view-id]
|
|
||||||
(fn [_ state]
|
|
||||||
(when @scrolling?
|
|
||||||
(a/put! scroll-ended true))
|
|
||||||
(let [{:strs [index]} (js->clj state)
|
|
||||||
new-view-id (index->tab index)]
|
|
||||||
(when-not (= view-id new-view-id)
|
|
||||||
(reset! swiped? true)
|
|
||||||
(dispatch [:navigate-to-tab 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] (a/<! scroll-start)]
|
|
||||||
;; start scrolling
|
|
||||||
(reset! scrolling? true)
|
|
||||||
(.scrollBy swiper to)
|
|
||||||
;; lock loop until scroll ends
|
|
||||||
(a/alts! [scroll-ended (a/timeout 2000)])
|
|
||||||
(reset! scrolling? false)
|
|
||||||
(recur (a/<! scroll-start))))
|
|
||||||
|
|
||||||
(defn main-tabs []
|
|
||||||
(let [view-id (subscribe [:get :view-id])
|
|
||||||
prev-view-id (subscribe [:get :prev-view-id])
|
|
||||||
tabs-hidden? (subscribe [:tabs-hidden?])
|
|
||||||
main-swiper (r/atom nil)
|
|
||||||
swiped? (r/atom false)
|
|
||||||
scroll-start (a/chan 10)
|
|
||||||
scroll-ended (a/chan 10)
|
|
||||||
tabs-were-hidden? (atom @tabs-hidden?)]
|
|
||||||
(r/create-class
|
|
||||||
{:component-did-mount
|
|
||||||
#(start-scrolling-loop scroll-start scroll-ended)
|
|
||||||
:component-will-update
|
|
||||||
(fn []
|
|
||||||
(if @swiped?
|
|
||||||
(reset! swiped? false)
|
|
||||||
(when (and (= @tabs-were-hidden? @tabs-hidden?) @main-swiper)
|
|
||||||
(let [to (scroll-to @prev-view-id @view-id)]
|
|
||||||
(a/put! scroll-start [@main-swiper to]))))
|
|
||||||
(reset! tabs-were-hidden? @tabs-hidden?))
|
|
||||||
:display-name "main-tabs"
|
|
||||||
:reagent-render
|
|
||||||
(fn []
|
|
||||||
[view common-st/flex
|
|
||||||
[status-bar {:type (if (= @view-id :wallet) :wallet :main)}]
|
|
||||||
[view common-st/flex
|
|
||||||
[drawer-view
|
|
||||||
[view {:style common-st/flex}
|
|
||||||
[swiper (merge
|
|
||||||
(st/main-swiper @tabs-hidden?)
|
|
||||||
{:index (get-tab-index @view-id)
|
|
||||||
:loop false
|
|
||||||
:ref #(reset! main-swiper %)
|
|
||||||
:on-momentum-scroll-end (on-scroll-end swiped? scroll-ended @view-id)})
|
|
||||||
(doall
|
|
||||||
(map-indexed (fn [index {vid :view-id screen :screen}]
|
|
||||||
^{:key index} [screen (= @view-id vid)]) tab-list))]
|
|
||||||
[tabs {:style (st/tabs-container @tabs-hidden?)
|
|
||||||
:selected-view-id @view-id
|
|
||||||
:tab-list tab-list}]
|
|
||||||
(when-not @tabs-hidden?
|
|
||||||
[bottom-shadow-view])]]]])})))
|
|
|
@ -19,6 +19,7 @@
|
||||||
(def color-gray5 "#d9dae1")
|
(def color-gray5 "#d9dae1")
|
||||||
(def color-gray6 "#212121")
|
(def color-gray6 "#212121")
|
||||||
(def color-gray7 "#9fa3b4")
|
(def color-gray7 "#9fa3b4")
|
||||||
|
(def color-gray8 "#6E777E")
|
||||||
(def color-dark "#49545d")
|
(def color-dark "#49545d")
|
||||||
(def color-steel "#838b91")
|
(def color-steel "#838b91")
|
||||||
(def color-white "white")
|
(def color-white "white")
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
(def color-dark-blue-3 "#191f37")
|
(def color-dark-blue-3 "#191f37")
|
||||||
(def color-light-gray "#EEF2F5")
|
(def color-light-gray "#EEF2F5")
|
||||||
(def color-light-gray2 "#ececf0")
|
(def color-light-gray2 "#ececf0")
|
||||||
|
(def color-light-gray3 "#e8ebec")
|
||||||
(def color-red "red")
|
(def color-red "red")
|
||||||
(def color-red-2 "#d84b4b")
|
(def color-red-2 "#d84b4b")
|
||||||
(def color-red-3 "#FFC1BD")
|
(def color-red-3 "#FFC1BD")
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
(ns status-im.components.tabs.bottom-shadow
|
|
||||||
(:require [status-im.components.tabs.styles :as st]
|
|
||||||
[status-im.components.react :refer [linear-gradient]]
|
|
||||||
[status-im.utils.platform :refer [platform-specific]]))
|
|
||||||
|
|
||||||
(defn bottom-shadow-view []
|
|
||||||
(when (get-in platform-specific [:tabs :tab-shadows?])
|
|
||||||
[linear-gradient {:locations [0 0.98 1]
|
|
||||||
:colors ["rgba(24, 52, 76, 0)" "rgba(24, 52, 76, 0.085)" "rgba(24, 52, 76, 0.165)"]
|
|
||||||
:style (merge
|
|
||||||
st/bottom-gradient
|
|
||||||
(get-in platform-specific [:component-styles :bottom-gradient]))}]))
|
|
|
@ -1,29 +1,24 @@
|
||||||
(ns status-im.components.tabs.styles
|
(ns status-im.components.tabs.styles
|
||||||
(:require [status-im.components.styles :as st]
|
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||||
|
(:require [status-im.components.styles :as styles]
|
||||||
[status-im.utils.platform :as p]))
|
[status-im.utils.platform :as p]))
|
||||||
|
|
||||||
|
|
||||||
(def tabs-height (if p/ios? 62 56))
|
(def tabs-height (if p/ios? 52 56))
|
||||||
(def tab-height (dec tabs-height))
|
(def tab-height (dec tabs-height))
|
||||||
|
|
||||||
(def bottom-gradient
|
|
||||||
{:position :absolute
|
|
||||||
:bottom 55
|
|
||||||
:left 0
|
|
||||||
:right 0})
|
|
||||||
|
|
||||||
(defn tabs-container [hidden?]
|
(defn tabs-container [hidden?]
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
:bottom (if hidden? (- tabs-height) 0)
|
:bottom (if hidden? (- tabs-height) 0)
|
||||||
:left 0
|
:left 0
|
||||||
:right 0
|
:right 0
|
||||||
:height tabs-height
|
:height tabs-height
|
||||||
:background-color st/color-white
|
:background-color styles/color-white
|
||||||
:transform [{:translateY 1}]})
|
:transform [{:translateY 1}]})
|
||||||
|
|
||||||
(def tabs-container-line
|
(def tabs-container-line
|
||||||
{:border-top-width 1
|
{:border-top-width 1
|
||||||
:border-top-color "#D7D7D7"})
|
:border-top-color styles/color-light-gray3})
|
||||||
|
|
||||||
(def tabs-inner-container
|
(def tabs-inner-container
|
||||||
{:flexDirection :row
|
{:flexDirection :row
|
||||||
|
@ -38,17 +33,16 @@
|
||||||
:justifyContent :center
|
:justifyContent :center
|
||||||
:alignItems :center})
|
:alignItems :center})
|
||||||
|
|
||||||
(defn tab-title [active?]
|
(defnstyle tab-title [active?]
|
||||||
{:font-size (if-not (or active? p/ios?) 12 14)
|
{:ios {:font-size 11}
|
||||||
|
:android {:font-size 12}
|
||||||
|
:margin-top 3
|
||||||
:min-width 60
|
:min-width 60
|
||||||
:text-align :center
|
:text-align :center
|
||||||
:color (if active? st/color-light-blue st/color-gray4)})
|
:color (if active? styles/color-blue4 styles/color-gray8)})
|
||||||
|
|
||||||
(def tab-icon
|
(defn tab-icon [active?]
|
||||||
{:width 24
|
{:color (if active? styles/color-blue4 styles/color-gray4)})
|
||||||
:height 24
|
|
||||||
:marginBottom 1
|
|
||||||
:align-self :center})
|
|
||||||
|
|
||||||
(def tab-container
|
(def tab-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
|
|
@ -1,32 +1,21 @@
|
||||||
(ns status-im.components.tabs.views
|
(ns status-im.components.tabs.views
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
(:require [re-frame.core :refer [dispatch]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :as react]
|
||||||
animated-view
|
[status-im.components.icons.vector-icons :as vi]
|
||||||
text-input
|
[status-im.components.tabs.styles :as styles]))
|
||||||
text
|
|
||||||
image
|
|
||||||
touchable-highlight]]
|
|
||||||
[reagent.core :as r]
|
|
||||||
[status-im.components.tabs.styles :as st]
|
|
||||||
[status-im.components.animation :as anim]
|
|
||||||
[status-im.utils.platform :as p]))
|
|
||||||
|
|
||||||
(defn tab [{:keys [view-id title icon-active icon-inactive selected-view-id]}]
|
(defn- tab [{:keys [view-id title icon-active icon-inactive selected-view-id]}]
|
||||||
(let [active? (= view-id selected-view-id)]
|
(let [active? (= view-id selected-view-id)]
|
||||||
[touchable-highlight {:style st/tab
|
[react/touchable-highlight {:style styles/tab
|
||||||
:disabled active?
|
:disabled active?
|
||||||
:on-press #(dispatch [:navigate-to-tab view-id])}
|
:on-press #(dispatch [:navigate-to-tab view-id])}
|
||||||
[view {:style st/tab-container}
|
[react/view {:style styles/tab-container}
|
||||||
(when-let [icon (if active? icon-active icon-inactive)]
|
(when-let [icon (if active? icon-active icon-inactive)]
|
||||||
[view
|
[react/view
|
||||||
[image {:source {:uri icon}
|
[vi/icon icon (styles/tab-icon active?)]])
|
||||||
:style st/tab-icon}]])
|
[react/view
|
||||||
[view
|
[react/text {:style (styles/tab-title active?)}
|
||||||
[text (merge
|
|
||||||
(if-not icon-active {:uppercase? (get-in p/platform-specific [:uppercase?])})
|
|
||||||
{:style (st/tab-title active?)
|
|
||||||
:font (if (and p/ios? active?) :medium :regular)})
|
|
||||||
title]]]]))
|
title]]]]))
|
||||||
|
|
||||||
(defn- create-tab [index data selected-view-id]
|
(defn- create-tab [index data selected-view-id]
|
||||||
|
@ -35,16 +24,15 @@
|
||||||
:selected-view-id selected-view-id})]
|
:selected-view-id selected-view-id})]
|
||||||
[tab data]))
|
[tab data]))
|
||||||
|
|
||||||
(defn- tabs-container [style children]
|
(defview tabs-container [style children]
|
||||||
(let [tabs-hidden? (subscribe [:tabs-hidden?])
|
(letsubs [tabs-hidden? [:tabs-hidden?]]
|
||||||
shadows? (get-in p/platform-specific [:tabs :tab-shadows?])]
|
[react/animated-view {:style (merge style
|
||||||
[animated-view {:style (merge style
|
styles/tabs-container-line)
|
||||||
(when-not shadows? st/tabs-container-line))
|
:pointer-events (if tabs-hidden? :none :auto)}
|
||||||
:pointerEvents (if @tabs-hidden? :none :auto)}
|
|
||||||
children]))
|
children]))
|
||||||
|
|
||||||
(defn tabs [{:keys [style tab-list selected-view-id]}]
|
(defn tabs [{:keys [style tab-list selected-view-id]}]
|
||||||
[tabs-container style
|
[tabs-container style
|
||||||
(into
|
(into
|
||||||
[view st/tabs-inner-container]
|
[react/view styles/tabs-inner-container]
|
||||||
(map-indexed #(create-tab %1 %2 selected-view-id) tab-list))])
|
(map-indexed #(create-tab %1 %2 selected-view-id) tab-list))])
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
(ns status-im.ui.screens.main-tabs.views
|
||||||
|
(:require-macros [status-im.utils.views :as views]
|
||||||
|
[cljs.core.async.macros :as async-macros])
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.components.react :as react]
|
||||||
|
[status-im.components.tabs.styles :as styles]
|
||||||
|
[status-im.components.styles :as common-styles]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[cljs.core.async :as async]
|
||||||
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
|
[status-im.components.drawer.view :refer [drawer-view]]
|
||||||
|
[status-im.ui.screens.chats-list.views :refer [chats-list]]
|
||||||
|
[status-im.ui.screens.discover.views :refer [discover]]
|
||||||
|
[status-im.ui.screens.contacts.views :refer [contact-groups-list]]
|
||||||
|
[status-im.ui.screens.wallet.main.views :refer [wallet]]
|
||||||
|
[status-im.components.tabs.views :refer [tabs]]))
|
||||||
|
|
||||||
|
(def tab-list
|
||||||
|
[{:view-id :wallet
|
||||||
|
:title (i18n/label :t/wallet)
|
||||||
|
:screen wallet
|
||||||
|
:icon-inactive :icons/wallet
|
||||||
|
:icon-active :icons/wallet-active}
|
||||||
|
{:view-id :chat-list
|
||||||
|
:title (i18n/label :t/chats)
|
||||||
|
:screen chats-list
|
||||||
|
:icon-inactive :icons/chats
|
||||||
|
:icon-active :icons/chats-active}
|
||||||
|
{:view-id :discover
|
||||||
|
:title (i18n/label :t/discover)
|
||||||
|
:screen discover
|
||||||
|
:icon-inactive :icons/discover
|
||||||
|
:icon-active :icons/discover-active}
|
||||||
|
{:view-id :contact-list
|
||||||
|
:title (i18n/label :t/contacts)
|
||||||
|
:screen contact-groups-list
|
||||||
|
:icon-inactive :icons/contacts
|
||||||
|
:icon-active :icons/contacts-active}])
|
||||||
|
|
||||||
|
(def tab->index (reduce #(assoc %1 (:view-id %2) (count %1)) {} tab-list))
|
||||||
|
|
||||||
|
(def index->tab (clojure.set/map-invert tab->index))
|
||||||
|
|
||||||
|
(defn get-tab-index [view-id]
|
||||||
|
(get tab->index view-id 0))
|
||||||
|
|
||||||
|
(defn scroll-to [prev-view-id view-id]
|
||||||
|
(let [p (get-tab-index prev-view-id)
|
||||||
|
n (get-tab-index view-id)]
|
||||||
|
(- n p)))
|
||||||
|
|
||||||
|
(defonce scrolling? (atom false))
|
||||||
|
|
||||||
|
(defn on-scroll-end [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 index)]
|
||||||
|
(when-not (= view-id new-view-id)
|
||||||
|
(reset! swiped? true)
|
||||||
|
(re-frame/dispatch [:navigate-to-tab new-view-id])))))
|
||||||
|
|
||||||
|
(defn start-scrolling-loop
|
||||||
|
"Loop that synchronizes tabs scrolling to avoid an inconsistent state."
|
||||||
|
[scroll-start scroll-ended]
|
||||||
|
(async-macros/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))))
|
||||||
|
|
||||||
|
(views/defview main-tabs []
|
||||||
|
(views/letsubs [view-id [:get :view-id]
|
||||||
|
prev-view-id [:get :prev-view-id]
|
||||||
|
tabs-hidden? [:tabs-hidden?]
|
||||||
|
main-swiper (atom nil)
|
||||||
|
swiped? (atom false)
|
||||||
|
scroll-start (async/chan 10)
|
||||||
|
scroll-ended (async/chan 10)
|
||||||
|
tabs-were-hidden? (atom @tabs-hidden?)]
|
||||||
|
{:component-did-mount
|
||||||
|
(fn []
|
||||||
|
(start-scrolling-loop scroll-start scroll-ended))
|
||||||
|
:component-will-update
|
||||||
|
(fn []
|
||||||
|
(if @swiped?
|
||||||
|
(reset! swiped? false)
|
||||||
|
(when (and (= @tabs-were-hidden? tabs-hidden?) @main-swiper)
|
||||||
|
(let [to (scroll-to prev-view-id view-id)]
|
||||||
|
(async/put! scroll-start [@main-swiper to]))))
|
||||||
|
(reset! tabs-were-hidden? tabs-hidden?))}
|
||||||
|
[react/view common-styles/flex
|
||||||
|
[status-bar {:type (if (= view-id :wallet) :wallet :main)}]
|
||||||
|
[react/view common-styles/flex
|
||||||
|
[drawer-view
|
||||||
|
[react/view {:style common-styles/flex}
|
||||||
|
[react/swiper
|
||||||
|
(merge
|
||||||
|
(styles/main-swiper tabs-hidden?)
|
||||||
|
{:index (get-tab-index view-id)
|
||||||
|
:loop false
|
||||||
|
:ref #(reset! main-swiper %)
|
||||||
|
:on-momentum-scroll-end (on-scroll-end swiped? scroll-ended view-id)})
|
||||||
|
(doall
|
||||||
|
(map-indexed (fn [index {vid :view-id screen :screen}]
|
||||||
|
^{:key index} [screen (= view-id vid)]) tab-list))]
|
||||||
|
[tabs {:style (styles/tabs-container tabs-hidden?)
|
||||||
|
:selected-view-id view-id
|
||||||
|
:tab-list tab-list}]]]]]))
|
|
@ -4,7 +4,7 @@
|
||||||
[status-im.utils.platform :refer [android?]]
|
[status-im.utils.platform :refer [android?]]
|
||||||
[status-im.components.react :refer [view modal]]
|
[status-im.components.react :refer [view modal]]
|
||||||
[status-im.components.styles :as common-styles]
|
[status-im.components.styles :as common-styles]
|
||||||
[status-im.components.main-tabs :refer [main-tabs]]
|
[status-im.ui.screens.main-tabs.views :refer [main-tabs]]
|
||||||
[status-im.components.context-menu :refer [menu-context]]
|
[status-im.components.context-menu :refer [menu-context]]
|
||||||
|
|
||||||
[status-im.ui.screens.accounts.login.views :refer [login]]
|
[status-im.ui.screens.accounts.login.views :refer [login]]
|
||||||
|
@ -60,12 +60,10 @@
|
||||||
(when view-id
|
(when view-id
|
||||||
(let [current-view (validate-current-view view-id signed-up?)]
|
(let [current-view (validate-current-view view-id signed-up?)]
|
||||||
(let [component (case current-view
|
(let [component (case current-view
|
||||||
:wallet main-tabs
|
(:wallet :chat-list :discover :contact-list) main-tabs
|
||||||
:wallet-list wallet-list-screen
|
:wallet-list wallet-list-screen
|
||||||
:wallet-send-transaction send-transaction
|
:wallet-send-transaction send-transaction
|
||||||
:discover main-tabs
|
|
||||||
:discover-search-results discover-search-results
|
:discover-search-results discover-search-results
|
||||||
:chat-list main-tabs
|
|
||||||
:new-chat new-chat
|
:new-chat new-chat
|
||||||
:new-group new-group
|
:new-group new-group
|
||||||
:edit-contact-group edit-contact-group
|
:edit-contact-group edit-contact-group
|
||||||
|
@ -75,7 +73,6 @@
|
||||||
:edit-group-contact-list edit-contact-group-contact-list
|
:edit-group-contact-list edit-contact-group-contact-list
|
||||||
:edit-chat-group-contact-list edit-chat-group-contact-list
|
:edit-chat-group-contact-list edit-chat-group-contact-list
|
||||||
:new-public-chat new-public-chat
|
:new-public-chat new-public-chat
|
||||||
:contact-list main-tabs
|
|
||||||
:contact-toggle-list contact-toggle-list
|
:contact-toggle-list contact-toggle-list
|
||||||
:group-contacts contact-list
|
:group-contacts contact-list
|
||||||
:reorder-groups reorder-groups
|
:reorder-groups reorder-groups
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(defn atom? [sub]
|
(defn atom? [sub]
|
||||||
(or (vector? sub)
|
(or (vector? sub)
|
||||||
(and (seq sub)
|
(and (seq sub)
|
||||||
(#{'atom `reagent.core/atom} (first sub)))))
|
(#{`reagent.core/atom} (first sub)))))
|
||||||
|
|
||||||
(defn walk-sub [sub form->sym]
|
(defn walk-sub [sub form->sym]
|
||||||
(if (coll? sub)
|
(if (coll? sub)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns status-im.test.components.main-tabs
|
(ns status-im.test.components.main-tabs
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
[status-im.components.main-tabs :as tabs]))
|
[status-im.ui.screens.main-tabs.views :as tabs]))
|
||||||
|
|
||||||
(deftest tab->index
|
(deftest tab->index
|
||||||
(is (contains? tabs/tab->index :chat-list))
|
(is (contains? tabs/tab->index :chat-list))
|
||||||
|
|
Loading…
Reference in New Issue