request 7 days of history

- fetch 7 days of history when joining a chat
- make 7 24h requests to request 7 days because mailservers
ignores requests for a timespan > 24h
- make requests sequentially to avoid timeouts
- change mailserver after 3 timeouts on a request

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2018-10-11 20:14:26 +02:00
parent 184dd03fa0
commit 660bd2d1bd
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
16 changed files with 225 additions and 188 deletions

View File

@ -181,6 +181,8 @@
browser/v8 browser/v8
dapp-permissions/v9]) dapp-permissions/v9])
(def v18 v17)
;; put schemas ordered by version ;; put schemas ordered by version
(def schemas [{:schema v1 (def schemas [{:schema v1
:schemaVersion 1 :schemaVersion 1
@ -232,4 +234,7 @@
:migration migrations/v16} :migration migrations/v16}
{:schema v17 {:schema v17
:schemaVersion 17 :schemaVersion 17
:migration migrations/v17}]) :migration migrations/v17}
{:schema v18
:schemaVersion 18
:migration migrations/v18}])

View File

@ -103,3 +103,12 @@
(defn v17 [old-realm new-realm] (defn v17 [old-realm new-realm]
(log/debug "migrating v17 account database")) (log/debug "migrating v17 account database"))
(defn v18
"reset last request to 1 to fetch 7 past days of history"
[old-realm new-realm]
(log/debug "migrating v18 account database")
(some-> old-realm
(.objects "transport-inbox-topic")
(.map (fn [inbox-topic _ _]
(aset inbox-topic "last-request" 1)))))

View File

@ -986,11 +986,6 @@
(log/error "Error on mark-trusted-peer: " error) (log/error "Error on mark-trusted-peer: " error)
(inbox/check-connection cofx))) (inbox/check-connection cofx)))
(handlers/register-handler-fx
:inbox.callback/request-messages-success
(fn [cofx [_ request]]
(inbox/add-request cofx request)))
;; transport module ;; transport module
(handlers/register-handler-fx (handlers/register-handler-fx

View File

@ -157,7 +157,7 @@
[{:keys [db] :as cofx} is-connected?] [{:keys [db] :as cofx} is-connected?]
(fx/merge cofx (fx/merge cofx
{:db (assoc db :network-status (if is-connected? :online :offline))} {:db (assoc db :network-status (if is-connected? :online :offline))}
(inbox/request-messages nil))) (inbox/network-connection-status-changed is-connected?)))
(defn- navigate-to-network-details (defn- navigate-to-network-details
[cofx network show-warning?] [cofx network show-warning?]

View File

@ -7,7 +7,8 @@
[{:keys [db]} chat-id] [{:keys [db]} chat-id]
{:db (update db :transport/chats dissoc chat-id) {:db (update db :transport/chats dissoc chat-id)
:data-store/tx [(transport-store/delete-transport-tx chat-id)] :data-store/tx [(transport-store/delete-transport-tx chat-id)]
:shh/remove-filter (get-in db [:transport/filters chat-id])}) :shh/remove-filter {:chat-id chat-id
:filter (get-in db [:transport/filters chat-id])}})
(fx/defn unsubscribe-from-chat (fx/defn unsubscribe-from-chat
"Unsubscribe from chat on transport layer" "Unsubscribe from chat on transport layer"

View File

@ -70,4 +70,4 @@
account A messages without this." account A messages without this."
[{:keys [db]}] [{:keys [db]}]
(let [{:transport/keys [filters]} db] (let [{:transport/keys [filters]} db]
{:shh/remove-filters (vals filters)})) {:shh/remove-filters filters}))

View File

@ -12,12 +12,9 @@
(spec/def ::pending-ack (spec/coll-of string? :kind vector?)) (spec/def ::pending-ack (spec/coll-of string? :kind vector?))
(spec/def ::pending-send (spec/coll-of string? :kind vector?)) (spec/def ::pending-send (spec/coll-of string? :kind vector?))
(spec/def ::resend? (spec/nilable #{"contact-request" "contact-request-confirmation" "contact-update"})) (spec/def ::resend? (spec/nilable #{"contact-request" "contact-request-confirmation" "contact-update"}))
(spec/def ::request-from pos-int?)
;; optional ;; optional
(spec/def ::topic (spec/nilable string?)) (spec/def ::topic (spec/nilable string?))
(spec/def ::request-id (spec/nilable string?))
(spec/def ::request-to (spec/nilable pos-int?))
(spec/def ::sym-key-id (spec/nilable string?)) (spec/def ::sym-key-id (spec/nilable string?))
;;TODO (yenda) remove once go implements persistence ;;TODO (yenda) remove once go implements persistence
(spec/def ::sym-key (spec/nilable string?)) (spec/def ::sym-key (spec/nilable string?))
@ -26,27 +23,32 @@
(spec/def :transport/filter any?) (spec/def :transport/filter any?)
(spec/def :request/from pos-int?) (spec/def :request/from pos-int?)
(spec/def :request/to pos-int?) (spec/def :request/to pos-int?)
(spec/def :request/attemps int?)
(spec/def :request/cursor :global/not-empty-string) (spec/def :request/cursor :global/not-empty-string)
(spec/def :transport.inbox/request (spec/keys :req-un [:request/from :request/to ::topic])) (spec/def :transport.inbox/request (spec/keys :req-un [:request/from :request/to ::topic]
(spec/def ::request-from pos-int?) :opt-un [:request/attemps]))
(spec/def :transport.inbox.topic/last-request ::request-from)
(spec/def :transport.inbox.topic/last-request pos-int?)
(spec/def :transport.inbox.topic/started-at pos-int?)
(spec/def :transport.inbox.topic/chat-id (spec/or :keyword keyword? (spec/def :transport.inbox.topic/chat-id (spec/or :keyword keyword?
:chat-id :global/not-empty-string)) :chat-id :global/not-empty-string))
(spec/def :transport.inbox.topic/chat-ids (spec/coll-of :transport.inbox.topic/chat-id (spec/def :transport.inbox.topic/chat-ids (spec/coll-of :transport.inbox.topic/chat-id
:kind set? :kind set?
:min-count 1)) :min-count 1))
(spec/def :transport.inbox.topic/request-pending? boolean?)
(spec/def :transport.inbox/topic (allowed-keys :req-un [:transport.inbox.topic/last-request (spec/def :transport.inbox/topic (allowed-keys :req-un [:transport.inbox.topic/last-request
:transport.inbox.topic/chat-ids] :transport.inbox.topic/chat-ids]
:opt-un [:transport.inbox.topic/request-pending?])) :opt-un [:transport.inbox.topic/started-at]))
(spec/def :transport/chat (allowed-keys :req-un [::ack ::seen ::pending-ack ::pending-send ::topic] (spec/def :transport/chat (allowed-keys :req-un [::ack ::seen ::pending-ack ::pending-send ::topic]
:opt-un [::sym-key-id ::sym-key ::resend?])) :opt-un [::sym-key-id ::sym-key ::resend?]))
(spec/def :transport.inbox/request-to :request/to)
(spec/def :transport/chats (spec/map-of :global/not-empty-string :transport/chat)) (spec/def :transport/chats (spec/map-of :global/not-empty-string :transport/chat))
(spec/def :transport/filters (spec/map-of :transport/filter-id :transport/filter)) (spec/def :transport/filters (spec/map-of :transport/filter-id :transport/filter))
(spec/def :transport.inbox/connection-checks pos-int?)
(spec/def :transport.inbox/topics (spec/map-of :global/not-empty-string :transport.inbox/topic)) (spec/def :transport.inbox/topics (spec/map-of :global/not-empty-string :transport.inbox/topic))
(spec/def :transport.inbox/requests (spec/map-of :global/not-empty-string :transport.inbox/request)) (spec/def :transport.inbox/current-request :transport.inbox/request)
(spec/def :transport.inbox/pending-requests integer?)
(defn create-chat (defn create-chat
"Initialize datastructure for chat representation at the transport level "Initialize datastructure for chat representation at the transport level
@ -124,3 +126,10 @@
(spec/keys :req-un [:message.text/content]))) (spec/keys :req-un [:message.text/content])))
(spec/def :message/message (spec/multi-spec content-type :content-type)) (spec/def :message/message (spec/multi-spec content-type :content-type))
(defn all-filters-added?
[{:keys [db]}]
(let [filters (set (keys (get db :transport/filters)))
chats (into #{:discovery-topic}
(keys (filter #(:topic (val %)) (get db :transport/chats))))]
(= chats filters)))

View File

@ -7,12 +7,12 @@
[status-im.utils.handlers :as handlers] [status-im.utils.handlers :as handlers]
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
(defn remove-filter! [filter] (defn remove-filter! [{:keys [chat-id filter]}]
(.stopWatching filter (.stopWatching filter
(fn [error _] (fn [error _]
(if error (if error
(log/warn :remove-filter-error filter error) (log/warn :remove-filter-error filter error)
(log/debug :removed-filter filter)))) (re-frame/dispatch [:shh.callback/filter-removed chat-id]))))
(log/debug :stop-watching filter)) (log/debug :stop-watching filter))
(defn add-filter! (defn add-filter!
@ -43,21 +43,36 @@
(re-frame/dispatch [:transport/messages-received js-error js-message]))] (re-frame/dispatch [:transport/messages-received js-error js-message]))]
(add-filter! web3 params callback :discovery-topic)))) (add-filter! web3 params callback :discovery-topic))))
(defn all-filters-added?
[{:keys [db]}]
(let [filters (set (keys (get db :transport/filters)))
chats (into #{:discovery-topic}
(keys (filter #(:topic (val %)) (get db :transport/chats))))]
(= chats filters)))
(handlers/register-handler-fx (handlers/register-handler-fx
:shh.callback/filter-added :shh.callback/filter-added
(fn [{:keys [db] :as cofx} [_ topic chat-id filter]] (fn [{:keys [db] :as cofx} [_ topic chat-id filter]]
(fx/merge cofx (fx/merge cofx
{:db (assoc-in db [:transport/filters chat-id] filter)} {:db (assoc-in db [:transport/filters chat-id] filter)}
(inbox/reset-request-to)
(inbox/upsert-inbox-topic {:topic topic (inbox/upsert-inbox-topic {:topic topic
:chat-id chat-id})))) :chat-id chat-id})
(inbox/process-next-messages-request))))
(handlers/register-handler-fx
:shh.callback/filter-removed
(fn [{:keys [db]} [_ chat-id]]
{:db (update db :transport/filters dissoc chat-id)}))
(re-frame/reg-fx (re-frame/reg-fx
:shh/remove-filter :shh/remove-filter
(fn [filter] (fn [{:keys [filter] :as params}]
(when filter (remove-filter! filter)))) (when filter (remove-filter! params))))
(re-frame/reg-fx (re-frame/reg-fx
:shh/remove-filters :shh/remove-filters
(fn [filters] (fn [filters]
(doseq [filter filters] (doseq [[chat-id filter] filters]
(when filter (remove-filter! filter))))) (when filter (remove-filter! {:chat-id chat-id
:filter filter})))))

View File

@ -1,7 +1,7 @@
(ns ^{:doc "Offline inboxing events and API"} (ns ^{:doc "Offline inboxing events and API"}
status-im.transport.inbox status-im.transport.inbox
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.constants :as constants] [status-im.accounts.db :as accounts.db]
[status-im.data-store.core :as data-store] [status-im.data-store.core :as data-store]
[status-im.data-store.transport :as transport-store] [status-im.data-store.transport :as transport-store]
[status-im.fleet.core :as fleet] [status-im.fleet.core :as fleet]
@ -10,7 +10,8 @@
[status-im.transport.utils :as transport.utils] [status-im.transport.utils :as transport.utils]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.utils.utils :as utils] [status-im.utils.utils :as utils]
[taoensso.timbre :as log])) [taoensso.timbre :as log]
[status-im.transport.db :as transport.db]))
;; How does offline inboxing work ? ;; How does offline inboxing work ?
;; ;;
@ -27,6 +28,7 @@
(def one-day (* 24 3600)) (def one-day (* 24 3600))
(def seven-days (* 7 one-day)) (def seven-days (* 7 one-day))
(def maximum-number-of-attemps 3)
(def connection-timeout (def connection-timeout
"Time after which mailserver connection is considered to have failed" "Time after which mailserver connection is considered to have failed"
@ -118,7 +120,9 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [address sym-key-id generating-sym-key?] :as wnode} (mailserver/fetch-current cofx)] (let [{:keys [address sym-key-id generating-sym-key?] :as wnode} (mailserver/fetch-current cofx)]
(fx/merge cofx (fx/merge cofx
{:db (update-mailserver-status db :connecting) {:db (-> db
(update-mailserver-status :connecting)
(update :transport.inbox/connection-checks inc))
:transport.inbox/add-peer address :transport.inbox/add-peer address
:utils/dispatch-later [{:ms connection-timeout :utils/dispatch-later [{:ms connection-timeout
:dispatch [:inbox/check-connection-timeout]}]} :dispatch [:inbox/check-connection-timeout]}]}
@ -137,9 +141,11 @@
{:keys [peers-summary]} db {:keys [peers-summary]} db
added? (registered-peer? peers-summary added? (registered-peer? peers-summary
address)] address)]
(fx/merge cofx
{:db (dissoc db :transport.inbox/current-request)}
(if added? (if added?
(mark-trusted-peer cofx) (mark-trusted-peer)
(add-peer cofx)))) (add-peer)))))
(fx/defn peers-summary-change (fx/defn peers-summary-change
"There is only 2 summary changes that require offline inboxing action: "There is only 2 summary changes that require offline inboxing action:
@ -172,34 +178,17 @@
(clj->js {:topic topic (clj->js {:topic topic
:mailServerPeer address :mailServerPeer address
:symKeyID sym-key-id :symKeyID sym-key-id
:timeout 20
:from from :from from
:to to}) :to to})
(fn [err request-id] (fn [error request-id]
(if-not err (if-not error
(re-frame/dispatch [:inbox.callback/request-messages-success {:topic topic (log/info "offline inbox: messages request success for topic " topic "from" from "to" to)
:request-id request-id (log/error "offline inbox: messages request error for topic " topic ": " error)))))
:from from
:to to}])
(log/error "offline inbox: messages request error for topic " topic ": " err)))))
(re-frame/reg-fx (re-frame/reg-fx
:transport.inbox/request-messages :transport.inbox/request-messages
(fn [{:keys [web3 wnode requests]}] (fn [{:keys [web3 wnode request]}]
(doseq [request requests] (request-messages! web3 wnode request)))
(request-messages! web3 wnode request))))
(defn prepare-request [now-in-s topic {:keys [last-request request-pending?]}]
(when-not request-pending?
{:from (max last-request
(- now-in-s one-day))
:to now-in-s
:topic topic}))
(defn prepare-requests [now-in-s topics]
(remove nil? (map (fn [[topic inbox-topic]]
(prepare-request now-in-s topic inbox-topic))
topics)))
(defn get-wnode-when-ready (defn get-wnode-when-ready
"return the wnode if the inbox is ready" "return the wnode if the inbox is ready"
@ -210,18 +199,50 @@
sym-key-id) sym-key-id)
wnode))) wnode)))
(fx/defn request-messages (defn split-request-per-day
"request messages if the inbox is ready" "NOTE: currently the mailserver is only accepting requests for a span
[{:keys [db now] :as cofx} topic] of 24 hours, so we split requests per 24h spans if the last request was
done more than 24h ago"
[now-in-s [topic {:keys [last-request]}]]
(let [days (conj
(into [] (range (max last-request
(- now-in-s seven-days))
now-in-s
one-day))
now-in-s)
day-ranges (map vector days (rest days))]
(for [[from to] day-ranges]
{:topic topic
:from from
:to to})))
(defn prepare-messages-requests
[{:keys [db now] :as cofx} request-to]
(let [web3 (:web3 db)]
(remove nil?
(mapcat (partial split-request-per-day request-to)
(:transport.inbox/topics db)))))
(fx/defn process-next-messages-request
[{:keys [db now] :as cofx}]
(when (and (transport.db/all-filters-added? cofx)
(not (:transport.inbox/current-request db)))
(when-let [wnode (get-wnode-when-ready cofx)] (when-let [wnode (get-wnode-when-ready cofx)]
(let [web3 (:web3 db) (let [request-to (or (:transport.inbox/request-to db)
now-in-s (quot now 1000) (quot now 1000))
requests (if topic requests (prepare-messages-requests cofx request-to)
[(prepare-request now-in-s topic (get-in db [:transport.inbox/topics topic]))] web3 (:web3 db)]
(prepare-requests now-in-s (:transport.inbox/topics db)))] (if-let [request (first requests)]
{:transport.inbox/request-messages {:web3 web3 {:db (assoc db
:transport.inbox/pending-requests (count requests)
:transport.inbox/current-request request
:transport.inbox/request-to request-to)
:transport.inbox/request-messages {:web3 web3
:wnode wnode :wnode wnode
:requests requests}}))) :request request}}
{:db (dissoc db
:transport.inbox/pending-requests
:transport.inbox/request-to)})))))
(fx/defn add-mailserver-trusted (fx/defn add-mailserver-trusted
"the current mailserver has been trusted "the current mailserver has been trusted
@ -230,7 +251,7 @@
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(fx/merge cofx (fx/merge cofx
{:db (update-mailserver-status db :connected)} {:db (update-mailserver-status db :connected)}
(request-messages nil))) (process-next-messages-request)))
(fx/defn add-mailserver-sym-key (fx/defn add-mailserver-sym-key
"the current mailserver sym-key has been generated "the current mailserver sym-key has been generated
@ -242,22 +263,50 @@
{:db (-> db {:db (-> db
(assoc-in [:inbox/wnodes current-fleet id :sym-key-id] sym-key-id) (assoc-in [:inbox/wnodes current-fleet id :sym-key-id] sym-key-id)
(update-in [:inbox/wnodes current-fleet id] dissoc :generating-sym-key?))} (update-in [:inbox/wnodes current-fleet id] dissoc :generating-sym-key?))}
(request-messages nil)))) (process-next-messages-request))))
(fx/defn check-connection (fx/defn change-mailserver
"check if mailserver is connected "mark mailserver status as `:error` if custom mailserver is used
mark mailserver status as `:error` if custom mailserver is used
otherwise try to reconnect to another mailserver" otherwise try to reconnect to another mailserver"
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(when (= :connecting (:mailserver-status db))
(if (mailserver/preferred-mailserver-id cofx) (if (mailserver/preferred-mailserver-id cofx)
{:db (update-mailserver-status db :error)} {:db (update-mailserver-status db :error)}
(fx/merge cofx (fx/merge cofx
(mailserver/set-current-mailserver) (mailserver/set-current-mailserver)
(connect-to-mailserver))))) (connect-to-mailserver))))
(fx/defn check-connection
"connection-checks counter is used to prevent changing
mailserver on flaky connections
if there is more than one connection check pending
decrement the connection check counter
else
change mailserver if mailserver is connected"
[{:keys [db] :as cofx}]
(if (zero? (dec (:transport.inbox/connection-checks db)))
(fx/merge cofx
{:db (dissoc db :transport.inbox/connection-checks)}
(when (= :connecting (:mailserver-status db))
(change-mailserver cofx)))
{:db (update db :transport.inbox/connection-checks dec)}))
(fx/defn reset-request-to
[{:keys [db]}]
{:db (dissoc db :transport.inbox/request-to)})
(fx/defn network-connection-status-changed
"when host reconnects, reset request-to and
reconnect to mailserver"
[{:keys [db] :as cofx} is-connected?]
(when (and (accounts.db/logged-in? cofx)
is-connected?)
(fx/merge cofx
(reset-request-to)
(connect-to-mailserver))))
(fx/defn remove-chat-from-inbox-topic (fx/defn remove-chat-from-inbox-topic
"if the chat is the only chat of the inbox topic delete the inbox topic "if the chat is the only chat of the inbox topic delete the inbox topic
and process-next-messages-requests again to remove pending request for that topic
otherwise remove the chat-id of the chat from the inbox topic and save" otherwise remove the chat-id of the chat from the inbox topic and save"
[{:keys [db now] :as cofx} chat-id] [{:keys [db now] :as cofx} chat-id]
(let [topic (get-in db [:transport/chats chat-id :topic]) (let [topic (get-in db [:transport/chats chat-id :topic])
@ -265,8 +314,10 @@
:chat-ids :chat-ids
disj chat-id)] disj chat-id)]
(if (empty? chat-ids) (if (empty? chat-ids)
(fx/merge cofx
{:db (update db :transport.inbox/topics dissoc topic) {:db (update db :transport.inbox/topics dissoc topic)
:data-store/tx [(transport-store/delete-transport-inbox-topic-tx topic)]} :data-store/tx [(transport-store/delete-transport-inbox-topic-tx topic)]}
(process-next-messages-request))
{:db (assoc-in db [:transport.inbox/topics topic] inbox-topic) {:db (assoc-in db [:transport.inbox/topics topic] inbox-topic)
:data-store/tx [(transport-store/save-transport-inbox-topic-tx :data-store/tx [(transport-store/save-transport-inbox-topic-tx
{:topic topic {:topic topic
@ -274,26 +325,36 @@
(fx/defn update-inbox-topic (fx/defn update-inbox-topic
"TODO: add support for cursors "TODO: add support for cursors
if there is a cursor, do not update `request-to` and `request-from`" if there is a cursor, do not update `last-request`"
[{:keys [db now] :as cofx} {:keys [request-id cursor]}] [{:keys [db now] :as cofx} {:keys [request-id cursor]}]
(let [{:keys [from to topic]} (get-in db [:transport.inbox/requests request-id]) (when-let [request (get db :transport.inbox/current-request)]
inbox-topic (-> (get-in db [:transport.inbox/topics topic]) (let [{:keys [from to topic]} request
(assoc :last-request to) inbox-topic (some-> (get-in db [:transport.inbox/topics topic])
(dissoc :request-pending?))] (assoc :last-request to))]
(log/info "offline inbox: message request " request-id
"completed for inbox topic" topic "from" from "to" to)
(if inbox-topic
(fx/merge cofx (fx/merge cofx
(if inbox-topic
{:db (-> db {:db (-> db
(update :transport.inbox/requests dissoc request-id) (dissoc :transport.inbox/current-request)
(assoc-in [:transport.inbox/topics topic] inbox-topic)) (assoc-in [:transport.inbox/topics topic] inbox-topic))
:data-store/tx [(transport-store/save-transport-inbox-topic-tx :data-store/tx [(transport-store/save-transport-inbox-topic-tx
{:topic topic {:topic topic
:inbox-topic inbox-topic})]}))) :inbox-topic inbox-topic})]})
(process-next-messages-request))
;; when the topic was deleted (filter was removed while request was pending)
(fx/merge cofx
{:db (dissoc db :transport.inbox/current-request)}
(process-next-messages-request))))))
(fx/defn upsert-inbox-topic (fx/defn upsert-inbox-topic
"if the chat-id is already in the topic we do nothing, otherwise we update "if the topic didn't exist
the topic create the topic
if the topic already existed we add the chat-id andreset last-request else if chat-id is not in the topic
because there was no filter for the chat and messages were ignored add the chat-id to the topic and reset last-request
if the topic didn't exist we created" there was no filter for the chat and messages for that
so the whole history for that topic needs to be re-fetched"
[{:keys [db] :as cofx} {:keys [topic chat-id]}] [{:keys [db] :as cofx} {:keys [topic chat-id]}]
(let [{:keys [chat-ids last-request] :as current-inbox-topic} (let [{:keys [chat-ids last-request] :as current-inbox-topic}
(get-in db [:transport.inbox/topics topic] {:chat-ids #{}})] (get-in db [:transport.inbox/topics topic] {:chat-ids #{}})]
@ -305,34 +366,26 @@
{:db (assoc-in db [:transport.inbox/topics topic] inbox-topic) {:db (assoc-in db [:transport.inbox/topics topic] inbox-topic)
:data-store/tx [(transport-store/save-transport-inbox-topic-tx :data-store/tx [(transport-store/save-transport-inbox-topic-tx
{:topic topic {:topic topic
:inbox-topic inbox-topic})]} :inbox-topic inbox-topic})]}))))
(request-messages topic)))))
(fx/defn resend-request (fx/defn resend-request
[{:keys [db] :as cofx} {:keys [request-id]}] [{:keys [db] :as cofx} {:keys [request-id]}]
(let [{:keys [from to topic]} (get-in db [:transport.inbox/requests request-id])] (if (>= maximum-number-of-attemps
(log/info "offline inbox: message request" request-id " expired for inbox topic" topic "from" from "to" to) (get-in [:transport.inbox/current-request :attemps] db))
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (update db :transport.inbox/current-request dissoc :attemps)}
(update :transport.inbox/requests dissoc request-id) (change-mailserver))
(update-in [:transport.inbox/topics topic] dissoc :request-pending?))} (when-let [wnode (get-wnode-when-ready cofx)]
(request-messages topic)))) (let [{:keys [topic from to] :as request} (get db :transport.inbox/current-request)
web3 (:web3 db)]
(fx/defn add-request (log/info "offline inbox: message request " request-id "expired for inbox topic" topic "from" from "to" to)
[{:keys [db] :as cofx} {:keys [topic request-id from to]}] {:db (update-in db [:transport.inbox/current-request :attemps] inc)
(log/info "offline inbox: message request " request-id "sent for inbox topic" topic "from" from "to" to) :transport.inbox/request-messages {:web3 web3
{:db (-> db :wnode wnode
(assoc-in [:transport.inbox/requests request-id] {:from from :request request}}))))
:to to
:topic topic})
(assoc-in [:transport.inbox/topics topic :request-pending?] true))})
(fx/defn initialize-offline-inbox (fx/defn initialize-offline-inbox
[cofx custom-mailservers] [cofx custom-mailservers]
(let [discovery-topic (transport.utils/get-topic constants/contact-discovery)]
(fx/merge cofx (fx/merge cofx
(mailserver/add-custom-mailservers custom-mailservers) (mailserver/add-custom-mailservers custom-mailservers)
(mailserver/set-current-mailserver) (mailserver/set-current-mailserver)))
(when-not (get-in cofx [:db :transport.inbox/topics discovery-topic])
(upsert-inbox-topic {:topic discovery-topic
:chat-id :discovery-topic})))))

View File

@ -80,7 +80,8 @@
"Stops the filter for the given chat-id" "Stops the filter for the given chat-id"
[{:keys [db]} chat-id] [{:keys [db]} chat-id]
(when-let [filter (get-in db [:transport/filters chat-id])] (when-let [filter (get-in db [:transport/filters chat-id])]
{:shh/remove-filter filter})) {:shh/remove-filter {:chat-id chat-id
:filter filter}}))
(defrecord NewContactKey [sym-key topic message] (defrecord NewContactKey [sym-key topic message]
protocol/StatusMessage protocol/StatusMessage

View File

@ -7,7 +7,7 @@
[status-im.i18n :as i18n])) [status-im.i18n :as i18n]))
(defview error-label (defview error-label
[{:keys [view-id label mailserver-error?] :as opts}] [{:keys [view-id label fetching? mailserver-error?] :as opts}]
{:should-component-update {:should-component-update
(fn [_ [_ old-props] [_ new-props]] (fn [_ [_ old-props] [_ new-props]]
@ -20,7 +20,9 @@
[react/text {:style styles/text [react/text {:style styles/text
:on-press (when mailserver-error? :on-press (when mailserver-error?
#(re-frame/dispatch [:inbox.ui/reconnect-mailserver-pressed]))} #(re-frame/dispatch [:inbox.ui/reconnect-mailserver-pressed]))}
(i18n/label label)]])) (if fetching?
(i18n/label :t/fetching-messages {:requests-left (str fetching?)})
(i18n/label label))]]))
(defview error-view [{:keys [top]}] (defview error-view [{:keys [top]}]
(letsubs [offline? [:offline?] (letsubs [offline? [:offline?]
@ -43,4 +45,5 @@
:window-width window-width :window-width window-width
:pending? pending? :pending? pending?
:label label :label label
:fetching? fetching?
:mailserver-error? mailserver-error?}])))) :mailserver-error? mailserver-error?}]))))

View File

@ -52,7 +52,7 @@
:transport/filters {} :transport/filters {}
:transport/message-envelopes {} :transport/message-envelopes {}
:transport.inbox/topics {} :transport.inbox/topics {}
:transport.inbox/requests {} :transport.inbox/pending-requests 0
:chat/cooldowns 0 :chat/cooldowns 0
:chat/cooldown-enabled? false :chat/cooldown-enabled? false
:chat/last-outgoing-message-sent-at 0 :chat/last-outgoing-message-sent-at 0
@ -155,7 +155,6 @@
(spec/def ::chain (spec/nilable string?)) (spec/def ::chain (spec/nilable string?))
(spec/def ::peers-count (spec/nilable integer?)) (spec/def ::peers-count (spec/nilable integer?))
(spec/def ::peers-summary (spec/nilable vector?)) (spec/def ::peers-summary (spec/nilable vector?))
(spec/def :inbox/fetching? (spec/nilable boolean?))
(spec/def :inbox/current-id (spec/nilable keyword?)) (spec/def :inbox/current-id (spec/nilable keyword?))
(spec/def ::collectible (spec/nilable map?)) (spec/def ::collectible (spec/nilable map?))
@ -220,7 +219,6 @@
:bootnodes/manage :bootnodes/manage
:inbox/wnodes :inbox/wnodes
:inbox/current-id :inbox/current-id
:inbox/fetching?
:node/status :node/status
:node/restart? :node/restart?
:node/address :node/address
@ -238,7 +236,10 @@
:transport/chats :transport/chats
:transport/filters :transport/filters
:transport.inbox/topics :transport.inbox/topics
:transport.inbox/requests :transport.inbox/pending-requests
:transport.inbox/current-request
:transport.inbox/connection-checks
:transport.inbox/request-to
:desktop/desktop :desktop/desktop
:dimensions/window :dimensions/window
:dapps/permissions] :dapps/permissions]

View File

@ -107,7 +107,7 @@
(fx/defn on-return-from-background [cofx] (fx/defn on-return-from-background [cofx]
(fx/merge cofx (fx/merge cofx
(inbox/request-messages nil) (inbox/process-next-messages-request)
(hardwallet/return-back-from-nfc-settings))) (hardwallet/return-back-from-nfc-settings)))
(defn app-state-change [state {:keys [db] :as cofx}] (defn app-state-change [state {:keys [db] :as cofx}]

View File

@ -48,7 +48,10 @@
(reg-sub :fetching? (reg-sub :fetching?
(fn [db] (fn [db]
(pos-int? (count (get db :transport.inbox/requests))))) (let [pending-requests (get db :transport.inbox/pending-requests)]
(when (and (pos-int? pending-requests)
(:transport.inbox/current-request db))
pending-requests))))
(reg-sub :offline? (reg-sub :offline?
:<- [:network-status] :<- [:network-status]

View File

@ -66,61 +66,3 @@
(is (not (-> (inbox/connect-to-mailserver {:db wnode-with-sym-key-db}) (is (not (-> (inbox/connect-to-mailserver {:db wnode-with-sym-key-db})
:shh/generate-sym-key-from-password :shh/generate-sym-key-from-password
first))))))) first)))))))
#_(deftest request-messages
(let [db {:mailserver-status :connected
:inbox/current-id "wnodeid"
:inbox/wnodes {:eth.beta {"wnodeid" {:address "wnode-address"
:sym-key-id "something"
:password "wnode-password"}}}
:account/account {:settings {:fleet :eth.beta}}
:transport/chats
{:dont-fetch-history {:topic "dont-fetch-history"}
:fetch-history {:topic "fetch-history"}}}
cofx {:db db :now 1000000000}]
(testing "inbox is ready"
(testing "last request is > the 7 days ago"
(let [cofx-with-last-request (assoc-in cofx [:db :account/account :last-request] 400000)
actual (inbox/request-messages cofx-with-last-request nil)]
(testing "it uses last request"
(is (= 400000 (get-in actual [:transport.inbox/request-messages :requests]))))))
(testing "last request is < the 7 days ago"
(let [cofx-with-last-request (assoc-in cofx [:db :account/account :last-request] 2)
actual (inbox/request-messages cofx-with-last-request nil)]
(testing "it uses last 7 days for catching up"
(is (= 395200 (get-in actual [:transport.inbox/request-messages :requests]))))
(testing "it only uses topics that dont have fetch history set"
(is (= ["0xf8946aac" "dont-fetch-history"]
(get-in actual [:transport.inbox/request-messages :requests]))))
(testing "it uses the last 24 hours to request history"
(is (= 913600
(get-in actual [:transport.inbox/request-messages :requests]))))
(testing "it fetches the right topic for history"
(is (= ["fetch-history"]
(get-in actual [:transport.inbox/request-messages :requests])))))))
(testing "inbox is not ready"
(testing "it does not do anything"
(is (nil? (inbox/request-messages {:db {}} nil)))))))
#_(deftest initialize-offline-inbox
(let [db {:mailserver-status :connected
:account/account {:settings {:fleet :eth.beta}}
:inbox/current-id "wnodeid"
:inbox/wnodes {:eth.beta {"wnodeid" {:address "wnode-address"
:sym-key-id "something"
:password "wnode-password"}}}}]
(testing "last-request is not set"
(testing "it sets it to now in seconds"
(is (= 10
(get-in
(inbox/initialize-offline-inbox {:now 10000 :db db} [])
[:db :account/account :last-request])))))
(testing "last-request is set"
(testing "leaves it unchanged"
(is (= "sometimeago"
(get-in
(inbox/initialize-offline-inbox
{:now "now"
:db (assoc-in db [:account/account :last-request] "sometimeago")}
[])
[:db :account/account :last-request])))))))

View File

@ -573,7 +573,7 @@
"public-chat-user-count": "{{count}} people", "public-chat-user-count": "{{count}} people",
"eth": "ETH", "eth": "ETH",
"transactions-history": "Transaction history", "transactions-history": "Transaction history",
"fetching-messages": "Fetching messages...", "fetching-messages": "Fetching messages... ({{requests-left}} requests left)",
"not-implemented": "!not implemented", "not-implemented": "!not implemented",
"password_error1": "Passwords don't match.", "password_error1": "Passwords don't match.",
"your-contact-code": "Granting access authorizes this DApp to retrieve your contact code", "your-contact-code": "Granting access authorizes this DApp to retrieve your contact code",