parent
cecb22a89b
commit
0ed19efbb3
|
@ -21,13 +21,14 @@
|
|||
(fx/defn initialize-app-db
|
||||
"Initialize db to initial state"
|
||||
[{{:keys [view-id hardwallet initial-props desktop/desktop
|
||||
supported-biometric-auth network/type]} :db}]
|
||||
supported-biometric-auth network/type app-active-since]} :db now :now}]
|
||||
{:db (assoc app-db
|
||||
:initial-props initial-props
|
||||
:desktop/desktop (merge desktop (:desktop/desktop app-db))
|
||||
:network/type type
|
||||
:hardwallet (dissoc hardwallet :secrets)
|
||||
:supported-biometric-auth supported-biometric-auth
|
||||
:app-active-since (or app-active-since now)
|
||||
:view-id view-id)})
|
||||
|
||||
(fx/defn initialize-views
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
(reg-root-key-sub :get-pairing-installations :pairing/installations)
|
||||
(reg-root-key-sub :tooltips :tooltips)
|
||||
(reg-root-key-sub :supported-biometric-auth :supported-biometric-auth)
|
||||
(reg-root-key-sub :app-active-since :app-active-since)
|
||||
(reg-root-key-sub :connectivity/ui-status-properties :connectivity/ui-status-properties)
|
||||
|
||||
;;NOTE this one is not related to ethereum network
|
||||
;; it is about cellular network/ wifi network
|
||||
|
@ -1489,7 +1491,7 @@
|
|||
;;TODO this subscription looks super weird huge and with dispatches?
|
||||
(re-frame/reg-sub
|
||||
:connectivity/status-properties
|
||||
:<- [:offline?]
|
||||
:<- [:network-status]
|
||||
:<- [:disconnected?]
|
||||
:<- [:mailserver/connecting?]
|
||||
:<- [:mailserver/connection-error?]
|
||||
|
@ -1497,22 +1499,12 @@
|
|||
:<- [:mailserver/fetching?]
|
||||
:<- [:network/type]
|
||||
:<- [:multiaccount]
|
||||
(fn [[offline? disconnected? mailserver-connecting? mailserver-connection-error?
|
||||
(fn [[network-status disconnected? mailserver-connecting? mailserver-connection-error?
|
||||
mailserver-request-error? mailserver-fetching? network-type multiaccount]]
|
||||
(let [wallet-offline? (and offline?
|
||||
;; There's no wallet of desktop
|
||||
(not platform/desktop?))
|
||||
error-label (cond
|
||||
(and wallet-offline?
|
||||
disconnected?)
|
||||
(let [error-label (cond
|
||||
(= network-status :offline)
|
||||
:t/offline
|
||||
|
||||
wallet-offline?
|
||||
:t/wallet-offline
|
||||
|
||||
disconnected?
|
||||
:t/disconnected
|
||||
|
||||
mailserver-connecting?
|
||||
:t/connecting
|
||||
|
||||
|
@ -1526,19 +1518,23 @@
|
|||
(not (:syncing-on-mobile-network? multiaccount)))
|
||||
:mobile-network
|
||||
|
||||
disconnected?
|
||||
:t/offline
|
||||
|
||||
:else nil)]
|
||||
{:message (or error-label :t/connected)
|
||||
:connected? (and (nil? error-label) (not= :mobile-network error-label))
|
||||
:connecting? (= error-label :t/connecting)
|
||||
:loading-indicator? mailserver-fetching?
|
||||
:on-press-fn #(cond
|
||||
:on-press-event (cond
|
||||
mailserver-connection-error?
|
||||
(re-frame/dispatch [:mailserver.ui/reconnect-mailserver-pressed])
|
||||
:mailserver.ui/reconnect-mailserver-pressed
|
||||
|
||||
mailserver-request-error?
|
||||
(re-frame/dispatch [:mailserver.ui/request-error-pressed])
|
||||
:mailserver.ui/request-error-pressed
|
||||
|
||||
(= :mobile-network error-label)
|
||||
(re-frame/dispatch [:mobile-network/show-offline-sheet]))})))
|
||||
:mobile-network/show-offline-sheet)})))
|
||||
|
||||
;;CONTACT ==============================================================================================================
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
(ns status-im.ui.components.connectivity.view
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs] :as views])
|
||||
(:require [reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.connectivity.styles :as styles]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(def connectivity-bar-height 35)
|
||||
(def connectivity-bar-height 36)
|
||||
(def neg-connectivity-bar-height (- connectivity-bar-height))
|
||||
|
||||
(defn easing [direction n]
|
||||
|
@ -68,9 +70,12 @@
|
|||
|
||||
(def to-hide? (reagent/atom false))
|
||||
|
||||
(defn manage-visibility [connected? anim-opacity anim-y]
|
||||
(defn manage-visibility [connected? animate? anim-opacity anim-y status-hidden]
|
||||
"status-hidden is a per-view state, while to-hide? is a global state common to
|
||||
all connectivity views (we have at least one view in home and one in chat)"
|
||||
(if connected?
|
||||
(when @to-hide?
|
||||
(if animate?
|
||||
(when (and @to-hide? (not @status-hidden))
|
||||
(animation/start
|
||||
(animation/parallel
|
||||
[(animation/timing anim-opacity
|
||||
|
@ -86,8 +91,15 @@
|
|||
:easing (.-ease (animation/easing))
|
||||
:useNativeDriver true})])
|
||||
;; second param of start() - a callback that fires when animation stops
|
||||
#(reset! to-hide? false)))
|
||||
#(do (reset! to-hide? false) (reset! status-hidden true))))
|
||||
(do
|
||||
(animation/set-value anim-opacity 0)
|
||||
(animation/set-value anim-y (if platform/desktop? 0 neg-connectivity-bar-height))
|
||||
(reset! to-hide? false)
|
||||
(reset! status-hidden true)))
|
||||
;; else
|
||||
(if animate?
|
||||
(when (and (not @to-hide?) @status-hidden)
|
||||
(animation/start
|
||||
(animation/parallel
|
||||
[(animation/timing anim-opacity
|
||||
|
@ -101,21 +113,33 @@
|
|||
:easing (.-ease (animation/easing))
|
||||
:useNativeDriver true})])
|
||||
;; second param of start() - a callback that fires when animation stops
|
||||
#(reset! to-hide? true))))
|
||||
#(do (reset! to-hide? true) (reset! status-hidden false))))
|
||||
(do
|
||||
(animation/set-value anim-opacity 1)
|
||||
(animation/set-value anim-y (if platform/desktop? connectivity-bar-height 0))
|
||||
(reset! to-hide? true)
|
||||
(reset! status-hidden false)))))
|
||||
|
||||
(defn connectivity-status
|
||||
[{:keys [connected?]} anim-translate-y]
|
||||
[{:keys [connected?]} anim-translate-y status-hidden]
|
||||
(let [anim-translate-y (or anim-translate-y (animation/create-value 0))
|
||||
anim-opacity (animation/create-value 0)]
|
||||
(manage-visibility connected?
|
||||
anim-opacity anim-translate-y)
|
||||
(reagent/create-class
|
||||
{:component-did-update
|
||||
{:component-did-mount
|
||||
(fn []
|
||||
(manage-visibility connected? false
|
||||
anim-opacity anim-translate-y status-hidden))
|
||||
:should-component-update
|
||||
;; ignore :loading-indicator?
|
||||
(fn [_ [_ old_p] [_ new_p]]
|
||||
(not= (dissoc old_p :loading-indicator?)
|
||||
(dissoc new_p :loading-indicator?)))
|
||||
:component-did-update
|
||||
(fn [comp]
|
||||
(manage-visibility (:connected? (reagent/props comp))
|
||||
anim-opacity anim-translate-y))
|
||||
(manage-visibility (:connected? (reagent/props comp)) true
|
||||
anim-opacity anim-translate-y status-hidden))
|
||||
:reagent-render
|
||||
(fn [{:keys [view-id message on-press-fn connected? connecting?] :as opts}]
|
||||
(fn [{:keys [view-id message on-press-event connected? connecting?] :as opts}]
|
||||
[react/animated-view {:style (styles/text-wrapper
|
||||
(assoc opts
|
||||
:height (if platform/desktop?
|
||||
|
@ -133,29 +157,94 @@
|
|||
[react/activity-indicator {:color colors/white :margin-right 6}])
|
||||
(if (= message :mobile-network)
|
||||
[react/nested-text {:style styles/text
|
||||
:on-press on-press-fn}
|
||||
:on-press (when on-press-event #(re-frame/dispatch [on-press-event]))}
|
||||
(i18n/label :t/waiting-for-wifi) " "
|
||||
[{:style {:text-decoration-line :underline}}
|
||||
(i18n/label :t/waiting-for-wifi-change)]]
|
||||
(when message
|
||||
[react/text {:style styles/text
|
||||
:on-press on-press-fn}
|
||||
(i18n/label message)])])})))
|
||||
:on-press (when on-press-event #(re-frame/dispatch [on-press-event]))}
|
||||
(i18n/label message)]))])})))
|
||||
|
||||
;; timer updating the enqueued status
|
||||
(def timer (atom nil))
|
||||
|
||||
;; connectivity status change going to be persisted to :connectivity/ui-status-properties
|
||||
(def enqueued-connectivity-status-properties (atom nil))
|
||||
|
||||
(defn propagate-status
|
||||
"Smoothly propagate from :connectivity/status-properties subscription to
|
||||
:ui-status-properties db. UI components will render based on :ui-status-properties"
|
||||
[{:keys [status-properties app-active-since ui-status-properties]}]
|
||||
(let [;; enqueued or immediate?
|
||||
;; send immediately if we are transitioning to an offline state
|
||||
enqueue? (cond
|
||||
(and
|
||||
(or
|
||||
(nil? @enqueued-connectivity-status-properties)
|
||||
(:connected? @enqueued-connectivity-status-properties)
|
||||
(:connecting? @enqueued-connectivity-status-properties))
|
||||
(not
|
||||
(or (:connected? status-properties)
|
||||
(:connecting? status-properties))))
|
||||
false
|
||||
|
||||
:else
|
||||
true)]
|
||||
(if enqueue?
|
||||
(when (or (and (nil? @enqueued-connectivity-status-properties)
|
||||
(not= status-properties ui-status-properties))
|
||||
(and (some? @enqueued-connectivity-status-properties)
|
||||
(not= status-properties @enqueued-connectivity-status-properties)))
|
||||
;; reset queued with new state and start a timer if not yet started
|
||||
(reset! enqueued-connectivity-status-properties status-properties)
|
||||
(when-not @timer
|
||||
(reset! timer (utils/set-timeout #(do
|
||||
(reset! timer nil)
|
||||
(when @enqueued-connectivity-status-properties
|
||||
(re-frame/dispatch [:set :connectivity/ui-status-properties @enqueued-connectivity-status-properties])
|
||||
(reset! enqueued-connectivity-status-properties nil)))
|
||||
|
||||
;; if the app is in foreground for less than 5s, postpone state changes for 5s otherwise 1s
|
||||
(if
|
||||
(and app-active-since
|
||||
(< (- (datetime/timestamp) app-active-since)
|
||||
5000))
|
||||
5000
|
||||
1000)))))
|
||||
(when (not= status-properties ui-status-properties)
|
||||
;; send immediately
|
||||
(reset! enqueued-connectivity-status-properties nil)
|
||||
(re-frame/dispatch [:set :connectivity/ui-status-properties status-properties])
|
||||
(when @timer
|
||||
(utils/clear-timeout @timer)
|
||||
(reset! timer nil))))))
|
||||
|
||||
(defn status-propagator-dummy-view
|
||||
"this empty view is needed to react propagate status-properties to ui-status-properties"
|
||||
[props]
|
||||
(reagent/create-class
|
||||
{:component-did-mount
|
||||
#(propagate-status props)
|
||||
:should-component-update
|
||||
(fn [_ _ [_ props]]
|
||||
(propagate-status props)
|
||||
false)
|
||||
:reagent-render
|
||||
#()}))
|
||||
|
||||
(defview connectivity-view [anim-translate-y]
|
||||
(letsubs [status-properties [:connectivity/status-properties]
|
||||
app-active-since [:app-active-since]
|
||||
ui-status-properties [:connectivity/ui-status-properties]
|
||||
status-hidden (reagent/atom true)
|
||||
view-id [:view-id]
|
||||
window-width (reagent/atom 0)]
|
||||
{:component-did-mount
|
||||
(fn []
|
||||
(when anim-translate-y
|
||||
(if (:connected? status-properties)
|
||||
(animation/set-value anim-translate-y neg-connectivity-bar-height)
|
||||
(animation/set-value anim-translate-y 0))))}
|
||||
(let [{:keys [loading-indicator?]} status-properties]
|
||||
(let [loading-indicator? (:loading-indicator? ui-status-properties)]
|
||||
[react/view {:style {:align-items :stretch
|
||||
:z-index 1}
|
||||
:on-layout #(reset! window-width (-> % .-nativeEvent .-layout .-width))}
|
||||
(when loading-indicator?
|
||||
(when (and loading-indicator? @status-hidden)
|
||||
[loading-indicator @window-width])
|
||||
;; This view below exists only to hide the connectivity-status bar when "connected".
|
||||
;; Ideally connectivity-status bar would be hidden under "toolbar/toolbar",
|
||||
|
@ -169,10 +258,16 @@
|
|||
:height connectivity-bar-height
|
||||
:background-color colors/white}]
|
||||
[connectivity-status
|
||||
(merge status-properties
|
||||
;on startup default connected
|
||||
(merge (or ui-status-properties
|
||||
{:connected? true :message :t/connected})
|
||||
{:view-id view-id
|
||||
:window-width @window-width})
|
||||
anim-translate-y]])))
|
||||
anim-translate-y
|
||||
status-hidden]
|
||||
[status-propagator-dummy-view {:status-properties status-properties
|
||||
:app-active-since app-active-since
|
||||
:ui-status-properties ui-status-properties}]])))
|
||||
|
||||
;; "push?" determines whether "content" gets pushed down when disconnected
|
||||
;; like in :home view, or stays put like in :chat view
|
||||
|
|
|
@ -78,9 +78,12 @@
|
|||
(spec/def ::tab-bar-visible? (spec/nilable boolean?))
|
||||
;;:online - presence of internet connection in the phone
|
||||
(spec/def ::network-status (spec/nilable keyword?))
|
||||
;; ui connectivity status
|
||||
(spec/def :connectivity/ui-status-properties (spec/nilable map?))
|
||||
|
||||
(spec/def ::app-state string?)
|
||||
(spec/def ::app-in-background-since (spec/nilable number?))
|
||||
(spec/def ::app-active-since (spec/nilable number?))
|
||||
|
||||
;;;;NODE
|
||||
|
||||
|
@ -275,6 +278,7 @@
|
|||
::chain
|
||||
::app-state
|
||||
::app-in-background-since
|
||||
::app-active-since
|
||||
::hardwallet
|
||||
::auth-method
|
||||
:multiaccount/multiaccount
|
||||
|
@ -301,6 +305,7 @@
|
|||
:chat/last-clock-value
|
||||
:chat/loaded-chats
|
||||
:chat/bot-db
|
||||
:connectivity/ui-status-properties
|
||||
:ens/registration
|
||||
:wallet/wallet
|
||||
:prices/prices
|
||||
|
|
|
@ -145,15 +145,18 @@
|
|||
(>= (- now app-in-background-since)
|
||||
const/ms-in-bg-for-require-bioauth))]
|
||||
(fx/merge cofx
|
||||
{:db (assoc db :app-in-background-since nil)}
|
||||
{:db (-> db
|
||||
(dissoc :app-in-background-since)
|
||||
(assoc :app-active-since now))}
|
||||
(mailserver/process-next-messages-request)
|
||||
(hardwallet/return-back-from-nfc-settings)
|
||||
#(when requires-bio-auth
|
||||
(biometric/authenticate % on-biometric-auth-result authentication-options)))))
|
||||
|
||||
(fx/defn on-going-in-background [{:keys [db now] :as cofx}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc db :app-in-background-since now)}))
|
||||
(fx/defn on-going-in-background [{:keys [db now]}]
|
||||
{:db (-> db
|
||||
(dissoc :app-active-since)
|
||||
(assoc :app-in-background-since now))})
|
||||
|
||||
(defn app-state-change [state {:keys [db] :as cofx}]
|
||||
(let [app-coming-from-background? (= state "active")
|
||||
|
|
|
@ -1082,7 +1082,7 @@
|
|||
"view-profile": "View profile",
|
||||
"view-signing": "View signing phrase",
|
||||
"view-superrare": "View in SuperRare",
|
||||
"waiting-for-wifi": "History syncing offline, waiting for Wi-Fi.",
|
||||
"waiting-for-wifi": "Offline, waiting for Wi-Fi.",
|
||||
"waiting-for-wifi-change": "Change",
|
||||
"waiting-to-sign": "Waiting to sign transaction...",
|
||||
"wallet": "Wallet",
|
||||
|
|
Loading…
Reference in New Issue