Skip to content

Commit

Permalink
new bottom tab (react-navigation)
Browse files Browse the repository at this point in the history
  • Loading branch information
rasom committed Feb 20, 2019
1 parent 0fe4ac5 commit b8d4f29
Show file tree
Hide file tree
Showing 18 changed files with 236 additions and 146 deletions.
2 changes: 1 addition & 1 deletion src/status_im/accounts/login/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@
{:db (assoc-in db [:accounts/login :password] password)}
(navigation/navigate-to-cofx :progress nil)
(user-login false))
(navigation/navigate-to-clean cofx :login nil)))
(navigation/navigate-to-cofx cofx :login nil)))

(re-frame/reg-fx
:accounts.login/login
Expand Down
10 changes: 7 additions & 3 deletions src/status_im/chat/subs.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
[status-im.chat.constants :as chat.constants]
[status-im.chat.db :as chat.db]
[status-im.models.transactions :as transactions]
[status-im.utils.platform :as platform]))
[status-im.utils.platform :as platform]
[status-im.ui.components.bottom-bar.styles :as tabs-styles]))

(re-frame/reg-sub ::chats :chats)
(re-frame/reg-sub ::access-scope->command-id :access-scope->command-id)
Expand Down Expand Up @@ -75,8 +76,11 @@
:<- [:get :keyboard-height]
(fn [kb-height]
(cond
(and platform/iphone-x? (> kb-height 0)) (- kb-height 34)
platform/ios? kb-height
(and platform/iphone-x? (> kb-height 0))
(- kb-height 34 tabs-styles/tabs-height)
platform/ios? (- kb-height (if (> kb-height 0)
tabs-styles/tabs-height
0))
:default 0)))

(re-frame/reg-sub
Expand Down
129 changes: 129 additions & 0 deletions src/status_im/ui/components/bottom_bar/core.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
(ns status-im.ui.components.bottom-bar.core
(:require-macros [status-im.utils.views :as views])
(:require
[status-im.ui.components.animation :as animation]
[status-im.ui.components.bottom-bar.styles :as tabs.styles]
[reagent.core :as reagent]
[status-im.ui.components.react :as react]
[status-im.utils.platform :as platform]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.common.common :as components.common]
[status-im.i18n :as i18n]
[status-im.ui.components.styles :as common.styles]
[re-frame.core :as re-frame]))

(defn animate
([visible duration to]
(animate visible duration to nil))
([visible duration to callback]
(animation/start
(animation/timing visible
{:toValue to
:duration duration
:useNativeDriver true})
callback)))

(def tabs-list-data
[{:view-id :chat-stack
:content {:title (i18n/label :t/home)
:icon :main-icons/home}
:count-subscription :chats/unread-messages-number
:accessibility-label :home-tab-button}
{:view-id :wallet-stack
:content {:title (i18n/label :t/wallet)
:icon :main-icons/wallet}
:count-subscription :get-wallet-unread-messages-number
:accessibility-label :wallet-tab-button}
{:view-id :profile-stack
:content {:title (i18n/label :t/profile)
:icon :main-icons/profile}
:count-subscription :get-profile-unread-messages-number
:accessibility-label :profile-tab-button}])

(defn- tab-content [{:keys [title icon]}]
(fn [active? count]
[react/view {:style tabs.styles/tab-container}
[react/view
[vector-icons/icon icon (tabs.styles/tab-icon active?)]]
[react/view
[react/text {:style (tabs.styles/tab-title active?)}
title]]
(when (pos? count)
[react/view tabs.styles/counter-container
[react/view tabs.styles/counter
[components.common/counter count]]])]))

(def tabs-list (map #(update % :content tab-content) tabs-list-data))

(views/defview tab [view-id content active? accessibility-label count-subscription]
(views/letsubs [count [count-subscription]]
[react/touchable-highlight
(cond-> {:style common.styles/flex
:disabled active?
:on-press #(re-frame/dispatch [:navigate-to-tab view-id])}
accessibility-label
(assoc :accessibility-label accessibility-label))
[react/view
[content active? count]]]))

(defn tabs [current-view-id]
[react/view {:style tabs.styles/tabs-container}
(for [{:keys [content view-id accessibility-label count-subscription]} tabs-list]
^{:key view-id} [tab view-id content (= view-id current-view-id) accessibility-label count-subscription])])

(defn tabs-animation-wrapper [visible? keyboard-shown? tab]
[react/animated-view
{:style {:height tabs.styles/tabs-height
:bottom 0
:left 0
:right 0
:position (when keyboard-shown? :absolute)
:transform [{:translateY
(animation/interpolate
visible?
{:inputRange [0 1]
:outputRange [tabs.styles/tabs-height
0]})}]}}
[react/safe-area-view [tabs tab]]])

(def disappearance-duration 150)
(def appearance-duration 100)

(defn bottom-bar [_]
(let [keyboard-shown? (reagent/atom false)
visible? (animation/create-value 1)
listeners (atom [])]
(reagent/create-class
{:component-will-mount
(fn []
(when platform/android?
(reset!
listeners
[(.addListener react/keyboard "keyboardDidShow"
(fn []
(reset! keyboard-shown? true)
(animate visible?
disappearance-duration 0)))
(.addListener react/keyboard "keyboardDidHide"
(fn []
(reset! keyboard-shown? false)
(animate visible? appearance-duration 1)))])))
:component-will-unmount
(fn []
(when (not-empty @listeners)
(doseq [listener @listeners]
(when listener
(.remove listener)))))
:reagent-render
(fn [args]
(let [idx (.. (:navigation args)
-state
-index)
tab (case idx
0 :chat-stack
1 :wallet-stack
2 :profile-stack
:chat-stack)]
(if platform/ios?
[react/safe-area-view [tabs tab]]
[tabs-animation-wrapper visible? @keyboard-shown? tab])))})))
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
(ns status-im.ui.screens.main-tabs.styles
(:require [status-im.ui.components.styles :as styles]
[status-im.ui.components.colors :as colors]
(ns status-im.ui.components.bottom-bar.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform])
(:require-macros [status-im.utils.styles :refer [defnstyle]]))

Expand Down
2 changes: 1 addition & 1 deletion src/status_im/ui/components/desktop/tabs.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[taoensso.timbre :as log]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.screens.main-tabs.styles :as tabs.styles])
[status-im.ui.components.bottom-bar.styles :as tabs.styles])
(:require-macros [status-im.utils.views :as views]))

;;TODO copy-pate with minimum modifications of status-react tabs
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/ui/screens/group/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[status-im.ui.screens.main-tabs.styles :as main-tabs.styles]
[status-im.ui.components.bottom-bar.styles :as main-tabs.styles]
[status-im.ui.components.styles :as components.styles]
[status-im.constants :as constants]
[status-im.utils.platform :as utils.platform]
Expand Down
88 changes: 15 additions & 73 deletions src/status_im/ui/screens/main_tabs/views.cljs
Original file line number Diff line number Diff line change
@@ -1,84 +1,26 @@
(ns status-im.ui.screens.main-tabs.views
(:require-macros [status-im.utils.views :as views])
(:require [status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar.view]
[status-im.ui.components.styles :as common.styles]
[status-im.ui.screens.home.views :as home]
[status-im.ui.screens.wallet.main.views :as wallet.main]
[status-im.ui.screens.main-tabs.styles :as styles]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.components.common.common :as components.common]))

(def tabs-list-data
[{:view-id :home
:content {:title (i18n/label :t/home)
:icon :main-icons/home}
:count-subscription :chats/unread-messages-number
:accessibility-label :home-tab-button}
{:view-id :wallet
:content {:title (i18n/label :t/wallet)
:icon :main-icons/wallet}
:count-subscription :get-wallet-unread-messages-number
:accessibility-label :wallet-tab-button}
{:view-id :my-profile
:content {:title (i18n/label :t/profile)
:icon :main-icons/profile}
:count-subscription :get-profile-unread-messages-number
:accessibility-label :profile-tab-button}])

(defn- tab-content [{:keys [title icon]}]
(fn [active? count]
[react/view {:style styles/tab-container}
[react/view
[vector-icons/icon icon (styles/tab-icon active?)]]
[react/view
[react/text {:style (styles/tab-title active?)}
title]]
(when (pos? count)
[react/view styles/counter-container
[react/view styles/counter
[components.common/counter count]]])]))

(def tabs-list (map #(update % :content tab-content) tabs-list-data))

(views/defview tab [view-id content active? accessibility-label count-subscription]
(views/letsubs [count [count-subscription]]
[react/touchable-highlight
(cond-> {:style common.styles/flex
:disabled active?
:on-press #(re-frame/dispatch [:navigate-to-tab view-id])}
accessibility-label
(assoc :accessibility-label accessibility-label))
[react/view
[content active? count]]]))

(defn tabs [current-view-id]
[react/view {:style styles/tabs-container}
(for [{:keys [content view-id accessibility-label count-subscription]} tabs-list]
^{:key view-id} [tab view-id content (= view-id current-view-id) accessibility-label count-subscription])])
[status-im.ui.screens.profile.user.views :as profile.user]))

(views/defview main-container [view-id]
(views/letsubs
[tab-bar-visible? [:tab-bar-visible?]]
;; :should-component-update is called only when props are changed,
;; that's why view-id is passed as a prop here. main-tabs component will be
;; rendered while next screen from stack navigator is shown, so we have
;; to prevent re-rendering to avoid no clause exception in case form
{:should-component-update
(fn [_ _ [_ new-view-id]]
(contains? #{:home :wallet :my-profile} new-view-id))}
[react/view common.styles/main-container
(case view-id
:home [home/home-wrapper]
:wallet [wallet.main/wallet]
:my-profile [profile.user/my-profile]
nil)

(when tab-bar-visible?
[tabs view-id])]))
;; :should-component-update is called only when props are changed,
;; that's why view-id is passed as a prop here. main-tabs component will be
;; rendered while next screen from stack navigator is shown, so we have
;; to prevent re-rendering to avoid no clause exception in case form
{:should-component-update
(fn [_ _ [_ new-view-id]]
(contains? #{:home :wallet :my-profile} new-view-id))}
[react/view common.styles/main-container
(case view-id
:home [home/home-wrapper]
:wallet [wallet.main/wallet]
:my-profile [profile.user/my-profile]
nil)])

(defn main-tabs [view-id]
[react/view common.styles/flex
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/ui/screens/pairing/views.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[reagent.core :as reagent]
[clojure.string :as string]
[status-im.utils.config :as config]
[status-im.ui.screens.main-tabs.styles :as main-tabs.styles]
[status-im.ui.components.bottom-bar.styles :as main-tabs.styles]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.ui.screens.home.styles :as home.styles]
Expand Down
84 changes: 41 additions & 43 deletions src/status_im/ui/screens/routing/chat_stack.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,44 @@
(:require [status-im.utils.config :as config]))

(def chat-stack
{:name :chat-stack
:screens [{:name :chat-main-stack
:screens (cond->
[:home
:chat
:profile
:new
:new-chat
:qr-scanner
:take-picture
:new-group
:add-participants-toggle-list
:contact-toggle-list
:group-chat-profile
:new-public-chat
:open-dapp
:dapp-description
:browser
:stickers
:stickers-pack
:login]

config/hardwallet-enabled?
(concat [:hardwallet-connect :enter-pin]))
:config {:initialRouteName :home}}
:wallet-modal
:chat-modal
:show-extension-modal
:stickers-pack-modal
{:name :wallet-send-modal-stack
:screens [:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-onboarding-setup-modal}}
:wallet-sign-message-modal]
:config {:mode :modal
:initialRouteName :chat-main-stack}})
{:name :chat-stack
:screens [{:name :chat-main-stack
:screens (cond->
[:home
:chat
:profile
:new
:new-chat
:qr-scanner
:take-picture
:new-group
:add-participants-toggle-list
:contact-toggle-list
:group-chat-profile
:new-public-chat
:open-dapp
:dapp-description
:browser
:stickers
:stickers-pack]
config/hardwallet-enabled?
(concat [:hardwallet-connect :enter-pin]))
:config {:initialRouteName :home}}
:wallet-modal
:chat-modal
:show-extension-modal
:stickers-pack-modal
{:name :wallet-send-modal-stack
:screens [:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-send-transaction-modal}}
{:name :wallet-send-modal-stack-with-onboarding
:screens [:wallet-onboarding-setup-modal
:wallet-send-transaction-modal
:wallet-transaction-sent-modal
:wallet-transaction-fee]
:config {:initialRouteName :wallet-onboarding-setup-modal}}
:wallet-sign-message-modal]
:config {:mode :modal
:initialRouteName :chat-main-stack}})
Loading

0 comments on commit b8d4f29

Please sign in to comment.