Switcher & navigation 2 foundation (#13167)
This commit is contained in:
parent
bcdb3c4194
commit
2a81814992
Binary file not shown.
After Width: | Height: | Size: 813 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 735 B |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
|
@ -47,6 +47,7 @@
|
|||
:ValueXY (fn [])
|
||||
:View {}
|
||||
:FlatList {}
|
||||
:Image {}
|
||||
:ScrollView {}
|
||||
:Text {}}
|
||||
:Easing {:bezier (fn [])
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
["@react-native-community/hooks" :as hooks]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]))
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
|
||||
|
||||
|
@ -74,6 +75,9 @@
|
|||
(def animated-view
|
||||
(reagent/adapt-react-class (.-View ^js animated)))
|
||||
|
||||
(def animated-image-view
|
||||
(reagent/adapt-react-class (.-Image ^js animated)))
|
||||
|
||||
(def ui-manager (.-UIManager ^js rn))
|
||||
|
||||
(def layout-animation (.-LayoutAnimation ^js rn))
|
||||
|
@ -103,6 +107,10 @@
|
|||
:delete #js {:type (:ease-in-ease-out layout-animation-types)
|
||||
:property (:opacity layout-animation-properties)}}})
|
||||
|
||||
(defonce enable-layout-animations
|
||||
(when (and platform/android? config/quo-preview-enabled?)
|
||||
(.setLayoutAnimationEnabledExperimental ^js ui-manager true)))
|
||||
|
||||
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js rn)))
|
||||
|
||||
;; Flat-list
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
[_ _]
|
||||
(let [pressed (reagent/atom false)]
|
||||
(fn [{:keys [on-press disabled type size before after above width
|
||||
on-long-press accessibility-label icon]
|
||||
on-long-press accessibility-label icon style]
|
||||
:or {type :primary
|
||||
size 40}}
|
||||
children]
|
||||
|
@ -126,7 +126,8 @@
|
|||
{:on-press-out (fn []
|
||||
(reset! pressed nil))})
|
||||
|
||||
[rn/view {:style (style-container
|
||||
[rn/view {:style (merge
|
||||
(style-container
|
||||
type
|
||||
size
|
||||
disabled
|
||||
|
@ -136,7 +137,8 @@
|
|||
above
|
||||
width
|
||||
before
|
||||
after)}
|
||||
after)
|
||||
style)}
|
||||
(when above
|
||||
[rn/view
|
||||
[quo2.icons/icon above {:container-style {:margin-bottom 2}
|
||||
|
|
|
@ -29,5 +29,6 @@
|
|||
(let [this (reagent/current-component)
|
||||
props (reagent/props this)
|
||||
style (text-style props)]
|
||||
(into [rn/text {:style style}]
|
||||
(into [rn/text (merge {:style style}
|
||||
(dissoc props :style :size :align :weight :color))]
|
||||
(reagent/children this))))
|
|
@ -34,6 +34,13 @@
|
|||
(def neutral-50-opa-30 (alpha neutral-50 0.3))
|
||||
(def neutral-50-opa-40 (alpha neutral-50 0.4))
|
||||
|
||||
;;70 with transparency
|
||||
(def neutral-70-opa-60 (alpha neutral-70 0.6))
|
||||
(def neutral-70-opa-70 (alpha neutral-70 0.7))
|
||||
(def neutral-70-opa-80 (alpha neutral-70 0.8))
|
||||
(def neutral-70-opa-90 (alpha neutral-70 0.9))
|
||||
(def neutral-70-opa-95 (alpha neutral-70 0.95))
|
||||
|
||||
;;80 with transparency
|
||||
(def neutral-80-opa-60 (alpha neutral-80 0.6))
|
||||
(def neutral-80-opa-70 (alpha neutral-80 0.7))
|
||||
|
@ -176,5 +183,15 @@
|
|||
(def info-50-opa-30 (alpha info-50 0.3))
|
||||
(def info-50-opa-40 (alpha info-50 0.4))
|
||||
|
||||
;;;;Switcher
|
||||
(def switcher-background "#040B14")
|
||||
|
||||
;;switcher-screen with transparency
|
||||
(def switcher-background-opa-60 (alpha switcher-background 0.6))
|
||||
(def switcher-background-opa-70 (alpha switcher-background 0.7))
|
||||
(def switcher-background-opa-80 (alpha switcher-background 0.8))
|
||||
(def switcher-background-opa-90 (alpha switcher-background 0.9))
|
||||
(def switcher-background-opa-95 (alpha switcher-background 0.95))
|
||||
|
||||
(defn theme-colors [light dark]
|
||||
(if (theme/dark?) dark light))
|
|
@ -10,6 +10,7 @@
|
|||
[quo.design-system.colors :as colors]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.navigation :as navigation]
|
||||
[status-im.navigation2 :as navigation2]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.utils :as utils]
|
||||
|
@ -263,6 +264,15 @@
|
|||
(navigation/pop-to-root-tab % :chat-stack))
|
||||
(navigation/navigate-to-cofx :chat nil))))
|
||||
|
||||
(fx/defn navigate-to-chat-nav2
|
||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||
{:events [:chat.ui/navigate-to-chat-nav2]}
|
||||
[{db :db :as cofx} chat-id from-switcher?]
|
||||
(fx/merge cofx
|
||||
{:db (assoc db :current-chat-id chat-id)}
|
||||
(preload-chat-data chat-id)
|
||||
(navigation2/navigate-to-nav2 :chat chat-id nil from-switcher?)))
|
||||
|
||||
(fx/defn handle-clear-history-response
|
||||
{:events [::history-cleared]}
|
||||
[{:keys [db]} chat-id response]
|
||||
|
|
|
@ -63,7 +63,9 @@
|
|||
[status-im.multiaccounts.login.core :as login.core]
|
||||
[status-im.signing.core :as signing]
|
||||
status-im.wallet-connect.core
|
||||
status-im.wallet-connect-legacy.core))
|
||||
status-im.wallet-connect-legacy.core
|
||||
status-im.navigation2
|
||||
status-im.navigation2.core))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
(ns status-im.navigation2
|
||||
(:require [status-im.utils.fx :as fx]
|
||||
[status-im.utils.datetime :as datetime]))
|
||||
|
||||
(def parent-stack (atom :home-stack))
|
||||
|
||||
(fx/defn init-root-nav2
|
||||
{:events [:init-root-nav2]}
|
||||
[_ root-id]
|
||||
{:init-root-fx-nav2 root-id})
|
||||
|
||||
(fx/defn open-modal-nav2
|
||||
{:events [:open-modal-nav2]}
|
||||
[_ modal]
|
||||
{:open-modal-fx-nav2 modal})
|
||||
|
||||
(fx/defn close-modal-nav2
|
||||
{:events [:close-modal-nav2]}
|
||||
[_ modal]
|
||||
{:close-modal-fx-nav2 modal})
|
||||
|
||||
(defn navigate-from-home-stack [go-to-view-id id db]
|
||||
(reset! parent-stack go-to-view-id)
|
||||
{:navigate-to-fx-nav2 [go-to-view-id id]
|
||||
:db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id
|
||||
:id id
|
||||
:clock (datetime/timestamp)})})
|
||||
|
||||
(defn navigate-from-switcher [go-to-view-id id db from-home?]
|
||||
(reset! parent-stack go-to-view-id)
|
||||
{:navigate-from-switcher-fx [go-to-view-id id from-home?]
|
||||
:db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id
|
||||
:id id
|
||||
:clock (datetime/timestamp)})})
|
||||
|
||||
(fx/defn navigate-to-nav2
|
||||
{:events [:navigate-to-nav2]}
|
||||
[{:keys [db] :as cofx} go-to-view-id id screen-params from-switcher?]
|
||||
(let [view-id (:view-id db)
|
||||
stacks (:navigation2/navigation2-stacks db)
|
||||
from-home? (= view-id :home-stack)]
|
||||
(if from-switcher?
|
||||
(navigate-from-switcher go-to-view-id id db from-home?)
|
||||
(if from-home?
|
||||
(navigate-from-home-stack go-to-view-id id db)
|
||||
;; TODO(parvesh) - new stacks created from other screens should be stacked on current stack, instead of creating new entry
|
||||
(navigate-from-home-stack go-to-view-id id db)))))
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
(ns status-im.navigation2.core
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.screens.views :as views]
|
||||
[status-im.navigation2.utils :as nav2-utils]
|
||||
[status-im.navigation2.roots :as roots]
|
||||
[status-im.navigation.roots :as nav-roots]
|
||||
["react-native-navigation" :refer (Navigation)]))
|
||||
|
||||
(def tab-key-idx {:home 0
|
||||
:communities 1
|
||||
:wallet 2
|
||||
:browser 3})
|
||||
|
||||
(defonce set-navigation-default-options
|
||||
(.setDefaultOptions Navigation (clj->js {:options {:topBar {:visible false}}})))
|
||||
|
||||
;; TODO (parvesh) - improve open-modal and close-modal
|
||||
(defn open-modal [comp]
|
||||
(.showModal Navigation
|
||||
(clj->js {:stack {:children
|
||||
[{:component
|
||||
{:name comp
|
||||
:id comp
|
||||
:options {:topBar {:visible false}}}}]}})))
|
||||
|
||||
(defn close-modal [_])
|
||||
|
||||
(defn close-all-modals []
|
||||
(.dismissAllModals Navigation))
|
||||
|
||||
(defn get-id [comp id]
|
||||
(str comp "-" id))
|
||||
|
||||
(defn get-options [show-topbar? options]
|
||||
(if show-topbar?
|
||||
(merge options
|
||||
(nav-roots/status-bar-options)
|
||||
(nav-roots/merge-top-bar (nav-roots/topbar-options) options))
|
||||
{:topBar {:visible false}}))
|
||||
|
||||
(defn change-stack-root [[comp _]]
|
||||
(let [{:keys [options]} (get views/screens comp)]
|
||||
(.setStackRoot Navigation
|
||||
(name comp)
|
||||
(clj->js {:stack {:id comp
|
||||
:children [{:component {:id comp
|
||||
:name comp
|
||||
:options (get-options false options)}}]}}))))
|
||||
|
||||
(defn navigate [[comp _]]
|
||||
(let [{:keys [options]} (get views/screens comp)]
|
||||
(reset! nav2-utils/container-stack-view-id comp)
|
||||
(.push Navigation
|
||||
(name :home-stack)
|
||||
(clj->js {:stack {:id comp
|
||||
:children [{:component {:id comp
|
||||
:name comp
|
||||
:options (get-options false options)}}]}}))))
|
||||
|
||||
(defn navigate-from-switcher [[comp id from-home?]]
|
||||
(if from-home?
|
||||
(navigate [comp id])
|
||||
(change-stack-root [comp id])))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:init-root-fx-nav2
|
||||
(fn [new-root-id]
|
||||
(reset! nav2-utils/container-stack-view-id new-root-id)
|
||||
(.setRoot Navigation (clj->js (get (roots/roots) new-root-id)))))
|
||||
|
||||
(re-frame/reg-fx :open-modal-fx-nav2 open-modal)
|
||||
|
||||
(re-frame/reg-fx :close-modal-fx-nav2 close-modal)
|
||||
|
||||
(re-frame/reg-fx :navigate-to-fx-nav2 navigate)
|
||||
|
||||
(re-frame/reg-fx :navigate-from-switcher-fx navigate-from-switcher)
|
|
@ -0,0 +1,27 @@
|
|||
(ns status-im.navigation2.home-stack
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.screens.main :as quo2.preview]
|
||||
[status-im.switcher.switcher :as switcher]
|
||||
[status-im.ui.screens.home.views :as home]
|
||||
[status-im.switcher.constants :as switcher-constants]
|
||||
[status-im.ui.screens.browser.empty-tab.views :as empty-tab]
|
||||
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
||||
[status-im.switcher.bottom-tabs :as bottom-tabs]))
|
||||
|
||||
;; TODO(parvesh) - improve stack changing performance (load all stacks at once)
|
||||
(defn stack-view []
|
||||
(let [{:keys [width height]} (switcher-constants/dimensions)]
|
||||
;; bottom-tabs-height (switcher-constants/bottom-tabs-height)]
|
||||
[rn/view {:style {:width width
|
||||
:height (- height 80)}} ;; TODO(parvesh) - add height for ios
|
||||
(case @bottom-tabs/selected-tab-id
|
||||
:chats-stack [home/home]
|
||||
:communities-stack [quo2.preview/main-screen]
|
||||
:wallet-stack [wallet.accounts/accounts-overview]
|
||||
:browser-stack [empty-tab/empty-tab])]))
|
||||
|
||||
(defn home []
|
||||
[:<>
|
||||
[stack-view]
|
||||
[bottom-tabs/bottom-tabs]
|
||||
[switcher/switcher :home-stack]])
|
|
@ -0,0 +1,9 @@
|
|||
(ns status-im.navigation2.roots)
|
||||
|
||||
(defn roots []
|
||||
{:home-stack
|
||||
{:root
|
||||
{:stack {:id :home-stack
|
||||
:children [{:component {:name :home-stack
|
||||
:id :home-stack
|
||||
:options {:topBar {:visible false}}}}]}}}})
|
|
@ -0,0 +1,6 @@
|
|||
(ns status-im.navigation2.screens
|
||||
(:require [status-im.navigation2.home-stack :as home-stack]))
|
||||
|
||||
(def screens [{:name :home-stack
|
||||
:insets {:top false}
|
||||
:component home-stack/home}])
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im.navigation2.stack-with-switcher
|
||||
(:require [status-im.switcher.switcher :as switcher]))
|
||||
|
||||
(defn overlap-stack [comp view-id]
|
||||
[:<>
|
||||
[comp]
|
||||
[switcher/switcher view-id]])
|
|
@ -0,0 +1,3 @@
|
|||
(ns status-im.navigation2.utils)
|
||||
|
||||
(defonce container-stack-view-id (atom nil))
|
|
@ -87,6 +87,7 @@
|
|||
(reg-root-key-sub :home-items-show-number :home-items-show-number)
|
||||
(reg-root-key-sub :waku/v2-peer-stats :peer-stats)
|
||||
(reg-root-key-sub :visibility-status-updates :visibility-status-updates)
|
||||
(reg-root-key-sub :navigation2/navigation2-stacks :navigation2/navigation2-stacks)
|
||||
|
||||
;;NOTE this one is not related to ethereum network
|
||||
;; it is about cellular network/ wifi network
|
||||
|
@ -2946,3 +2947,19 @@
|
|||
:<- [:bookmarks]
|
||||
(fn [bookmarks]
|
||||
(into {} (remove #(:removed (second %)) bookmarks))))
|
||||
|
||||
;; NAVIGATION2
|
||||
|
||||
|
||||
(re-frame/reg-sub
|
||||
:navigation2/switcher-cards
|
||||
:<- [:navigation2/navigation2-stacks]
|
||||
(fn [stacks [_ toggle-switcher-screen]]
|
||||
(sort-by :clock >
|
||||
(reduce (fn [acc stack-vector]
|
||||
(let [{:keys [type clock id]} (get stack-vector 1)]
|
||||
(conj acc {:type type
|
||||
:clock clock
|
||||
:id id
|
||||
:toggle-switcher-screen toggle-switcher-screen})))
|
||||
'() stacks))))
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
(ns status-im.switcher.animation
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.switcher.constants :as constants]
|
||||
[status-im.ui.components.animation :as anim]))
|
||||
|
||||
(def bottom-tabs-opacity (anim/create-value 1))
|
||||
(def bottom-tabs-position (anim/create-value 0))
|
||||
|
||||
;; TODO(parvesh): Use 300, after using dispatch-later for opening card(otherwise pending animation issue)
|
||||
;; or OnAnimationEnd
|
||||
(def layout-animation #js {:duration 250
|
||||
:create #js {:type (:ease-in-ease-out rn/layout-animation-types)
|
||||
:property (:scale-xy rn/layout-animation-properties)}
|
||||
:update #js {:type (:ease-in-ease-out rn/layout-animation-types)
|
||||
:property (:scale-xy rn/layout-animation-properties)}
|
||||
:delete #js {:type (:ease-in-ease-out rn/layout-animation-types)
|
||||
:property (:scale-xy rn/layout-animation-properties)}})
|
||||
|
||||
(defn animate-layout [show? anim-values]
|
||||
(let [{:keys [width height]} (constants/dimensions)
|
||||
target-radius (- (max width height)
|
||||
constants/switcher-button-radius)]
|
||||
(rn/configure-next layout-animation)
|
||||
(reset! (:switcher-screen-radius anim-values) (if show? target-radius 1))
|
||||
(reagent/flush)))
|
||||
|
||||
(defn timing-animation [property toValue]
|
||||
(anim/timing property {:toValue toValue
|
||||
:duration 300
|
||||
:useNativeDriver true}))
|
||||
|
||||
(defn animate-components [show? view-id anim-values]
|
||||
(anim/start
|
||||
(anim/parallel
|
||||
(into
|
||||
[(timing-animation (:switcher-button-opacity anim-values) (if show? 0 1))
|
||||
(timing-animation (:switcher-close-button-icon-opacity anim-values) (if show? 1 0))
|
||||
(timing-animation (:switcher-close-button-background-opacity anim-values) (if show? 0.2 0))]
|
||||
(when (= view-id :home-stack)
|
||||
[(timing-animation bottom-tabs-opacity (if show? 0 1))
|
||||
(timing-animation bottom-tabs-position (if show? (constants/bottom-tabs-height) 0))])))))
|
||||
|
||||
(defn animate [show? view-id anim-values]
|
||||
(reagent/flush)
|
||||
(animate-layout show? anim-values)
|
||||
(animate-components show? view-id anim-values))
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.switcher.bottom-tabs
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.switcher.styles :as styles]
|
||||
[status-im.ui.components.icons.icons :as icons]))
|
||||
|
||||
(def selected-tab-id (reagent/atom :chats-stack))
|
||||
|
||||
(defn bottom-tab-pressed [tab-id]
|
||||
(when-not (= tab-id @selected-tab-id)
|
||||
(reset! selected-tab-id tab-id)))
|
||||
|
||||
;; TODO(parvesh) - reimplement tab with counter, once design is complete
|
||||
;; (implement natively, for performance improvement)
|
||||
(defn bottom-tab [icon tab-id]
|
||||
[rn/touchable-opacity {:style {:padding 15}
|
||||
:active-opacity 1
|
||||
:on-press #(bottom-tab-pressed tab-id)}
|
||||
[icons/icon icon (styles/bottom-tab-icon
|
||||
(if (= tab-id @selected-tab-id)
|
||||
:bottom-tabs-selected-tab
|
||||
:bottom-tabs-non-selected-tab))]])
|
||||
|
||||
(defn bottom-tabs []
|
||||
[rn/animated-view {:style (styles/bottom-tabs)}
|
||||
[bottom-tab :main-icons/redesign-messages :chats-stack]
|
||||
[bottom-tab :main-icons/communities :communities-stack]
|
||||
[rn/view {:width 10}]
|
||||
[bottom-tab :main-icons/redesign-wallet :wallet-stack]
|
||||
[bottom-tab :main-icons/browser :browser-stack]])
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.switcher.cards.messaging-card
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.components.text :as text]
|
||||
[status-im.constants :as constants]
|
||||
[quo2.components.button :as button]
|
||||
[status-im.utils.handlers :refer [>evt <sub]]
|
||||
[status-im.switcher.cards.styles :as styles]))
|
||||
|
||||
(defn on-press [id toggle-switcher-screen]
|
||||
(toggle-switcher-screen)
|
||||
(>evt [:chat.ui/navigate-to-chat-nav2 id true]))
|
||||
|
||||
;; TODO - add last message for other content types
|
||||
(defn last-message [{:keys [content content-type]}]
|
||||
(cond
|
||||
(= constants/content-type-text content-type)
|
||||
[text/text (styles/messaging-card-last-message-text-props) (:text content)]))
|
||||
|
||||
(defn card [{:keys [id toggle-switcher-screen]}]
|
||||
(let [chat (<sub [:chats/chat id])]
|
||||
[rn/touchable-without-feedback {:on-press #(on-press id toggle-switcher-screen)}
|
||||
[rn/view {:style (styles/messaging-card-main-container)}
|
||||
[rn/view {:style (styles/messaging-card-secondary-container)}
|
||||
[text/text (styles/messaging-card-title-props) (:alias chat)]
|
||||
[text/text (styles/messaging-card-subtitle-props) "Message"]
|
||||
[rn/view {:style (styles/messaging-card-details-container)}
|
||||
[last-message (:last-message chat)]]]
|
||||
[rn/view {:style (styles/messaging-card-avatar-container)}]
|
||||
[button/button (styles/messaging-card-close-button-props) :main-icons/close]]]))
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
(ns status-im.switcher.cards.styles
|
||||
(:require [quo.theme :as theme]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(def themes
|
||||
{:light {:messaging-card-container-background-color "#26A69A"
|
||||
:messaging-card-secondary-container-background-color colors/white
|
||||
:messaging-card-title-color colors/black
|
||||
:messaging-card-subtitle-color colors/neutral-50
|
||||
:messaging-card-last-message-text-color colors/black
|
||||
:messaging-card-close-button-bg-color colors/white-opa-50
|
||||
:messaging-card-close-button-icon-color colors/black}
|
||||
:dark {:messaging-card-container-background-color "#26A69A"
|
||||
:messaging-card-secondary-container-background-color colors/neutral-90
|
||||
:messaging-card-title-color colors/white
|
||||
:messaging-card-subtitle-color colors/neutral-40
|
||||
:messaging-card-last-message-text-color colors/white
|
||||
:messaging-card-close-button-bg-color colors/neutral-80-opa-60
|
||||
:messaging-card-close-button-icon-color colors/white}})
|
||||
|
||||
(defn get-color [key]
|
||||
(get-in themes [(theme/get-theme) key]))
|
||||
|
||||
;; Messaging Card
|
||||
|
||||
(defn messaging-card-main-container []
|
||||
{:width 160
|
||||
:height 172
|
||||
:border-radius 16
|
||||
:margin 8
|
||||
:background-color (get-color :messaging-card-container-background-color)})
|
||||
|
||||
(defn messaging-card-secondary-container []
|
||||
{:width 160
|
||||
:height 132
|
||||
:background-color (get-color :messaging-card-secondary-container-background-color)
|
||||
:border-radius 16
|
||||
:position :absolute
|
||||
:bottom 0})
|
||||
|
||||
(defn messaging-card-title []
|
||||
{:position :absolute
|
||||
:top 32
|
||||
:margin-horizontal 12
|
||||
:color (get-color :messaging-card-title-color)})
|
||||
|
||||
(defn messaging-card-title-props []
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:style (messaging-card-title)})
|
||||
|
||||
(defn messaging-card-subtitle []
|
||||
{:position :absolute
|
||||
:top 54
|
||||
:margin-horizontal 12
|
||||
:color (get-color :messaging-card-subtitle-color)})
|
||||
|
||||
(defn messaging-card-subtitle-props []
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (messaging-card-subtitle)})
|
||||
|
||||
(defn messaging-card-details-container []
|
||||
{:position :absolute
|
||||
:bottom 12
|
||||
:margin-horizontal 12
|
||||
:width 136
|
||||
:height 36})
|
||||
|
||||
(defn messaging-card-last-message-text []
|
||||
{:color (get-color :messaging-card-last-message-text-color)})
|
||||
|
||||
(defn messaging-card-last-message-text-props []
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:number-of-lines 2
|
||||
:ellipsize-mode :tail
|
||||
:style (messaging-card-last-message-text)})
|
||||
|
||||
(defn messaging-card-close-button []
|
||||
{:position :absolute
|
||||
:right 8
|
||||
:top 8
|
||||
:background-color (get-color :messaging-card-close-button-bg-color)
|
||||
:icon-color (get-color :messaging-card-icon-color)})
|
||||
|
||||
(defn messaging-card-close-button-props []
|
||||
{:size 24
|
||||
:type :grey
|
||||
:icon true
|
||||
:on-press #(print "close pressed")
|
||||
:style (messaging-card-close-button)})
|
||||
|
||||
(defn messaging-card-avatar-container []
|
||||
{:width 48
|
||||
:height 48
|
||||
:border-radius 24
|
||||
:position :absolute
|
||||
:left 12
|
||||
:top 16
|
||||
:background-color :pink})
|
|
@ -0,0 +1,32 @@
|
|||
(ns status-im.switcher.constants
|
||||
(:require [status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(def switcher-button-radius 24)
|
||||
|
||||
(def switcher-button-size
|
||||
(* switcher-button-radius 2))
|
||||
|
||||
(def switcher-bottom-positions
|
||||
{:android
|
||||
{:home-stack 17
|
||||
:chat 57}
|
||||
:ios
|
||||
{:home-stack 35
|
||||
:chat 67}})
|
||||
|
||||
(defn switcher-bottom-position [view-id]
|
||||
(get-in
|
||||
switcher-bottom-positions
|
||||
[(keyword platform/os) view-id]))
|
||||
|
||||
(defn switcher-center-position [view-id]
|
||||
(+ (switcher-bottom-position view-id) (/ switcher-button-size 2)))
|
||||
|
||||
;; TODO(parvesh) - use different height for android and ios(Confirm from Design)
|
||||
(defn bottom-tabs-height []
|
||||
(if platform/android? 55 80))
|
||||
|
||||
;; TODO - move to switcher/utils.cljs
|
||||
(defn dimensions []
|
||||
(<sub [:dimensions/window]))
|
|
@ -0,0 +1,97 @@
|
|||
(ns status-im.switcher.styles
|
||||
(:require [quo.theme :as theme]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im.switcher.constants :as constants]
|
||||
[status-im.switcher.animation :as animation]))
|
||||
|
||||
(def themes
|
||||
{:light {:bottom-tabs-bg-color colors/neutral-80
|
||||
:bottom-tabs-on-scroll-bg-color colors/neutral-80-opa-80
|
||||
:bottom-tabs-non-selected-tab colors/neutral-50
|
||||
:bottom-tabs-selected-tab colors/white}
|
||||
:dark {:bottom-tabs-bg-color colors/neutral-80
|
||||
:bottom-tabs-on-scroll-bg-color colors/neutral-80-opa-60
|
||||
:bottom-tabs-non-selected-tab colors/neutral-40
|
||||
:bottom-tabs-selected-tab colors/white}})
|
||||
|
||||
(defn get-color [key]
|
||||
(get-in themes [(theme/get-theme) key]))
|
||||
|
||||
;; Bottom Tabs
|
||||
(defn bottom-tab-icon [tab-state]
|
||||
{:width 20
|
||||
:height 20
|
||||
:color (get-color tab-state)})
|
||||
|
||||
(defn bottom-tabs []
|
||||
{:background-color (get-color :bottom-tabs-bg-color)
|
||||
:flex-direction :row
|
||||
:flex 1
|
||||
:align-items :center
|
||||
:justify-content :space-around
|
||||
:height (constants/bottom-tabs-height)
|
||||
:position :absolute
|
||||
:bottom 0
|
||||
:right 0
|
||||
:left 0
|
||||
:opacity animation/bottom-tabs-opacity
|
||||
:transform [{:translateY animation/bottom-tabs-position}]})
|
||||
|
||||
;; Switcher
|
||||
(defn switcher-button [opacity]
|
||||
{:width constants/switcher-button-size
|
||||
:height constants/switcher-button-size
|
||||
:opacity opacity})
|
||||
|
||||
(defn merge-switcher-button-common-styles [style]
|
||||
(merge
|
||||
{:width constants/switcher-button-size
|
||||
:height constants/switcher-button-size
|
||||
:border-radius constants/switcher-button-radius
|
||||
:position :absolute
|
||||
:bottom 0
|
||||
:z-index 3
|
||||
:align-items :center
|
||||
:align-self :center
|
||||
:justify-content :center}
|
||||
style))
|
||||
|
||||
(defn switcher-button-touchable [view-id]
|
||||
(merge-switcher-button-common-styles
|
||||
{:align-self :center
|
||||
:bottom (constants/switcher-bottom-position view-id)}))
|
||||
|
||||
(defn switcher-close-button-background [opacity]
|
||||
(merge-switcher-button-common-styles
|
||||
{:background-color colors/switcher-background
|
||||
:opacity opacity}))
|
||||
|
||||
(defn switcher-close-button-icon [opacity]
|
||||
(merge-switcher-button-common-styles
|
||||
{:opacity opacity}))
|
||||
|
||||
(defn switcher-screen [view-id radius]
|
||||
(let [bottom (- (constants/switcher-center-position view-id) radius)
|
||||
size (* 2 radius)]
|
||||
(merge-switcher-button-common-styles
|
||||
{:background-color colors/switcher-background-opa-80
|
||||
:bottom bottom
|
||||
:border-radius 1000
|
||||
:width size
|
||||
:overflow :hidden
|
||||
:height size})))
|
||||
|
||||
(defn switcher-screen-container [view-id radius]
|
||||
(let [radius radius
|
||||
bottom (- radius (constants/switcher-center-position view-id))
|
||||
{:keys [width height]} (constants/dimensions)]
|
||||
{:position :absolute
|
||||
:align-self :center
|
||||
:bottom bottom
|
||||
:width width
|
||||
:height (- height 25)
|
||||
:align-items :center}))
|
||||
|
||||
(defn switcher-switch-screen []
|
||||
{:margin-top 40
|
||||
:align-items :center})
|
|
@ -0,0 +1,44 @@
|
|||
(ns status-im.switcher.switcher
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.switcher.styles :as styles]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.switcher.animation :as animation]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.switcher.switcher-container :as switcher-container]))
|
||||
|
||||
(defn toggle-switcher-screen [switcher-opened? view-id anim-values]
|
||||
(swap! switcher-opened? not)
|
||||
(animation/animate @switcher-opened? view-id anim-values))
|
||||
|
||||
(defn switcher-button [switcher-opened? view-id anim-values]
|
||||
[rn/touchable-opacity {:active-opacity 1
|
||||
:on-press #(toggle-switcher-screen switcher-opened? view-id anim-values)
|
||||
:style (styles/switcher-button-touchable view-id)}
|
||||
[rn/animated-view {:style (styles/switcher-close-button-background
|
||||
(:switcher-close-button-background-opacity anim-values))}]
|
||||
[rn/animated-view {:style (styles/switcher-close-button-icon
|
||||
(:switcher-close-button-icon-opacity anim-values))}
|
||||
[icons/icon :main-icons/close {:color :white}]]
|
||||
[rn/animated-image-view {:source (resources/get-image :status-logo)
|
||||
:style (styles/switcher-button
|
||||
(:switcher-button-opacity anim-values))}]])
|
||||
|
||||
(defn switcher-screen [switcher-opened? view-id anim-values]
|
||||
[rn/view {:style (styles/switcher-screen
|
||||
view-id @(:switcher-screen-radius anim-values))
|
||||
:pointer-events (if switcher-opened? :auto :none)}
|
||||
[switcher-container/container
|
||||
view-id @(:switcher-screen-radius anim-values)
|
||||
#(toggle-switcher-screen switcher-opened? view-id anim-values)]])
|
||||
|
||||
(defn switcher [view-id]
|
||||
(let [switcher-opened? (reagent/atom false)
|
||||
anim-values {:switcher-button-opacity (anim/create-value 1)
|
||||
:switcher-close-button-icon-opacity (anim/create-value 0)
|
||||
:switcher-close-button-background-opacity (anim/create-value 0)
|
||||
:switcher-screen-radius (reagent/atom 1)}]
|
||||
[:<>
|
||||
[switcher-screen switcher-opened? view-id anim-values]
|
||||
[switcher-button switcher-opened? view-id anim-values]]))
|
|
@ -0,0 +1,34 @@
|
|||
(ns status-im.switcher.switcher-container
|
||||
(:require [quo.react-native :as rn]
|
||||
status-im.switcher.cards.messaging-card
|
||||
[status-im.switcher.styles :as styles]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.switcher.cards.messaging-card :as messaging-card]))
|
||||
|
||||
;; TODO - use something like this to avoid multiple renders etc.
|
||||
;; (defn switch-screen [toggle-switcher-screen]
|
||||
;; (let [cards (<sub [:navigation2/switcher-cards])
|
||||
;; new-cards (reduce (fn [acc card]
|
||||
;; (conj acc (assoc card :toggle-switcher-screen toggle-switcher-screen)))
|
||||
;; () cards)]
|
||||
;; (fn []
|
||||
;; [rn/view {:style (styles/switcher-switch-screen)}
|
||||
;; [rn/flat-list {:width 352
|
||||
;; :data new-cards
|
||||
;; :render-fn messaging-card/card
|
||||
;; :num-columns 2
|
||||
;; :key-fn str}]])))
|
||||
|
||||
(defn switch-screen [toggle-switcher-screen]
|
||||
(let [cards (<sub [:navigation2/switcher-cards toggle-switcher-screen])]
|
||||
[rn/view {:style (styles/switcher-switch-screen)}
|
||||
[rn/flat-list {:width 352
|
||||
:data cards
|
||||
:render-fn messaging-card/card
|
||||
:num-columns 2
|
||||
:key-fn str}]]))
|
||||
|
||||
(defn container [view-id switcher-screen-radius toggle-switcher-screen]
|
||||
[rn/view {:style (styles/switcher-screen-container
|
||||
view-id switcher-screen-radius)}
|
||||
[switch-screen toggle-switcher-screen]])
|
|
@ -0,0 +1,6 @@
|
|||
(ns status-im.switcher.utils
|
||||
(:require [re-frame.core :as re-frame]))
|
||||
|
||||
(def switcher-container-view-id (atom nil))
|
||||
|
||||
(re-frame/reg-fx :switcher-container-view-id #(reset! switcher-container-view-id %))
|
|
@ -123,6 +123,7 @@
|
|||
:accessibility-label :appearance-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :quo2-preview])}])
|
||||
;; :on-press #(re-frame/dispatch [:init-root-nav2 :home-stack])}])
|
||||
[quo/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title (i18n/label :t/appearance)
|
||||
|
|
|
@ -121,7 +121,9 @@
|
|||
[status-im.ui.screens.wallet.recipient.views :as recipient]
|
||||
[status-im.ui.screens.wallet.send.views :as wallet.send]
|
||||
[quo2.screens.main :as quo2.preview]
|
||||
[status-im.utils.config :as config]))
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.navigation2.screens :as navigation2.screens]))
|
||||
;[status-im.navigation2.stack-with-switcher :as stack-with-switcher]))
|
||||
;[quo2.foundations.colors :as quo2.colors]))
|
||||
|
||||
(def components
|
||||
|
@ -229,6 +231,7 @@
|
|||
:rightButtons (right-button-options :chat :more)}}
|
||||
:right-handler chat/topbar-button
|
||||
:component chat/chat}
|
||||
;; :component #(stack-with-switcher/overlap-stack chat/chat :chat)}
|
||||
|
||||
;Pinned messages
|
||||
{:name :chat-pinned-messages
|
||||
|
@ -914,5 +917,7 @@
|
|||
quo.preview/main-screens)
|
||||
(when config/quo-preview-enabled?
|
||||
quo2.preview/screens)
|
||||
(when config/quo-preview-enabled?
|
||||
navigation2.screens/screens)
|
||||
(when config/quo-preview-enabled?
|
||||
quo2.preview/main-screens)))
|
||||
|
|
Loading…
Reference in New Issue