From 54546204ae18bd7fbe9b85b1b847db915efe7ead Mon Sep 17 00:00:00 2001 From: Eric Dvorsak Date: Fri, 2 Mar 2018 20:46:55 +0100 Subject: [PATCH] [fix 3424] visually indicated when mailserver or all peers are disconnected Signed-off-by: Pedro Pombeiro --- src/status_im/chat/screen.cljs | 4 +- .../chat/views/input/result_box.cljs | 4 +- src/status_im/protocol/handlers.cljs | 185 +++++++++++------- src/status_im/translations/en.cljs | 1 + .../{sync_state => connectivity}/styles.cljs | 2 +- .../ui/components/connectivity/view.cljs | 41 ++++ .../ui/components/sync_state/offline.cljs | 39 ---- src/status_im/ui/screens/db.cljs | 5 + src/status_im/ui/screens/home/views.cljs | 4 +- src/status_im/ui/screens/subs.cljs | 25 ++- 10 files changed, 183 insertions(+), 127 deletions(-) rename src/status_im/ui/components/{sync_state => connectivity}/styles.cljs (90%) create mode 100644 src/status_im/ui/components/connectivity/view.cljs delete mode 100644 src/status_im/ui/components/sync_state/offline.cljs diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index dea804334b..eff001d447 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -15,7 +15,7 @@ [status-im.ui.components.list-selection :as list-selection] [status-im.ui.components.react :as react] [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.components.sync-state.offline :as offline] + [status-im.ui.components.connectivity.view :as connectivity] [status-im.ui.components.toolbar.view :as toolbar] [status-im.utils.platform :as platform])) @@ -103,4 +103,4 @@ [input/container {:text-empty? (string/blank? input-text)}] (when show-bottom-info? [bottom-info/bottom-info-view]) - [offline/offline-view {:top (get platform/platform-specific :status-bar-default-height)}]])) + [connectivity/error-view {:top (get platform/platform-specific :status-bar-default-height)}]])) diff --git a/src/status_im/chat/views/input/result_box.cljs b/src/status_im/chat/views/input/result_box.cljs index 8bd42a76b0..c791e46675 100644 --- a/src/status_im/chat/views/input/result_box.cljs +++ b/src/status_im/chat/views/input/result_box.cljs @@ -8,7 +8,7 @@ icon]] [status-im.chat.views.input.animations.expandable :refer [expandable-view]] [status-im.chat.views.input.box-header :as box-header] - [status-im.ui.components.sync-state.offline :refer [offline-view]])) + [status-im.ui.components.connectivity.view :as connectivity])) (defview result-box-container [markup] [view {:flex 1} @@ -20,4 +20,4 @@ [expandable-view {:key :result-box :custom-header (box-header/get-header :result-box)} [result-box-container markup] - [offline-view]])) + [connectivity/error-view]])) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index ea306b0949..a1923bcbd3 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -241,108 +241,143 @@ #(re-frame/dispatch [::request-messages-error %])))) (re-frame/reg-fx - ::handle-whisper-message - listeners/handle-whisper-message) + ::handle-whisper-message + listeners/handle-whisper-message) ;;;; Handlers + +(defn get-wnode [db] + (let [wnode-id (get db :inbox/wnode)] + (get-in db [:inbox/wnodes wnode-id :address]))) + +(defn connectivity-check [peers {:keys [db] :as cofx}] + (let [wnode (get-wnode db) + peers-count (count peers) + mailserver-connected? (inbox/registered-peer? peers wnode)] + {:db (cond-> db + mailserver-connected? (dissoc :mailserver-status) + (not mailserver-connected?) (assoc :mailserver-status :disconnected) + :always (assoc :peers-count peers-count))})) + +(re-frame/reg-fx + :connectivity/fetch-peers + (fn [{:keys [wnode web3 retries]}] + (inbox/fetch-peers #(re-frame/dispatch [:connectivity-check-success %]) + #(log/error :connectivity/fetch-peers %)))) + +(handlers/register-handler-fx + :connectivity-check + (fn [{:keys [db]} _] + (let [web3 (:web3 db) + wnode (get-wnode db)] + {:connectivity/fetch-peers {:wnode wnode + :web3 web3}}))) + +(handlers/register-handler-fx + :connectivity-check-success + (fn [{:keys [db] :as cofx} [_ peers]] + (handlers/merge-fx cofx + {:dispatch-later [{:ms 30000 :dispatch [:connectivity-check]}]} + (connectivity-check peers)))) + ;; NOTE(dmitryn): events chain ;; add-peer -> fetch-peers -> mark-trusted-peer -> get-sym-key -> request-messages (handlers/register-handler-fx - :initialize-offline-inbox - (fn [{:keys [db]} [_ web3]] - (log/info "offline inbox: initialize") - (let [wnode-id (get db :inbox/wnode) - wnode (get-in db [:inbox/wnodes wnode-id :address])] - {::add-peer {:wnode wnode - :web3 web3}}))) + :initialize-offline-inbox + (fn [{:keys [db]} [_ web3]] + (log/info "offline inbox: initialize") + (let [wnode (get-wnode db)] + {::add-peer {:wnode wnode + :web3 web3}}))) (handlers/register-handler-fx - ::add-peer-success - (fn [{:keys [db]} [_ web3 response]] - (let [wnode-id (get db :inbox/wnode) - wnode (get-in db [:inbox/wnodes wnode-id :address])] - (log/info "offline inbox: add-peer response" wnode response) - {::fetch-peers {:wnode wnode - :web3 web3 - :retries 0}}))) + ::add-peer-success + (fn [{:keys [db]} [_ web3 response]] + (let [wnode (get-wnode db)] + (log/info "offline inbox: add-peer response" wnode response) + {::fetch-peers {:wnode wnode + :web3 web3 + :retries 0}}))) (handlers/register-handler-fx - ::fetch-peers-success - (fn [{:keys [db]} [_ web3 peers retries]] - (let [wnode-id (get db :inbox/wnode) - wnode (get-in db [:inbox/wnodes wnode-id :address])] - (log/info "offline inbox: fetch-peers response" peers) - (if (inbox/registered-peer? peers wnode) - {::mark-trusted-peer {:wnode wnode - :web3 web3 - :peers peers}} - (do - (log/info "Peer" wnode "is not registered. Retrying fetch peers.") - {::fetch-peers {:wnode wnode - :web3 web3 - :retries (inc retries)}}))))) + ::fetch-peers-success + (fn [{:keys [db] :as cofx} [_ web3 peers retries]] + (let [wnode (get-wnode db)] + (log/info "offline inbox: fetch-peers response" peers) + (if (inbox/registered-peer? peers wnode) + (handlers/merge-fx cofx + {::mark-trusted-peer {:wnode wnode + :web3 web3 + :peers peers} + :dispatch-later [{:ms 30000 :dispatch [:connectivity-check]}]} + (connectivity-check peers)) + (do + (log/info "Peer" wnode "is not registered. Retrying fetch peers.") + (handlers/merge-fx cofx + {::fetch-peers {:wnode wnode + :web3 web3 + :retries (inc retries)}} + (connectivity-check peers))))))) (handlers/register-handler-fx - ::mark-trusted-peer-success - (fn [{:keys [db]} [_ web3 response]] - (let [wnode-id (get db :inbox/wnode) - wnode (get-in db [:inbox/wnodes wnode-id :address]) - password (:inbox/password db)] - (log/info "offline inbox: mark-trusted-peer response" wnode response) - {::get-sym-key {:password password - :web3 web3}}))) + ::mark-trusted-peer-success + (fn [{:keys [db]} [_ web3 response]] + (let [wnode (get-wnode db) + password (:inbox/password db)] + (log/info "offline inbox: mark-trusted-peer response" wnode response) + {::get-sym-key {:password password + :web3 web3}}))) (handlers/register-handler-fx - ::get-sym-key-success - (fn [{:keys [db]} [_ web3 sym-key-id]] - (log/info "offline inbox: get-sym-key response" sym-key-id) - (let [wnode-id (get db :inbox/wnode) - wnode (get-in db [:inbox/wnodes wnode-id :address]) - topic (:inbox/topic db)] - {::request-messages {:wnode wnode - :topic topic - :sym-key-id sym-key-id - :web3 web3}}))) + ::get-sym-key-success + (fn [{:keys [db]} [_ web3 sym-key-id]] + (log/info "offline inbox: get-sym-key response" sym-key-id) + (let [wnode (get-wnode db) + topic (:inbox/topic db)] + {::request-messages {:wnode wnode + :topic topic + :sym-key-id sym-key-id + :web3 web3}}))) (handlers/register-handler-fx - ::request-messages-success - (fn [_ [_ response]] - (log/info "offline inbox: request-messages response" response))) + ::request-messages-success + (fn [_ [_ response]] + (log/info "offline inbox: request-messages response" response))) (handlers/register-handler-fx - ::add-peer-error - (fn [_ [_ error]] - (log/error "offline inbox: add-peer error" error))) + ::add-peer-error + (fn [_ [_ error]] + (log/error "offline inbox: add-peer error" error))) (handlers/register-handler-fx - ::fetch-peers-error - (fn [_ [_ error]] - (log/error "offline inbox: fetch-peers error" error))) + ::fetch-peers-error + (fn [_ [_ error]] + (log/error "offline inbox: fetch-peers error" error))) (handlers/register-handler-fx - ::mark-trusted-peer-error - (fn [_ [_ error]] - (log/error "offline inbox: mark-trusted-peer error" error))) + ::mark-trusted-peer-error + (fn [_ [_ error]] + (log/error "offline inbox: mark-trusted-peer error" error))) (handlers/register-handler-fx - ::get-sym-key-error - (fn [_ [_ error]] - (log/error "offline inbox: get-sym-key error" error))) + ::get-sym-key-error + (fn [_ [_ error]] + (log/error "offline inbox: get-sym-key error" error))) (handlers/register-handler-fx - ::request-messages-error - (fn [_ [_ error]] - (log/error "offline inbox: request-messages error" error))) + ::request-messages-error + (fn [_ [_ error]] + (log/error "offline inbox: request-messages error" error))) (handlers/register-handler-fx - :handle-whisper-message - (fn [_ [_ error msg options]] - {::handle-whisper-message {:error error - :msg msg - :options options}})) + :handle-whisper-message + (fn [_ [_ error msg options]] + {::handle-whisper-message {:error error + :msg msg + :options options}})) ;;; INITIALIZE PROTOCOL (handlers/register-handler-fx @@ -361,7 +396,7 @@ :updates-public-key updates-public-key :updates-private-key updates-private-key :status status :contacts all-contacts} :db (assoc db :web3 web3 - :rpc-url (or ethereum-rpc-url constants/ethereum-rpc-url))})))) + :rpc-url (or ethereum-rpc-url constants/ethereum-rpc-url))})))) (handlers/register-handler-fx :load-processed-messages @@ -461,8 +496,8 @@ (when (nil? route-fx) (log/debug "Unknown message type" type)) (cache/add! processed-message) (merge - {::save-processed-messages processed-message} - route-fx)))))) + {::save-processed-messages processed-message} + route-fx)))))) (handlers/register-handler-fx :update-message-status diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 18b4cdf5ed..450cd72868 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -8,6 +8,7 @@ :chat-name "Chat name" :notifications-title "Notifications and sounds" :offline "Offline" + :connection-problem "Messages connection problem" :search-for "Search for..." :cancel "Cancel" :next "Next" diff --git a/src/status_im/ui/components/sync_state/styles.cljs b/src/status_im/ui/components/connectivity/styles.cljs similarity index 90% rename from src/status_im/ui/components/sync_state/styles.cljs rename to src/status_im/ui/components/connectivity/styles.cljs index e9848f7cd7..753a8bec4f 100644 --- a/src/status_im/ui/components/sync_state/styles.cljs +++ b/src/status_im/ui/components/connectivity/styles.cljs @@ -1,4 +1,4 @@ -(ns status-im.ui.components.sync-state.styles +(ns status-im.ui.components.connectivity.styles (:require-macros [status-im.utils.styles :refer [defnstyle]])) (defnstyle offline-wrapper [top opacity window-width pending?] diff --git a/src/status_im/ui/components/connectivity/view.cljs b/src/status_im/ui/components/connectivity/view.cljs new file mode 100644 index 0000000000..a2b03f8414 --- /dev/null +++ b/src/status_im/ui/components/connectivity/view.cljs @@ -0,0 +1,41 @@ +(ns status-im.ui.components.connectivity.view + (:require [re-frame.core :as re-frame] + [reagent.core :as reagent] + [status-im.ui.components.react :as react] + [status-im.ui.components.connectivity.styles :as styles] + [status-im.ui.components.animation :as animation] + [status-im.i18n :as i18n])) + +(def window-width (:width (react/get-dimensions "window"))) + +(defn start-error-animation [offline-opacity] + (animation/start + (animation/timing offline-opacity {:toValue 1.0 + :duration 250}))) + +(defn error-view [_] + (let [offline? (re-frame/subscribe [:offline?]) + connection-problem? (re-frame/subscribe [:connection-problem?]) + offline-opacity (animation/create-value 0.0) + on-update (fn [_ _] + (animation/set-value offline-opacity 0) + (when (or @offline? @connection-problem?) + (start-error-animation offline-opacity))) + pending-contact? (re-frame/subscribe [:current-contact :pending?]) + view-id (re-frame/subscribe [:get :view-id])] + (reagent/create-class + {:component-did-mount + on-update + :component-did-update + on-update + :display-name "connectivity-error-view" + :reagent-render + (fn [{:keys [top]}] + (when (or @offline? @connection-problem?) + (let [pending? (and @pending-contact? (= :chat @view-id))] + [react/animated-view {:style (styles/offline-wrapper top offline-opacity window-width pending?)} + [react/view + [react/text {:style styles/offline-text} + (i18n/label (if @connection-problem? + :t/connection-problem + :t/offline))]]])))}))) diff --git a/src/status_im/ui/components/sync_state/offline.cljs b/src/status_im/ui/components/sync_state/offline.cljs deleted file mode 100644 index c59ac6815b..0000000000 --- a/src/status_im/ui/components/sync_state/offline.cljs +++ /dev/null @@ -1,39 +0,0 @@ -(ns status-im.ui.components.sync-state.offline - (:require [re-frame.core :as re-frame] - [reagent.core :as reagent] - [status-im.ui.components.react :as react] - [status-im.ui.components.sync-state.styles :as styles] - [status-im.ui.components.animation :as animation] - [status-im.i18n :as i18n])) - -(def window-width (:width (react/get-dimensions "window"))) - -(defn start-offline-animation [offline-opacity] - (animation/start - (animation/timing offline-opacity {:toValue 1.0 - :duration 250}))) - -(defn offline-view [_] - (let [sync-state (re-frame/subscribe [:sync-state]) - network-status (re-frame/subscribe [:get :network-status]) - offline-opacity (animation/create-value 0.0) - on-update (fn [_ _] - (animation/set-value offline-opacity 0) - (when (or (= @network-status :offline) (= @sync-state :offline)) - (start-offline-animation offline-opacity))) - pending-contact? (re-frame/subscribe [:current-contact :pending?]) - view-id (re-frame/subscribe [:get :view-id])] - (reagent/create-class - {:component-did-mount - on-update - :component-did-update - on-update - :display-name "offline-view" - :reagent-render - (fn [{:keys [top]}] - (when (or (= @network-status :offline) (= @sync-state :offline)) - (let [pending? (and @pending-contact? (= :chat @view-id))] - [react/animated-view {:style (styles/offline-wrapper top offline-opacity window-width pending?)} - [react/view - [react/text {:style styles/offline-text} - (i18n/label :t/offline)]]])))}))) diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index f2cbe097c9..9ee824b797 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -68,6 +68,9 @@ ;;:online - presence of internet connection in the phone (spec/def ::network-status (spec/nilable keyword?)) +(spec/def ::mailserver-status (spec/nilable keyword?)) +(spec/def ::peers-count (spec/nilable integer?)) + ;;;;NODE (spec/def ::sync-listening-started (spec/nilable boolean?)) @@ -174,6 +177,8 @@ ::keyboard-max-height ::orientation ::network-status + ::mailserver-status + ::peers-count ::sync-listening-started ::sync-state ::sync-data diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index 7ef9ea0d77..03c12654f3 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -7,7 +7,7 @@ [status-im.ui.components.native-action-button :refer [native-action-button]] [status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.actions :as toolbar.actions] - [status-im.ui.components.sync-state.offline :refer [offline-view]] + [status-im.ui.components.connectivity.view :as connectivity] [status-im.ui.screens.home.views.inner-item :as inner-item] [status-im.ui.screens.home.styles :as styles] [status-im.ui.components.icons.vector-icons :as vector-icons] @@ -86,4 +86,4 @@ ^{:key home-item-id} [home-list-deletable home-item])}]) (when platform/android? [home-action-button]) - [offline-view]])) + [connectivity/error-view]])) diff --git a/src/status_im/ui/screens/subs.cljs b/src/status_im/ui/screens/subs.cljs index c1994a065b..645d7a3765 100644 --- a/src/status_im/ui/screens/subs.cljs +++ b/src/status_im/ui/screens/subs.cljs @@ -31,13 +31,26 @@ (fn [current-account] (:signed-up? current-account))) -(reg-sub :network - (fn [db] - (:network db))) +(reg-sub :network :network) -(reg-sub :sync-state - (fn [db] - (:sync-state db))) +(reg-sub :sync-state :sync-state) +(reg-sub :network-status :network-status) +(reg-sub :peers-count :peers-count) +(reg-sub :mailserver-status :mailserver-status) + +(reg-sub :offline? + :<- [:network-status] + :<- [:sync-state] + (fn [[network-status sync-state]] + (or (= network-status :offline) + (= sync-state :offline)))) + +(reg-sub :connection-problem? + :<- [:mailserver-status] + :<- [:peers-count] + (fn [[mailserver-status peers-count]] + (or (= :disconnected mailserver-status) + (zero? peers-count)))) (reg-sub :syncing? :<- [:sync-state]