Two pane ui on large screens

Signed-off-by: Volodymyr Kozieiev <vkjr.sp@gmail.com>
This commit is contained in:
Volodymyr Kozieiev 2019-07-05 12:05:36 +03:00
parent de0d98da20
commit ea8bf402d7
No known key found for this signature in database
GPG Key ID: 1F706640AAF07516
26 changed files with 232 additions and 119 deletions

View File

@ -45,6 +45,7 @@
"text-encoding" "text-encoding"
"js-sha3" "js-sha3"
"react-navigation" "react-navigation"
"react-native-navigation-twopane"
"hi-base32" "hi-base32"
"react-native-mail" "react-native-mail"
"react-native-shake"] "react-native-shake"]
@ -87,6 +88,7 @@
"js-sha3" "js-sha3"
"web3-utils" "web3-utils"
"react-navigation" "react-navigation"
"react-native-navigation-twopane"
"hi-base32"] "hi-base32"]
;; Resoures ;; Resoures

View File

@ -91,6 +91,7 @@
"react-native-tcp": "3.3.0", "react-native-tcp": "3.3.0",
"react-native-udp": "2.2.1", "react-native-udp": "2.2.1",
"react-native-webview-bridge": "git+https://github.com/status-im/react-native-webview-bridge.git#0.33.16-status-rn049-desktop", "react-native-webview-bridge": "git+https://github.com/status-im/react-native-webview-bridge.git#0.33.16-status-rn049-desktop",
"react-native-navigation-twopane": "git+https://github.com/status-im/react-native-navigation-twopane.git#v0.0.2-status",
"react-navigation": "^2.12.1", "react-navigation": "^2.12.1",
"realm": "git+https://github.com/status-im/realm-js.git#v2.20.1", "realm": "git+https://github.com/status-im/realm-js.git#v2.20.1",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#v2.0.2-status", "rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#v2.0.2-status",

View File

@ -7146,6 +7146,10 @@ react-native-invertible-scroll-view@1.1.0:
version "3.0.2" version "3.0.2"
resolved "git+https://github.com/status-im/react-native-languages.git#60338ff3040b8af68d33233aebeb36db4d31aed0" resolved "git+https://github.com/status-im/react-native-languages.git#60338ff3040b8af68d33233aebeb36db4d31aed0"
"react-native-navigation-twopane@git+https://github.com/status-im/react-native-navigation-twopane.git#v0.0.2-status":
version "0.0.2"
resolved "git+https://github.com/status-im/react-native-navigation-twopane.git#04ed5fddfb46a6a3ee30776987acb4d3b11c27d4"
react-native-os@1.1.0: react-native-os@1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.1.0.tgz#bfbe1c44d8a5b14a6f3a3a405d8ada6f547a516e" resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.1.0.tgz#bfbe1c44d8a5b14a6f3a3a405d8ada6f547a516e"

View File

@ -66,6 +66,7 @@
"react-native-udp": "git+https://github.com/status-im/react-native-udp.git#v2.3.1-1-status", "react-native-udp": "git+https://github.com/status-im/react-native-udp.git#v2.3.1-1-status",
"react-native-webview": "^5.2.1", "react-native-webview": "^5.2.1",
"react-native-webview-bridge": "git+https://github.com/status-im/react-native-webview-bridge.git#fix/classnames-colision", "react-native-webview-bridge": "git+https://github.com/status-im/react-native-webview-bridge.git#fix/classnames-colision",
"react-native-navigation-twopane": "git+https://github.com/status-im/react-native-navigation-twopane.git#v0.0.2-status",
"react-navigation": "^3.11.0", "react-navigation": "^3.11.0",
"realm": "2.28.1", "realm": "2.28.1",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#v2.0.2-status", "rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#v2.0.2-status",

View File

@ -5619,6 +5619,10 @@ react-native-languages@^3.0.2:
version "3.0.7" version "3.0.7"
resolved "git+https://github.com/status-im/react-native-mail.git#5dd2d4e92fa696a9dd0efebdc530df22772326fe" resolved "git+https://github.com/status-im/react-native-mail.git#5dd2d4e92fa696a9dd0efebdc530df22772326fe"
"react-native-navigation-twopane@git+https://github.com/status-im/react-native-navigation-twopane.git#v0.0.2-status":
version "0.0.2"
resolved "git+https://github.com/status-im/react-native-navigation-twopane.git#04ed5fddfb46a6a3ee30776987acb4d3b11c27d4"
"react-native-os@git+https://github.com/status-im/react-native-os.git#v1.1.0-1-status": "react-native-os@git+https://github.com/status-im/react-native-os.git#v1.1.0-1-status":
version "1.1.0" version "1.1.0"
resolved "git+https://github.com/status-im/react-native-os.git#1a6d0835f919cb075793ad7c602f2724eee4702d" resolved "git+https://github.com/status-im/react-native-os.git#1a6d0835f919cb075793ad7c602f2724eee4702d"

View File

@ -36,5 +36,6 @@
(def snoopy-buffer (fn [] #js {})) (def snoopy-buffer (fn [] #js {}))
(def background-timer (fn [] #js {:setTimeout (fn [cb ms] (js/setTimeout cb ms))})) (def background-timer (fn [] #js {:setTimeout (fn [cb ms] (js/setTimeout cb ms))}))
(def react-navigation (js/require "react-navigation")) (def react-navigation (js/require "react-navigation"))
(def react-native-navigation-twopane (js/require "react-native-navigation-twopane"))
(def react-native-shake (fn [] #js {})) (def react-native-shake (fn [] #js {}))
(def react-native-mail (fn [] #js {:mail (fn [])})) (def react-native-mail (fn [] #js {:mail (fn [])}))

View File

@ -34,6 +34,7 @@
(def background-timer-class (js-require/js-require "react-native-background-timer")) (def background-timer-class (js-require/js-require "react-native-background-timer"))
(defn background-timer [] (.-default (background-timer-class))) (defn background-timer [] (.-default (background-timer-class)))
(def react-navigation (js/require "react-navigation")) (def react-navigation (js/require "react-navigation"))
(def react-native-navigation-twopane (js/require "react-native-navigation-twopane"))
(def react-native-shake (js-require/js-require "react-native-shake")) (def react-native-shake (js-require/js-require "react-native-shake"))
(def react-native-screens (js-require/js-require "react-native-screens")) (def react-native-screens (js-require/js-require "react-native-screens"))
(def mail-class (js-require/js-require "react-native-mail")) (def mail-class (js-require/js-require "react-native-mail"))

View File

@ -24,6 +24,8 @@
(def default-number-of-messages 20) (def default-number-of-messages 20)
(def blocks-per-hour 120) (def blocks-per-hour 120)
(def one-earth-day 86400) (def one-earth-day 86400)
(def two-pane-min-width 640)
(def left-pane-min-width 320)
(def mailserver-password "status-offline-inbox") (def mailserver-password "status-offline-inbox")

View File

@ -804,6 +804,18 @@
current-param-position current-param-position
value)))) value))))
(defn- mark-messages-seen
[{:keys [db] :as cofx}]
(let [{:keys [current-chat-id]} db]
(chat/mark-messages-seen cofx current-chat-id)))
(handlers/register-handler-fx
:chat.ui/mark-messages-seen
(fn [{:keys [db] :as cofx} [_ view-id]]
(fx/merge cofx
{:db (assoc db :view-id view-id)}
#(mark-messages-seen %))))
(handlers/register-handler-fx (handlers/register-handler-fx
:chat/send-plain-text-message :chat/send-plain-text-message
(fn [{{:keys [current-chat-id]} :db :as cofx} [_ message-text]] (fn [{{:keys [current-chat-id]} :db :as cofx} [_ message-text]]

View File

@ -59,6 +59,7 @@
(reg-root-key-sub :view-id :view-id) (reg-root-key-sub :view-id :view-id)
(reg-root-key-sub :navigation-stack :navigation-stack) (reg-root-key-sub :navigation-stack :navigation-stack)
(reg-root-key-sub :screen-params :navigation/screen-params) (reg-root-key-sub :screen-params :navigation/screen-params)
(reg-root-key-sub :two-pane-ui-enabled? :two-pane-ui-enabled?)
;;bottom sheet ;;bottom sheet
(reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?) (reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?)

View File

@ -150,13 +150,14 @@
(defview connectivity-view [anim-translate-y] (defview connectivity-view [anim-translate-y]
(letsubs [status-properties [:connectivity/status-properties] (letsubs [status-properties [:connectivity/status-properties]
view-id [:view-id] view-id [:view-id]
window-width [:dimensions/window-width]] window-width (reagent/atom 0)]
(let [{:keys [loading-indicator?]} status-properties] (let [{:keys [loading-indicator?]} status-properties]
[react/view {:style {:align-self :flex-start}} [react/view {:style {:align-items :stretch}
:on-layout #(reset! window-width (-> % .-nativeEvent .-layout .-width))}
(when loading-indicator? (when loading-indicator?
[loading-indicator window-width]) [loading-indicator @window-width])
[connectivity-status [connectivity-status
(merge status-properties (merge status-properties
{:view-id view-id {:view-id view-id
:window-width window-width}) :window-width @window-width})
anim-translate-y]]))) anim-translate-y]])))

View File

@ -18,6 +18,10 @@
[status-im.utils.slurp :refer [slurp]] [status-im.utils.slurp :refer [slurp]]
[status-im.utils.views :as views])) [status-im.utils.views :as views]))
(defn- start-chat [topic]
(re-frame/dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}])
(re-frame/dispatch [:set :public-group-topic nil]))
(defn- chat-name-input [topic error] (defn- chat-name-input [topic error]
[react/view [react/view
[react/view (merge add-new.styles/input-container {:margin-top 8}) [react/view (merge add-new.styles/input-container {:margin-top 8})
@ -26,8 +30,7 @@
[text-input.view/text-input-with-label [text-input.view/text-input-with-label
{:container styles/input-container {:container styles/input-container
:on-change-text #(re-frame/dispatch [:set :public-group-topic %]) :on-change-text #(re-frame/dispatch [:set :public-group-topic %])
:on-submit-editing #(when (db/valid-topic? topic) :on-submit-editing #(when (db/valid-topic? topic) (start-chat topic))
(re-frame/dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}]))
:auto-capitalize :none :auto-capitalize :none
:auto-focus false :auto-focus false
:accessibility-label :chat-name-input :accessibility-label :chat-name-input
@ -43,9 +46,7 @@
(first topic)]]) (first topic)]])
(defn- render-topic [topic] (defn- render-topic [topic]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/start-public-chat [react/touchable-highlight {:on-press #(start-chat topic)
topic
{:navigation-reset? true}])
:accessibility-label :chat-item} :accessibility-label :chat-item}
[react/view [react/view
[list/item [list/item

View File

@ -78,7 +78,8 @@
(defview stickers-paging-panel [installed-packs selected-pack] (defview stickers-paging-panel [installed-packs selected-pack]
(letsubs [ref (atom nil) (letsubs [ref (atom nil)
window-width [:dimensions/window-width]] window-width [:dimensions/window-width]
content-width (reagent/atom 0)]
{:component-will-update (fn [_ [_ installed-packs selected-pack]] {:component-will-update (fn [_ [_ installed-packs selected-pack]]
(update-scroll-position @ref installed-packs selected-pack window-width)) (update-scroll-position @ref installed-packs selected-pack window-width))
:component-did-mount #(update-scroll-position @ref installed-packs selected-pack window-width)} :component-did-mount #(update-scroll-position @ref installed-packs selected-pack window-width)}
@ -87,12 +88,13 @@
:shows-horizontal-scroll-indicator false :shows-horizontal-scroll-indicator false
:on-momentum-scroll-end #(on-scroll % installed-packs window-width) :on-momentum-scroll-end #(on-scroll % installed-packs window-width)
:scrollEventThrottle 8 :scrollEventThrottle 8
:on-scroll #(reset! scroll-x (.-nativeEvent.contentOffset.x %))} :on-scroll #(reset! scroll-x (.-nativeEvent.contentOffset.x %))
:on-layout #(reset! content-width (-> % .-nativeEvent .-layout .-width))}
^{:key "recent"} ^{:key "recent"}
[recent-stickers-panel window-width] [recent-stickers-panel @content-width]
(for [{:keys [stickers id]} installed-packs] (for [{:keys [stickers id]} installed-packs]
^{:key (str "sticker" id)} ^{:key (str "sticker" id)}
[stickers-panel (map #(assoc % :pack id) stickers) window-width])])) [stickers-panel (map #(assoc % :pack id) stickers) @content-width])]))
(defn pack-icon [{:keys [id on-press background-color] (defn pack-icon [{:keys [id on-press background-color]
:or {on-press #(re-frame/dispatch [:stickers/select-pack id])}} :or {on-press #(re-frame/dispatch [:stickers/select-pack id])}}

View File

@ -432,7 +432,8 @@
current-chat-id [:chats/current-chat-id] current-chat-id [:chats/current-chat-id]
show-message-options? [:chats/current-chat-ui-prop :show-message-options?] show-message-options? [:chats/current-chat-ui-prop :show-message-options?]
show-stickers? [:chats/current-chat-ui-prop :show-stickers?] show-stickers? [:chats/current-chat-ui-prop :show-stickers?]
anim-translate-y (animation/create-value -35)] two-pane-ui-enabled? [:two-pane-ui-enabled?]
anim-translate-y (animation/create-value (if two-pane-ui-enabled? 0 -35))]
;; this check of current-chat-id is necessary only because in a fresh public chat creation sometimes ;; this check of current-chat-id is necessary only because in a fresh public chat creation sometimes
;; this component renders before current-chat-id is set to current chat-id. Hence further down in sub ;; this component renders before current-chat-id is set to current chat-id. Hence further down in sub
;; components (e.g. chat-toolbar) there can be a brief visual inconsistancy like showing 'add contact' ;; components (e.g. chat-toolbar) there can be a brief visual inconsistancy like showing 'add contact'
@ -443,7 +444,8 @@
(re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))} (re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))}
^{:key current-chat-id} ^{:key current-chat-id}
[chat-toolbar current-chat public? modal?] [chat-toolbar current-chat public? modal?]
[connectivity/connectivity-view anim-translate-y] (when-not two-pane-ui-enabled?
[connectivity/connectivity-view anim-translate-y])
[connectivity/connectivity-animation-wrapper [connectivity/connectivity-animation-wrapper
{} {}
anim-translate-y anim-translate-y
@ -464,3 +466,8 @@
(defview chat-modal [] (defview chat-modal []
[chat-root true]) [chat-root true])
(defview select-chat []
[react/view {:style {:align-items :center :justify-content :center :flex 1}}
[react/text {:style style/decline-chat}
(i18n/label :t/select-chat)]])

View File

@ -68,7 +68,8 @@
:current [] :current []
:puk [] :puk []
:enter-step :original}} :enter-step :original}}
:chats/loading? true}) :chats/loading? true
:two-pane-ui-enabled? (dimensions/fit-two-pane?)})
;;;;GLOBAL ;;;;GLOBAL
@ -151,6 +152,7 @@
(spec/def :desktop/desktop (spec/nilable any?)) (spec/def :desktop/desktop (spec/nilable any?))
(spec/def ::tooltips (spec/nilable any?)) (spec/def ::tooltips (spec/nilable any?))
(spec/def ::initial-props (spec/nilable any?)) (spec/def ::initial-props (spec/nilable any?))
(spec/def ::two-pane-ui-enabled? (spec/nilable boolean?))
;;;;NETWORK ;;;;NETWORK
@ -352,4 +354,5 @@
::collectible ::collectible
::collectibles ::collectibles
::extensions-store ::extensions-store
:registry/registry])) :registry/registry
::two-pane-ui-enabled?]))

View File

@ -65,11 +65,6 @@
:http-post :http-post
http-post) http-post)
(defn- mark-messages-seen
[{:keys [db] :as cofx}]
(let [{:keys [current-chat-id]} db]
(chat/mark-messages-seen cofx current-chat-id)))
(defn- http-raw-post [{:keys [url body response-validator success-event-creator failure-event-creator timeout-ms opts]}] (defn- http-raw-post [{:keys [url body response-validator success-event-creator failure-event-creator timeout-ms opts]}]
(let [on-success #(re-frame/dispatch (success-event-creator %)) (let [on-success #(re-frame/dispatch (success-event-creator %))
on-error (when failure-event-creator #(re-frame/dispatch (failure-event-creator %))) on-error (when failure-event-creator #(re-frame/dispatch (failure-event-creator %)))
@ -204,6 +199,11 @@
(fn [{:keys [db]} [_ dimensions]] (fn [{:keys [db]} [_ dimensions]]
{:db (assoc db :dimensions/window (dimensions/window dimensions))})) {:db (assoc db :dimensions/window (dimensions/window dimensions))}))
(handlers/register-handler-fx
:set-two-pane-ui-enabled
(fn [{:keys [db]} [_ enabled?]]
{:db (assoc db :two-pane-ui-enabled? enabled?)}))
(handlers/register-handler-fx (handlers/register-handler-fx
:screens/on-will-focus :screens/on-will-focus
(fn [{:keys [db] :as cofx} [_ view-id]] (fn [{:keys [db] :as cofx} [_ view-id]]
@ -222,5 +222,4 @@
:hardwallet-connect-modal (hardwallet/hardwallet-connect-screen-did-load %) :hardwallet-connect-modal (hardwallet/hardwallet-connect-screen-did-load %)
:hardwallet-authentication-method (hardwallet/authentication-method-screen-did-load %) :hardwallet-authentication-method (hardwallet/authentication-method-screen-did-load %)
:accounts (hardwallet/accounts-screen-did-load %) :accounts (hardwallet/accounts-screen-did-load %)
:chat (mark-messages-seen %)
nil)))) nil))))

View File

@ -16,7 +16,9 @@
[status-im.ui.screens.home.views.inner-item :as inner-item] [status-im.ui.screens.home.views.inner-item :as inner-item]
[status-im.ui.components.common.common :as components.common] [status-im.ui.components.common.common :as components.common]
[status-im.ui.components.list-selection :as list-selection] [status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.animation :as animation]) [status-im.ui.components.animation :as animation]
[status-im.constants :as constants]
[status-im.ui.components.colors :as colors])
(:require-macros [status-im.utils.views :as views])) (:require-macros [status-im.utils.views :as views]))
(views/defview les-debug-info [] (views/defview les-debug-info []
@ -121,49 +123,54 @@
(views/defview home [loading?] (views/defview home [loading?]
(views/letsubs (views/letsubs
[anim-translate-y (animation/create-value -35) [anim-translate-y (animation/create-value -35)
{:keys [search-filter chats all-home-items]} [:home-items]] {:keys [search-filter chats all-home-items]} [:home-items]
window-width [:dimensions/window-width]
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
{:component-did-mount (fn [this] {:component-did-mount (fn [this]
(let [[_ loading?] (.. this -props -argv)] (let [[_ loading?] (.. this -props -argv)]
(when loading? (utils/set-timeout #(re-frame/dispatch [:init-rest-of-chats]) 100))))} (when loading? (utils/set-timeout #(re-frame/dispatch [:init-rest-of-chats]) 100))))}
[react/view {:flex 1} (let [home-width (if (> window-width constants/two-pane-min-width)
[status-bar/status-bar {:type :main}] (max constants/left-pane-min-width (/ window-width 3))
[react/keyboard-avoiding-view {:style {:flex 1 window-width)]
:align-items :center} [react/view (merge {:flex 1 :width home-width}
:on-layout (fn [e] (when two-pane-ui-enabled?
(re-frame/dispatch {:border-right-width 1 :border-right-color colors/gray-light}))
[:set-once :content-layout-height [status-bar/status-bar {:type :main}]
(-> e .-nativeEvent .-layout .-height)]))} [react/keyboard-avoiding-view {:style {:flex 1
[react/view {:style {:flex 1 :align-items :center}
:align-self :stretch}} :on-layout (fn [e]
[toolbar/toolbar nil nil [toolbar/content-title (i18n/label :t/chat)]] (re-frame/dispatch
[les-debug-info] [:set-once :content-layout-height
(cond loading? (-> e .-nativeEvent .-layout .-height)]))}
[react/view {:style {:flex 1 [react/view {:style {:flex 1
:justify-content :center :align-self :stretch}}
:align-items :center}} [toolbar/toolbar nil nil [toolbar/content-title (i18n/label :t/chat)]]
[connectivity/connectivity-view anim-translate-y] [les-debug-info]
[connectivity/connectivity-animation-wrapper (cond loading?
{} [react/view {:style {:flex 1
anim-translate-y :justify-content :center
[react/activity-indicator {:flex 1 :align-items :center}}
:animating true}]]] [connectivity/connectivity-view anim-translate-y]
[connectivity/connectivity-animation-wrapper
:else {}
[react/view {:style {:flex 1}} anim-translate-y
[connectivity/connectivity-view anim-translate-y] [react/activity-indicator {:flex 1
[connectivity/connectivity-animation-wrapper :animating true}]]] :else
{} [react/view {:style {:flex 1}}
anim-translate-y [connectivity/connectivity-view anim-translate-y]
[filter.views/search-input-wrapper search-filter] [connectivity/connectivity-animation-wrapper
(if (and (not search-filter) {}
(empty? all-home-items)) anim-translate-y
[home-empty-view] [filter.views/search-input-wrapper search-filter]
[home-items-view (if (and (not search-filter)
search-filter (empty? all-home-items))
chats [home-empty-view]
all-home-items [home-items-view
filter.views/search-input-state])]])] search-filter
[home-action-button]]])) chats
all-home-items
filter.views/search-input-state])]])]
[home-action-button]]])))
(views/defview home-wrapper [] (views/defview home-wrapper []
(views/letsubs [loading? [:chats/loading?]] (views/letsubs [loading? [:chats/loading?]]

View File

@ -98,7 +98,9 @@
(and group-chat public?) :public-chat-actions (and group-chat public?) :public-chat-actions
(and group-chat (not public?)) :group-chat-actions (and group-chat (not public?)) :group-chat-actions
:else :private-chat-actions)] :else :private-chat-actions)]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id]) [react/touchable-highlight {:on-press #(do
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
(re-frame/dispatch [:chat.ui/mark-messages-seen :chat]))
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])} :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])}
[react/view styles/chat-container [react/view styles/chat-container
[react/view styles/chat-icon-container [react/view styles/chat-icon-container

View File

@ -4,6 +4,7 @@
{:name :chat-stack {:name :chat-stack
:screens [:home :screens [:home
:chat :chat
:select-chat
:profile :profile
:new :new
:new-chat :new-chat
@ -17,4 +18,5 @@
:new-public-chat :new-public-chat
:stickers :stickers
:stickers-pack] :stickers-pack]
:config {:initialRouteName :home}}) :config {:initialRouteName :home
:emptyRightPaneName :select-chat}})

View File

@ -114,26 +114,45 @@
(defn stack-navigator [routes config] (defn stack-navigator [routes config]
(nav-reagent/stack-navigator (nav-reagent/stack-navigator
routes routes
(cond-> (merge {:headerMode "none"
(merge {:headerMode "none" :cardStyle {:backgroundColor :white}
:cardStyle {:backgroundColor :white} #_:transitionConfig
#_:transitionConfig #_(fn []
#_(fn [] #js {:transitionSpec #js{:duration 10}})
#js {:transitionSpec #js{:duration 10}}) :onTransitionStart (fn [n]
:onTransitionStart (fn [n] (let [idx (.. n
(let [idx (.. n -navigation
-navigation -state
-state -index)
-index) routes (.. n
routes (.. n -navigation
-navigation -state
-state -routes)]
-routes)] (when (and (array? routes) (int? idx))
(when (and (array? routes) (int? idx)) (let [route (aget routes idx)
(let [route (aget routes idx) route-name (keyword (.-routeName route))]
route-name (keyword (.-routeName route))] (bottom-bar/minimize-bar route-name)))))}
(bottom-bar/minimize-bar route-name)))))} (prepare-config config))))
(prepare-config config)))))
(defn twopane-navigator [routes config]
(navigation/twopane-navigator
routes
(merge {:headerMode "none"
:cardStyle {:backgroundColor :white}
:onTransitionStart (fn [n]
(let [idx (.. n
-navigation
-state
-index)
routes (.. n
-navigation
-state
-routes)]
(when (and (array? routes) (int? idx))
(let [route (aget routes idx)
route-name (keyword (.-routeName route))]
(bottom-bar/minimize-bar route-name)))))}
(prepare-config config))))
(defn switch-navigator [routes config] (defn switch-navigator [routes config]
(nav-reagent/switch-navigator (nav-reagent/switch-navigator
@ -147,7 +166,7 @@
(declare stack-screens) (declare stack-screens)
(defn build-screen [screen] (defn build-screen [navigator screen]
"Builds screen from specified configuration. Currently screen can be "Builds screen from specified configuration. Currently screen can be
- keyword, which points to some specific route - keyword, which points to some specific route
- vector of [:modal :screen-key] type when screen should be wrapped as modal - vector of [:modal :screen-key] type when screen should be wrapped as modal
@ -162,8 +181,8 @@
(let [res (cond (let [res (cond
(map? screen-config) (map? screen-config)
(let [{:keys [screens config]} screen-config] (let [{:keys [screens config]} screen-config]
(stack-navigator (navigator
(stack-screens screens) (stack-screens navigator screens)
config)) config))
(vector? screen-config) (vector? screen-config)
@ -178,9 +197,9 @@
(assoc :navigationOptions (assoc :navigationOptions
(:navigation screen-config)))]))) (:navigation screen-config)))])))
(defn stack-screens [screens-map] (defn stack-screens [navigator screens-map]
(->> screens-map (->> screens-map
(map build-screen) (map (partial build-screen navigator))
(into {}))) (into {})))
(defn wrap-bottom-bar (defn wrap-bottom-bar
@ -190,28 +209,28 @@
(defn app-container [navigator] (defn app-container [navigator]
(.createAppContainer js-dependencies/react-navigation navigator)) (.createAppContainer js-dependencies/react-navigation navigator))
(defn get-main-component [view-id] (defn get-main-component [view-id two-pane?]
(log/debug :component view-id) (log/debug :component view-id)
(app-container (app-container
(switch-navigator (switch-navigator
(into {} (into {}
[(build-screen (intro-login-stack/login-stack view-id)) [(build-screen stack-navigator (intro-login-stack/login-stack view-id))
(build-screen (intro-login-stack/intro-stack)) (build-screen stack-navigator (intro-login-stack/intro-stack))
[:tabs-and-modals [:tabs-and-modals
{:screen {:screen
(stack-navigator (stack-navigator
(merge (merge
{:tabs {:tabs
{:screen (tab-navigator {:screen (tab-navigator
(->> [(build-screen chat-stack/chat-stack) (->> [(build-screen (if two-pane? twopane-navigator stack-navigator) chat-stack/chat-stack)
(build-screen browser-stack/browser-stack) (build-screen stack-navigator browser-stack/browser-stack)
(build-screen wallet-stack/wallet-stack) (build-screen stack-navigator wallet-stack/wallet-stack)
(build-screen profile-stack/profile-stack)] (build-screen stack-navigator profile-stack/profile-stack)]
(into {})) (into {}))
{:initialRouteName :chat-stack {:initialRouteName :chat-stack
:tabBarComponent (reagent.core/reactify-component :tabBarComponent (reagent.core/reactify-component
wrap-bottom-bar)})}} wrap-bottom-bar)})}}
(stack-screens modals/modal-screens)) (stack-screens stack-navigator modals/modal-screens))
{:mode :modal {:mode :modal
:initialRouteName :tabs :initialRouteName :tabs
:onTransitionStart (fn [])})}]]) :onTransitionStart (fn [])})}]])

View File

@ -97,6 +97,7 @@
:keycard-onboarding-recovery-phrase-confirm-word2 keycard.onboarding/recovery-phrase-confirm-word :keycard-onboarding-recovery-phrase-confirm-word2 keycard.onboarding/recovery-phrase-confirm-word
:home home/home-wrapper :home home/home-wrapper
:chat chat/chat :chat chat/chat
:select-chat chat/select-chat
:profile profile.contact/profile :profile profile.contact/profile
:new add-new/add-new :new add-new/add-new
:new-chat new-chat/new-chat :new-chat new-chat/new-chat

View File

@ -15,6 +15,7 @@
[status-im.ui.screens.home.sheet.views :as home.sheet] [status-im.ui.screens.home.sheet.views :as home.sheet]
[status-im.ui.screens.routing.core :as routing] [status-im.ui.screens.routing.core :as routing]
[status-im.ui.screens.signing.views :as signing] [status-im.ui.screens.signing.views :as signing]
[status-im.utils.dimensions :as dimensions]
status-im.ui.screens.wallet.collectibles.etheremon.views status-im.ui.screens.wallet.collectibles.etheremon.views
status-im.ui.screens.wallet.collectibles.cryptostrikers.views status-im.ui.screens.wallet.collectibles.cryptostrikers.views
status-im.ui.screens.wallet.collectibles.cryptokitties.views status-im.ui.screens.wallet.collectibles.cryptokitties.views
@ -53,6 +54,25 @@
[bottom-sheet/bottom-sheet opts]))) [bottom-sheet/bottom-sheet opts])))
(defn reset-component-on-mount [view-id component two-pane?]
(when (and @initial-view-id
(or
js/goog.DEBUG
(not @component)))
(reset! component (routing/get-main-component
(if js/goog.DEBUG
@initial-view-id
@view-id)
two-pane?))))
(defn reset-component-on-update [view-id component two-pane?]
(when (and @initial-view-id (not @component))
(reset! component (routing/get-main-component
(if js/goog.DEBUG
@initial-view-id
@view-id)
two-pane?))))
(defonce state (atom nil)) (defonce state (atom nil))
(defn persist-state [state-obj] (defn persist-state [state-obj]
@ -67,36 +87,40 @@
(resolve @state)))) (resolve @state))))
(defn main [] (defn main []
(let [view-id (re-frame/subscribe [:view-id]) (let [view-id (re-frame/subscribe [:view-id])
main-component (atom nil)] main-component (atom nil)
main-component-two-pane (atom nil)
two-pane? (reagent/atom (dimensions/fit-two-pane?))]
(reagent/create-class (reagent/create-class
{:component-did-mount {:component-did-mount
(fn [] (fn []
(re-frame/dispatch [:set-two-pane-ui-enabled @two-pane?])
(log/debug :main-component-did-mount @view-id) (log/debug :main-component-did-mount @view-id)
(utils.universal-links/initialize)) (utils.universal-links/initialize))
:component-will-mount :component-will-mount
(fn [] (fn []
(.addEventListener (react/dimensions)
"change"
(fn [dimensions]
(let [two-pane-enabled? (dimensions/fit-two-pane?)]
(do
(re-frame/dispatch [:set-two-pane-ui-enabled two-pane-enabled?])
(log/debug ":set-two-pane " two-pane-enabled?)
(reset! two-pane? two-pane-enabled?)))))
(when-not @initial-view-id (when-not @initial-view-id
(reset! initial-view-id @view-id)) (reset! initial-view-id @view-id))
(when (and @initial-view-id (reset-component-on-mount view-id main-component false)
(or (reset-component-on-mount view-id main-component-two-pane true))
js/goog.DEBUG
(not @main-component)))
(reset! main-component (routing/get-main-component
(if js/goog.DEBUG
@initial-view-id
@view-id)))))
:component-will-unmount :component-will-unmount
utils.universal-links/finalize utils.universal-links/finalize
:component-will-update :component-will-update
(fn [] (fn []
(when-not @initial-view-id (when-not @initial-view-id
(reset! initial-view-id @view-id)) (reset! initial-view-id @view-id))
(when (and @initial-view-id (not @main-component))
(reset! main-component (routing/get-main-component (reset-component-on-update view-id main-component false)
(if js/goog.DEBUG (reset-component-on-update view-id main-component-two-pane true)
@initial-view-id
@view-id))))
(when-not platform/desktop? (when-not platform/desktop?
(react/dismiss-keyboard!))) (react/dismiss-keyboard!)))
:component-did-update :component-did-update
@ -106,7 +130,7 @@
(fn [] (fn []
(when (and @view-id main-component) (when (and @view-id main-component)
[react/view {:flex 1} [react/view {:flex 1}
[:> @main-component [:> (if @two-pane? @main-component-two-pane @main-component)
{:ref (fn [r] {:ref (fn [r]
(navigation/set-navigator-ref r) (navigation/set-navigator-ref r)
(when (and (when (and
@ -114,7 +138,7 @@
(not js/goog.DEBUG) (not js/goog.DEBUG)
(not (contains? #{:intro :login :progress} @view-id))) (not (contains? #{:intro :login :progress} @view-id)))
(navigation/navigate-to @view-id nil))) (navigation/navigate-to @view-id nil)))
;; see https://reactnavigation.org/docs/en/state-persistence.html#development-mode ;; see https://reactnavigation.org/docs/en/state-persistence.html#development-mode
:persistNavigationState (when js/goog.DEBUG persist-state) :persistNavigationState (when js/goog.DEBUG persist-state)
:loadNavigationState (when js/goog.DEBUG load-state)}] :loadNavigationState (when js/goog.DEBUG load-state)}]
[signing/signing] [signing/signing]

View File

@ -1,11 +1,15 @@
(ns status-im.utils.dimensions (ns status-im.utils.dimensions
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.ui.components.react :as react])) [status-im.ui.components.react :as react]
[status-im.constants :as constants]))
(declare window)
(defn add-event-listener [] (defn add-event-listener []
(.addEventListener (react/dimensions) (.addEventListener (react/dimensions)
"change" "change"
#(re-frame/dispatch [:update-window-dimensions %]))) #(do
(re-frame/dispatch [:update-window-dimensions %]))))
(defn window (defn window
([] ([]
@ -14,3 +18,7 @@
(-> m (-> m
(js->clj :keywordize-keys true) (js->clj :keywordize-keys true)
:window))) :window)))
(defn fit-two-pane? []
(let [width (get (window) :width)]
(>= width constants/two-pane-min-width)))

View File

@ -1,6 +1,7 @@
(ns status-im.utils.navigation (ns status-im.utils.navigation
(:require [status-im.react-native.js-dependencies :as js-dependencies] (:require [status-im.react-native.js-dependencies :as js-dependencies]
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]
[goog.object :as gobj]))
(def navigation-actions (def navigation-actions
(.-NavigationActions js-dependencies/react-navigation)) (.-NavigationActions js-dependencies/react-navigation))
@ -46,3 +47,8 @@
(.dispatch (.dispatch
@navigator-ref @navigator-ref
(.back navigation-actions)))) (.back navigation-actions))))
(defonce TwoPaneNavigator (gobj/get js-dependencies/react-native-navigation-twopane #js ["createTwoPaneNavigator"]))
(defn twopane-navigator [routeConfigs stackNavigatorConfig]
(TwoPaneNavigator (clj->js routeConfigs) (clj->js stackNavigatorConfig)))

View File

@ -53,4 +53,5 @@
(def desktop-menu #js {}) (def desktop-menu #js {})
(def desktop-config #js {}) (def desktop-config #js {})
(def react-native-mail (fn [] #js {:mail #js {}})) (def react-native-mail (fn [] #js {:mail #js {}}))
(def react-native-navigation-twopane #js {})

View File

@ -1077,6 +1077,7 @@
"network-fee" : "Network fee", "network-fee" : "Network fee",
"sign-with-password" : "Sign with password", "sign-with-password" : "Sign with password",
"signing-a-message" : "Signing a message", "signing-a-message" : "Signing a message",
"select-chat" : "Select chat to start messaging",
"etherscan-lookup": "Look up on Etherscan", "etherscan-lookup": "Look up on Etherscan",
"retry": "Retry", "retry": "Retry",
"ens-deposit": "Deposit", "ens-deposit": "Deposit",