[fix 5371] status bar covers touchable UI

- fix #5371
- fix #4345
- introduce "Connected..." status bar
- introduce fetching animation
- removes overlap of status bar with views
- add animations for status bar

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2018-12-18 11:05:28 +01:00
parent 760956dfe1
commit 8ef905edfb
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
10 changed files with 208 additions and 116 deletions

View File

@ -12,14 +12,10 @@
(get db :mailserver/pending-requests)))
(re-frame/reg-sub
:mailserver/fetching?
:mailserver/connecting?
:<- [:mailserver/state]
:<- [:mailserver/pending-requests]
(fn [[state pending-requests]]
(when (and pending-requests
(= state :connected)
(pos-int? pending-requests))
pending-requests)))
(fn [state]
(#{:connecting :added} state)))
(re-frame/reg-sub
:mailserver/connection-error?
@ -32,6 +28,19 @@
(fn [db]
(get db :mailserver/request-error)))
(re-frame/reg-sub
:mailserver/fetching?
:<- [:mailserver/state]
:<- [:mailserver/pending-requests]
:<- [:mailserver/connecting?]
:<- [:mailserver/connection-error?]
:<- [:mailserver/request-error?]
(fn [[state pending-requests connecting? connection-error? request-error?]]
(and pending-requests
(= state :connected)
(pos-int? pending-requests)
(not (or connecting? connection-error? request-error?)))))
(re-frame/reg-sub
:mailserver/current-id
(fn [db]

View File

@ -3,26 +3,22 @@
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform]))
(defnstyle text-wrapper [{:keys [top window-width pending? modal?]}]
(cond->
{:opacity 1.0
:background-color colors/gray
:height 35
:position :absolute}
(defnstyle text-wrapper
[{:keys [window-width modal? height background-color opacity]}]
(cond-> {:flex-direction :row
:justify-content :center
:opacity opacity
:background-color (or background-color colors/gray)
:height height}
platform/desktop?
(assoc
:left 0
:right 0)
(assoc :left 0
:right 0)
(not platform/desktop?)
(assoc
:ios {:z-index 0}
:width window-width
:top (+ top
(if (and modal? platform/android?) 31 56)
(if pending? 35 0)))))
(assoc :width window-width)))
(def text
{:text-align :center
:color :white
{:color :white
:font-size 14
:top 8})

View File

@ -0,0 +1,50 @@
(ns status-im.ui.components.connectivity.subs
(:require [re-frame.core :as re-frame]
[status-im.utils.platform :as utils.platform]
[status-im.i18n :as i18n]))
(re-frame/reg-sub
:connectivity/status-properties
:<- [:offline?]
:<- [:disconnected?]
:<- [:mailserver/connecting?]
:<- [:mailserver/connection-error?]
:<- [:mailserver/request-error?]
:<- [:mailserver/fetching?]
(fn [[offline? disconnected? mailserver-connecting? mailserver-connection-error?
mailserver-request-error? mailserver-fetching?]]
(let [wallet-offline? (and offline?
;; There's no wallet of desktop
(not utils.platform/desktop?))
error-label (cond
(and wallet-offline?
disconnected?)
:t/offline
wallet-offline?
:t/wallet-offline
disconnected?
:t/disconnected
mailserver-connecting?
:t/connecting
mailserver-connection-error?
:t/mailserver-reconnect
mailserver-request-error?
:t/mailserver-request-error-status
:else nil)]
{:message (i18n/label (or error-label :t/connected))
:connected? (nil? error-label)
:connecting? (= error-label :t/connecting)
:loading-indicator? mailserver-fetching?
:on-press-fn #(cond
mailserver-connection-error?
(re-frame/dispatch
[:mailserver.ui/reconnect-mailserver-pressed])
mailserver-request-error?
(re-frame/dispatch
[:mailserver.ui/request-error-pressed]))})))

View File

@ -5,62 +5,117 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.connectivity.styles :as styles]
[status-im.utils.platform :as utils.platform]
[status-im.i18n :as i18n]))
[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]))
(defview error-label
[{:keys [view-id label mailserver-fetching? mailserver-connection-error?
mailserver-request-error?] :as opts}]
{:should-component-update
(fn [_ [_ old-props] [_ new-props]]
;; prevents flickering on navigation
(= (:view-id old-props) (:view-id new-props)))}
(let [wrapper-style (styles/text-wrapper
(assoc opts :modal? (= view-id :chat-modal)))]
[react/view {:style wrapper-style
:accessibility-label :connection-status-text}
[react/text {:style styles/text
:on-press #(cond
mailserver-connection-error?
(re-frame/dispatch [:mailserver.ui/reconnect-mailserver-pressed])
mailserver-request-error?
(re-frame/dispatch [:mailserver.ui/request-error-pressed]))}
(if (and (not (or mailserver-connection-error?
mailserver-request-error?))
mailserver-fetching?)
(i18n/label :t/fetching-messages {:requests-left (str mailserver-fetching?)})
(i18n/label label))]]))
(views/defview loading-indicator [parent-width]
(views/letsubs [anim-width (animation/create-value (* 0.15 parent-width))
anim-x (animation/create-value 0)
easing-in (fn [n] {:toValue (* n parent-width)
:easing (.in (animation/easing) (.-quad (animation/easing)))
:duration 400})
easing-out (fn [n] {:toValue (* n parent-width)
:easing (.out (animation/easing) (.-quad (animation/easing)))
:duration 400})]
{:component-did-mount (fn [_]
(animation/start
(animation/anim-loop
(animation/anim-sequence
[(animation/parallel
[(animation/timing anim-width (easing-in 0.6))
(animation/timing anim-x (easing-in 0.2))])
(animation/parallel
[(animation/timing anim-width (easing-out 0.15))
(animation/timing anim-x (easing-out 0.85))])
(animation/parallel
[(animation/timing anim-width (easing-in 0.6))
(animation/timing anim-x (easing-in 0.2))])
(animation/parallel
[(animation/timing anim-width (easing-out 0.15))
(animation/timing anim-x (easing-out 0))])]))))}
[react/view {:style {:width parent-width
:height 3
:background-color colors/blue-light}}
[react/animated-view {:style {:margin-left anim-x
:width anim-width
:height 3
:background-color colors/blue}}]]))
(defview error-view [{:keys [top]}]
(letsubs [offline? [:offline?]
disconnected? [:disconnected?]
mailserver-connection-error? [:mailserver/connection-error?]
mailserver-request-error? [:mailserver/request-error?]
mailserver-fetching? [:mailserver/fetching?]
current-chat-contact [:chats/current-chat-contact]
view-id [:get :view-id]
window-width [:dimensions/window-width]]
(let [wallet-offline? (and offline?
;; There's no wallet of desktop
(not utils.platform/desktop?))]
(defonce show-connected? (reagent/atom true))
(when-let [label (cond
(and wallet-offline?
disconnected?) :t/offline
(defn manage-visibility [connected? anim-opacity anim-height]
(if connected?
(do (animation/start
(animation/parallel
[(animation/timing anim-opacity
{:toValue 0
:delay 800
:duration 150
:easing (.-ease (animation/easing))})
(animation/timing anim-height
{:toValue 0
:delay 800
:duration 150
:easing (.-ease (animation/easing))})]))
(utils/set-timeout
#(reset! show-connected? false)
2000))
(do (reset! show-connected? true)
(animation/start
(animation/parallel
[(animation/timing anim-opacity
{:toValue 1
:duration 150
:easing (.-ease (animation/easing))})
(animation/timing anim-height
{:toValue 35
:duration 150
:easing (.-ease (animation/easing))})])))))
wallet-offline? :t/wallet-offline
disconnected? :t/disconnected
(defn connectivity-status
[{:keys [connected?]}]
(let [anim-opacity (animation/create-value 0)
anim-height (animation/create-value 0)]
(manage-visibility connected?
anim-opacity anim-height)
(reagent/create-class
{:component-did-update
(fn [comp]
(manage-visibility (:connected? (reagent/props comp))
anim-opacity anim-height))
:reagent-render
(fn [{:keys [view-id message on-press-fn
connected? connecting? loading-indicator?] :as opts}]
(when (or (not connected?)
@show-connected?)
[react/animated-view {:style (styles/text-wrapper
(assoc opts
:height anim-height
:background-color (if connected?
colors/green
colors/gray)
:opacity anim-opacity
:modal? (= view-id :chat-modal)))
:accessibility-label :connection-status-text}
(when connecting?
[react/activity-indicator {:animated true
:color colors/white
:margin-right 6}])
[react/text {:style styles/text
:on-press on-press-fn}
message]]))})))
mailserver-connection-error? :t/mailserver-reconnect
mailserver-request-error? :t/mailserver-request-error-status
mailserver-fetching? :t/fetching-messages
:else nil)]
(let [pending? (and (:pending current-chat-contact) (= :chat view-id))]
[error-label
{:view-id view-id
:top top
:window-width window-width
:pending? pending?
:label label
:mailserver-fetching? mailserver-fetching?
:mailserver-request-error? mailserver-request-error?
:mailserver-connection-error? mailserver-connection-error?}])))))
(defview connectivity-view []
(letsubs [status-properties [:connectivity/status-properties]
view-id [:get :view-id]
window-width [:dimensions/window-width]]
(let [{:keys [loading-indicator?]} status-properties]
[react/view {:style {:align-self :flex-start}}
(when loading-indicator?
[loading-indicator window-width])
[connectivity-status
(merge status-properties
{:view-id view-id
:window-width window-width})]])))

View File

@ -21,7 +21,7 @@
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.http :as http]
[status-im.utils.js-resources :as js-res]
[status-im.ui.components.animation :as animation])
[status-im.ui.components.connectivity.view :as connectivity])
(:require-macros
[status-im.utils.slurp :refer [slurp]]
[status-im.utils.views :as views]))
@ -104,34 +104,6 @@
:accessibility-label :refresh-page-button}
[icons/icon :icons/refresh]]])
(views/defview loading-indicatior [parent-width]
(views/letsubs [anim-width (animation/create-value (* 0.15 parent-width))
anim-x (animation/create-value 0)
easing-in (fn [n] {:toValue (* n parent-width)
:easing (.in (animation/easing) (.-quad (animation/easing)))
:duration 400})
easing-out (fn [n] {:toValue (* n parent-width)
:easing (.out (animation/easing) (.-quad (animation/easing)))
:duration 400})]
{:component-did-mount (fn [_]
(animation/start
(animation/anim-loop
(animation/anim-sequence
[(animation/parallel
[(animation/timing anim-width (easing-in 0.6))
(animation/timing anim-x (easing-in 0.2))])
(animation/parallel
[(animation/timing anim-width (easing-out 0.15))
(animation/timing anim-x (easing-out 0.85))])
(animation/parallel
[(animation/timing anim-width (easing-in 0.6))
(animation/timing anim-x (easing-in 0.2))])
(animation/parallel
[(animation/timing anim-width (easing-out 0.15))
(animation/timing anim-x (easing-out 0))])]))))}
[react/view {:style {:width parent-width :height 3 :background-color colors/blue-light}}
[react/animated-view {:style {:margin-left anim-x :width anim-width :height 3 :background-color colors/blue}}]]))
;; should-component-update is called only when component's props are changed,
;; that's why it can't be used in `browser`, because `url` comes from subs
(views/defview browser-component
@ -195,7 +167,7 @@
[status-bar/status-bar]
[toolbar error? url url-original browser browser-id url-editing?]
(when (and loading? (not (nil? @width)))
[loading-indicatior @width])
[connectivity/loading-indicator @width])
[browser-component {:webview webview
:dapp? dapp?
:error? error?

View File

@ -66,7 +66,9 @@
:icon-opts {:color :black
:accessibility-label :chat-menu-button}
:handler #(on-options chat-id name group-chat public?)}]])]
(when-not (or public? group-chat) [add-contact-bar (first contacts)])]))
[connectivity/connectivity-view]
(when-not (or public? group-chat)
[add-contact-bar (first contacts)])]))
(defmulti message-row (fn [{{:keys [type]} :row}] type))
@ -198,8 +200,7 @@
(when show-bottom-info?
[bottom-info/bottom-info-view])
(when show-message-options?
[message-options/view])
[connectivity/error-view {:top (get platform/platform-specific :status-bar-default-height)}]]]))
[message-options/view])]]))
(defview chat []
[chat-root false])

View File

@ -249,7 +249,7 @@
[message (:text content) (= from current-public-key)
(assoc message-obj :group-chat group-chat
:current-public-key current-public-key)]))]]
[connectivity/error-view]])))
[connectivity/connectivity-view]])))
(views/defview send-button [inp-ref disconnected?]
(views/letsubs [{:keys [input-text]} [:chats/current-chat]]

View File

@ -105,12 +105,19 @@
[toolbar show-welcome? (and network-initialized? (not rpc-network?)) sync-state latest-block-number]
(cond show-welcome?
[welcome view-id]
loading?
[react/view {:style {:flex 1
:justify-content :center
:align-items :center}}
[connectivity/connectivity-view]
[components/activity-indicator {:flex 1
:animating true}]]
:else
[chats-list])
[react/view {:style {:flex 1}}
[connectivity/connectivity-view]
[chats-list]])
(when platform/android?
[home-action-button])
(when-not show-welcome?
[connectivity/error-view])]))
[home-action-button])]))
(views/defview home-wrapper []
(views/letsubs [loading? [:get :chats/loading?]]

View File

@ -5,6 +5,7 @@
status-im.contact.subs
status-im.search.subs
status-im.mailserver.subs
status-im.ui.components.connectivity.subs
status-im.ui.screens.accounts.subs
status-im.ui.screens.extensions.subs
status-im.ui.screens.home.subs

View File

@ -190,6 +190,7 @@
"create-new-account": "Create new account",
"are-you-sure?": "Are you sure?",
"disconnected": "Chat offline",
"connecting": "Connecting...",
"wallet-offline": "Wallet offline",
"sign-in-to-status": "Sign in to Status",
"leave-group-chat-confirmation": "Are you sure you want to leave this group?",