Wallet status badge for offline RPC handling (#21484)

This commit is contained in:
Alexander 2024-11-19 12:38:06 +01:00 committed by GitHub
parent 7acaff6167
commit 65c872c6ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 203 additions and 19 deletions

View File

@ -94,13 +94,16 @@
notification-count
activity-center-on-press
scan-on-press
qr-code-on-press]
qr-code-on-press
right-section-content]
:as props}]
(let [theme (quo.theme/use-theme)
button-common-props (get-button-common-props {:theme theme
:jump-to? jump-to?
:blur? blur?})]
[rn/view {:style style/right-section}
(when right-section-content
right-section-content)
[button/button
(assoc button-common-props :accessibility-label :open-scanner-button :on-press scan-on-press)
:i/scan]
@ -137,6 +140,7 @@
:qr-code-on-press callback
:notification-count number
:max-unread-notifications used to specify max number for counter
:right-section-content
"
[{:keys [avatar-on-press avatar-props customization-color container-style] :as props}]
[rn/view {:style (merge style/top-nav-container container-style)}

View File

@ -0,0 +1,14 @@
(ns quo.components.tags.network-status-tag.component-spec
(:require
[quo.components.tags.network-status-tag.view :as network-status-tag]
[test-helpers.component :as h]))
(h/describe "Network status component test"
(h/test "5 min ago render"
(h/render [network-status-tag/view
{:label "Updated 5 min ago"}])
(h/is-truthy (h/get-by-text "Updated 5 min ago")))
(h/test "15 min ago render"
(h/render [network-status-tag/view
{:label "Updated 15 min ago"}])
(h/is-truthy (h/get-by-text "Updated 15 min ago"))))

View File

@ -0,0 +1,28 @@
(ns quo.components.tags.network-status-tag.style
(:require
[quo.foundations.colors :as colors]))
(def main
{:justify-content :center
:align-items :center
:height 24})
(defn inner
[theme]
{:border-width 1
:border-radius 12
:flex 1
:flex-direction :row
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:align-items :center
:padding-horizontal 8})
(def label
{:color colors/warning-50
:margin-left 6})
(def dot
{:width 8
:height 8
:border-radius 8
:background-color colors/warning-50})

View File

@ -0,0 +1,19 @@
(ns quo.components.tags.network-status-tag.view
(:require
[quo.components.markdown.text :as text]
[quo.components.tags.network-status-tag.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn view
[{:keys [label]}]
(let [theme (quo.theme/use-theme)]
[rn/view {:style style/main}
[rn/view {:style (style/inner theme)}
[rn/view {:style style/dot}]
[text/text
{:style style/label
:weight :medium
:size :label
:align :center}
label]]]))

View File

@ -155,6 +155,7 @@
quo.components.tabs.tabs.view
quo.components.tags.collectible-tag.view
quo.components.tags.context-tag.view
quo.components.tags.network-status-tag.view
quo.components.tags.network-tags.view
quo.components.tags.number-tag.view
quo.components.tags.permission-tag
@ -438,6 +439,7 @@
(def context-tag quo.components.tags.context-tag.view/view)
(def network-tags quo.components.tags.network-tags.view/view)
(def number-tag quo.components.tags.number-tag.view/view)
(def network-status-tag quo.components.tags.network-status-tag.view/view)
(def permission-tag quo.components.tags.permission-tag/tag)
(def status-tag quo.components.tags.status-tags/status-tag)
(def summary-tag quo.components.tags.summary-tag.view/view)

View File

@ -1,11 +1,26 @@
(ns status-im.common.home.top-nav.view
(:require
[cljs-time.core :as t]
[quo.core :as quo]
[react-native.core :as rn]
[status-im.common.home.top-nav.style :as style]
[status-im.constants :as constants]
[status-im.contexts.profile.utils :as profile.utils]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- network-status-label
[now wallet-latest-update]
(when (t/after? now (t/plus wallet-latest-update (t/minutes 5)))
(let [units [{:name :t/datetime-second-short :limit 60 :in-second 1}
{:name :t/datetime-minute-mid :limit 3600 :in-second 60}
{:name :t/datetime-hour-short-lowercase :limit 86400 :in-second 3600}
{:name :t/datetime-day :limit nil :in-second 86400}]
time-ago (datetime/time-ago-long wallet-latest-update units)]
[rn/view {:style {:justify-content :center}}
[quo/network-status-tag {:label (i18n/label :t/wallet-updated-at {:at time-ago})}]])))
(defn view
"[top-nav props]
props
@ -17,6 +32,8 @@
online? (rf/sub [:visibility-status-updates/online?
public-key])
customization-color (rf/sub [:profile/customization-color])
wallet-latest-update (rf/sub [:wallet/latest-update])
wallet-blockchain-status (rf/sub [:wallet/blockchain-status])
avatar {:online? online?
:full-name (profile.utils/displayed-name profile)
:profile-picture (profile.utils/photo profile)}
@ -37,6 +54,9 @@
{:avatar-on-press #(rf/dispatch [:open-modal :settings])
:scan-on-press #(rf/dispatch [:open-modal :shell-qr-reader])
:activity-center-on-press #(rf/dispatch [:activity-center/open])
:right-section-content (when (and (= (:status wallet-blockchain-status) "down")
wallet-latest-update)
[network-status-label (t/now) wallet-latest-update])
:qr-code-on-press #(rf/dispatch [:open-modal :screen/share-shell
{:initial-tab initial-share-tab}])
:container-style (merge style/top-nav-container container-style)

View File

@ -180,6 +180,7 @@
[status-im.contexts.preview.quo.tabs.tabs :as tabs]
[status-im.contexts.preview.quo.tags.collectible-tag :as collectible-tag]
[status-im.contexts.preview.quo.tags.context-tags :as context-tags]
[status-im.contexts.preview.quo.tags.network-status-tag :as network-status-tag]
[status-im.contexts.preview.quo.tags.network-tags :as network-tags]
[status-im.contexts.preview.quo.tags.number-tag :as number-tag]
[status-im.contexts.preview.quo.tags.permission-tag :as permission-tag]
@ -520,6 +521,8 @@
:component collectible-tag/view}
{:name :context-tags
:component context-tags/view}
{:name :network-status-tag
:component network-status-tag/view}
{:name :network-tags
:component network-tags/view}
{:name :number-tag

View File

@ -0,0 +1,19 @@
(ns status-im.contexts.preview.quo.tags.network-status-tag
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :label :type :text}])
(defn view
[]
(let [state (reagent/atom {:label "Updated 5 min ago"})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view {:style {:align-items :center}}
[quo/network-status-tag @state]]])))

View File

@ -1,6 +1,7 @@
(ns status-im.contexts.wallet.events
(:require
[camel-snake-kebab.extras :as cske]
[cljs-time.coerce :as time-coerce]
[clojure.set]
[clojure.string :as string]
[react-native.platform :as platform]
@ -224,7 +225,8 @@
{:error error
:event :wallet/get-wallet-token-for-account
:params address})
{:db (assoc-in db [:wallet :ui :tokens-loading address] false)}))
{:fx [[:dispatch [:wallet/get-last-wallet-token-update-if-needed]]]
:db (assoc-in db [:wallet :ui :tokens-loading address] false)}))
(rf/reg-event-fx
:wallet/store-wallet-token
@ -240,10 +242,34 @@
accounts))
stored-accounts
tokens-per-account))]
{:db (-> db
{:fx [[:dispatch [:wallet/get-last-wallet-token-update-if-needed]]]
:db (-> db
(update-in [:wallet :accounts] add-tokens tokens)
(assoc-in [:wallet :ui :tokens-loading address] false))})))
(rf/reg-event-fx
:wallet/get-last-wallet-token-update-if-needed
(fn [{:keys [db]}]
(let [all-tokens-loaded? (->> (get-in db [:wallet :ui :tokens-loading])
vals
(every? false?))]
(when all-tokens-loaded?
{:fx [[:json-rpc/call
[{:method "wallet_getLastWalletTokenUpdate"
:params []
:on-success [:wallet/get-last-wallet-token-update-success]
:on-error [:wallet/log-rpc-error
{:event :wallet/get-last-wallet-token-update-if-needed}]}]]]}))))
(rf/reg-event-fx
:wallet/get-last-wallet-token-update-success
(fn [{:keys [db]} [data]]
(let [last-updates (reduce (fn [acc [k v]]
(assoc acc k (time-coerce/from-long (* 1000 v))))
{}
data)]
{:db (assoc-in db [:wallet :ui :last-updates-per-address] last-updates)})))
(rf/defn scan-address-success
{:events [:wallet/scan-address-success]}
[{:keys [db]} address]
@ -653,3 +679,10 @@
new-account-addresses)))))
(rf/reg-event-fx :wallet/reconcile-keypairs reconcile-keypairs)
(rf/reg-event-fx
:wallet/blockchain-health-changed
(fn [{:keys [db]} [{:keys [message]}]]
(let [full-status (cske/transform-keys message transforms/->kebab-case-keyword)]
{:db (assoc-in db [:wallet :blockchain] full-status)})))

View File

@ -93,6 +93,9 @@
:dispatch [:wallet/blockchain-status-changed
(transforms/js->clj event-js)]}]]]}
"wallet-blockchain-health-changed"
{:fx [[:dispatch [:wallet/blockchain-health-changed (transforms/js->clj event-js)]]]}
"wallet-activity-filtering-done"
{:fx
[[:dispatch

View File

@ -1,5 +1,6 @@
(ns status-im.subs.wallet.wallet
(:require [clojure.string :as string]
(:require [cljs-time.core :as t]
[clojure.string :as string]
[re-frame.core :as rf]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.utils :as utils]
@ -39,6 +40,33 @@
:<- [:wallet/ui]
:-> :scanned-address)
(rf/reg-sub
:wallet/last-updates-per-address
:<- [:wallet/ui]
:-> :last-updates-per-address)
(rf/reg-sub
:wallet/latest-update
:<- [:wallet/last-updates-per-address]
(fn [last-updates-per-address]
(->> last-updates-per-address
vals
(reduce (fn [earliest-time last-update-time]
(if (or (nil? earliest-time)
(t/before? last-update-time earliest-time))
last-update-time
earliest-time))))))
(rf/reg-sub
:wallet/blockchain
:<- [:wallet]
:-> :blockchain)
(rf/reg-sub
:wallet/blockchain-status
:<- [:wallet/blockchain]
:-> :status)
(rf/reg-sub
:wallet/tokens
:<- [:wallet]

View File

@ -46,7 +46,7 @@
(def day (* 24 hour))
(def week (* 7 day))
(defn weeks [w] (* w week))
(def units
(def default-units
[{:name :t/datetime-second-short :limit 60 :in-second 1}
{:name :t/datetime-minute-short :limit 3600 :in-second 60}
{:name :t/datetime-hour-short :limit 86400 :in-second 3600}
@ -272,27 +272,29 @@
(let [diff (seconds-ago date-time)
unit (first (drop-while #(and (>= diff (:limit %))
(:limit %))
units))]
default-units))]
(-> (/ diff (:in-second unit))
Math/floor
int
(format-time-ago unit))))
(defn time-ago-long
[date-time]
(let [time-ago-seconds (seconds-ago date-time)
unit (first (drop-while #(and (>= time-ago-seconds (:limit %))
(:limit %))
units))
diff (-> (/ time-ago-seconds (:in-second unit))
Math/floor
int)
([date-time units]
(let [time-ago-seconds (seconds-ago date-time)
unit (first (drop-while #(and (>= time-ago-seconds (:limit %))
(:limit %))
units))
diff (-> (/ time-ago-seconds (:in-second unit))
Math/floor
int)
name (i18n/label-pluralize diff (:name unit))]
(i18n/label :t/datetime-ago-format
{:ago (i18n/label :t/datetime-ago)
:number diff
:time-intervals name})))
name (i18n/label-pluralize diff (:name unit))]
(i18n/label :t/datetime-ago-format
{:ago (i18n/label :t/datetime-ago)
:number diff
:time-intervals name})))
([date-time]
(time-ago-long date-time default-units)))
(defn to-date
[ms]

View File

@ -690,10 +690,18 @@
"one": "H",
"other": "H"
},
"datetime-hour-short-lowercase": {
"one": "h",
"other": "h"
},
"datetime-minute": {
"one": "minute",
"other": "minutes"
},
"datetime-minute-mid": {
"one": "min",
"other": "min"
},
"datetime-minute-short": {
"one": "M",
"other": "M"
@ -2804,6 +2812,7 @@
"wallet-settings": "Wallet settings",
"wallet-total-value": "Total value",
"wallet-transaction-total-fee": "Total Fee",
"wallet-updated-at": "Updated {{at}}",
"wants-to-access-profile": "wants to access to your profile",
"wants-to-join": "wants to join",
"warning": "Warning",