mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-26 07:15:53 +00:00
[fixes #4745] Don't query mailserver on restored account
When creating a new account / recovery we don't poll the mailserver anymore for historic messages, which solves the immediate issue of fetching only received messages Handle messages sent from a different device in public chat / restore history. The message will be added, shown correctly as sent by the user, and the status will be set as sent ( need to check for seen race condition, as messages will now be added twice). This means that multidevice should now work for public chats. Move contact updates to discovery topic. This is necessary as there is a pre-existing bug whereby contact updates would not work anymore after wallet recovery, as the code relies on the initial contact request being stored on the mailserver, which we cannot guarantee (we only pull 7 days of data). Not pulling history anymore exacerbate the problems but does not introduce it. To make sure that contact updates will work after wallet recovery, we also need to consider a ContactUpdate in the same way we consider a ContactRequest (the other peer has no idea that the user has recovered the wallet). This does not change any behaviour in terms of obscurity/security as ContactRequest are automatically processed (in both case the contact will be set as pending?, not as accepted) At this stage ContactRequest, ContactRequestConfirmed, ContactUpdate have all the same logic, i.e. update the contact information, leave the pending flag alone. Only 1 day of history is fetched for newly joined chats, if catching up 7 days is the cap as before. Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
13c8cbf253
commit
b34744133b
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
(defn console-message [{:keys [timestamp message-id content content-type]}]
|
(defn console-message [{:keys [timestamp message-id content content-type]}]
|
||||||
{:message-id message-id
|
{:message-id message-id
|
||||||
:outgoing false
|
|
||||||
:chat-id constants/console-chat-id
|
:chat-id constants/console-chat-id
|
||||||
:from constants/console-chat-id
|
:from constants/console-chat-id
|
||||||
:to "me"
|
:to "me"
|
||||||
|
@ -101,7 +101,6 @@
|
|||||||
:timestamp now
|
:timestamp now
|
||||||
:content (str content)
|
:content (str content)
|
||||||
:content-type constants/text-content-type
|
:content-type constants/text-content-type
|
||||||
:outgoing false
|
|
||||||
:clock-value (utils.clocks/send 0)
|
:clock-value (utils.clocks/send 0)
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:from chat-id
|
:from chat-id
|
||||||
|
@ -101,9 +101,14 @@
|
|||||||
status)
|
status)
|
||||||
:data-store/tx [(user-statuses-store/save-status-tx status)]}))
|
:data-store/tx [(user-statuses-store/save-status-tx status)]}))
|
||||||
|
|
||||||
|
(defn add-outgoing-status [{:keys [from] :as message} {:keys [db]}]
|
||||||
|
(assoc message :outgoing (= from (:current-public-key db))))
|
||||||
|
|
||||||
(defn- add-message
|
(defn- add-message
|
||||||
[batch? {:keys [chat-id message-id clock-value content] :as message} current-chat? {:keys [db] :as cofx}]
|
[batch? {:keys [chat-id message-id clock-value content] :as message} current-chat? {:keys [db] :as cofx}]
|
||||||
(let [prepared-message (prepare-message message chat-id current-chat?)]
|
(let [prepared-message (-> message
|
||||||
|
(prepare-message chat-id current-chat?)
|
||||||
|
(add-outgoing-status cofx))]
|
||||||
(let [fx {:db (cond->
|
(let [fx {:db (cond->
|
||||||
(-> db
|
(-> db
|
||||||
(update-in [:chats chat-id :messages] assoc message-id prepared-message)
|
(update-in [:chats chat-id :messages] assoc message-id prepared-message)
|
||||||
@ -126,37 +131,60 @@
|
|||||||
(when send-seen?
|
(when send-seen?
|
||||||
(transport/send (protocol/map->MessagesSeen {:message-ids #{message-id}}) chat-id cofx)))
|
(transport/send (protocol/map->MessagesSeen {:message-ids #{message-id}}) chat-id cofx)))
|
||||||
|
|
||||||
|
(defn ensure-clock-value [{:keys [clock-value] :as message} {:keys [last-clock-value]}]
|
||||||
|
(if clock-value
|
||||||
|
message
|
||||||
|
(assoc message :clock-value (utils.clocks/send last-clock-value))))
|
||||||
|
|
||||||
|
(defn add-command-request
|
||||||
|
[{:keys [content-type content] :as message} chat {:keys [db]}]
|
||||||
|
(let [request-command (:request-command content)
|
||||||
|
current-account (:account/account db)
|
||||||
|
command-request? (and (= content-type
|
||||||
|
constants/content-type-command-request)
|
||||||
|
request-command)
|
||||||
|
{:keys [access-scope->commands-responses]
|
||||||
|
:contacts/keys [contacts]} db]
|
||||||
|
(if command-request?
|
||||||
|
(assoc-in
|
||||||
|
message
|
||||||
|
[:content :request-command-ref]
|
||||||
|
(lookup-response-ref access-scope->commands-responses
|
||||||
|
current-account
|
||||||
|
chat
|
||||||
|
contacts
|
||||||
|
request-command))
|
||||||
|
message)))
|
||||||
|
|
||||||
(defn- add-received-message
|
(defn- add-received-message
|
||||||
[batch?
|
[batch?
|
||||||
{:keys [from message-id chat-id content content-type clock-value to-clock-value js-obj] :as message}
|
{:keys [from message-id chat-id content content-type clock-value js-obj] :as raw-message}
|
||||||
{:keys [db now] :as cofx}]
|
{:keys [db now] :as cofx}]
|
||||||
(let [{:keys [web3 current-chat-id view-id access-scope->commands-responses]
|
(let [{:keys [web3 current-chat-id view-id]} db
|
||||||
:contacts/keys [contacts]} db
|
|
||||||
current-account (:account/account db)
|
|
||||||
current-chat? (and (= :chat view-id) (= current-chat-id chat-id))
|
current-chat? (and (= :chat view-id) (= current-chat-id chat-id))
|
||||||
{:keys [last-clock-value
|
{:keys [public?] :as chat} (get-in db [:chats chat-id])
|
||||||
public?] :as chat} (get-in db [:chats chat-id])
|
add-message-fn (if batch? add-batch-message add-single-message)
|
||||||
request-command (:request-command content)
|
message (-> raw-message
|
||||||
command-request? (and (= content-type constants/content-type-command-request)
|
(ensure-clock-value chat)
|
||||||
request-command)
|
;; TODO (cammellos): Refactor so it's not computed twice
|
||||||
add-message-fn (if batch? add-batch-message add-single-message)]
|
(add-outgoing-status cofx)
|
||||||
|
(add-command-request chat cofx))]
|
||||||
(handlers-macro/merge-fx cofx
|
(handlers-macro/merge-fx cofx
|
||||||
{:confirm-messages-processed [{:web3 web3
|
{:confirm-messages-processed [{:web3 web3
|
||||||
:js-obj js-obj}]}
|
:js-obj js-obj}]}
|
||||||
(add-message-fn (cond-> message
|
(add-message-fn message current-chat?)
|
||||||
(not clock-value)
|
;; Checking :outgoing here only works for now as we don't have a :seen
|
||||||
(assoc :clock-value (utils.clocks/send last-clock-value)) ; TODO (cammeelos): for backward compatibility, we use received time to be removed when not an issue anymore
|
;; status for public chats, if we add processing of our own messages
|
||||||
command-request?
|
;; for 1-to-1 care needs to be taken not to override the :seen status
|
||||||
(assoc-in [:content :request-command-ref]
|
(add-own-status chat-id message-id (cond (:outgoing message) :sent
|
||||||
(lookup-response-ref access-scope->commands-responses
|
current-chat? :seen
|
||||||
current-account chat contacts request-command)))
|
:else :received))
|
||||||
current-chat?)
|
|
||||||
(add-own-status chat-id message-id (if current-chat? :seen :received))
|
|
||||||
(requests-events/add-request chat-id message-id)
|
(requests-events/add-request chat-id message-id)
|
||||||
(send-message-seen chat-id message-id (and (not public?)
|
(send-message-seen chat-id message-id (and (not public?)
|
||||||
current-chat?
|
current-chat?
|
||||||
(not (chat-model/bot-only-chat? db chat-id))
|
(not (chat-model/bot-only-chat? db chat-id))
|
||||||
(not (= constants/system from)))))))
|
(not (= constants/system from))
|
||||||
|
(not (:outgoing message)))))))
|
||||||
|
|
||||||
(def ^:private add-single-received-message (partial add-received-message false))
|
(def ^:private add-single-received-message (partial add-received-message false))
|
||||||
(def ^:private add-batch-received-message (partial add-received-message true))
|
(def ^:private add-batch-received-message (partial add-received-message true))
|
||||||
@ -195,7 +223,6 @@
|
|||||||
|
|
||||||
(defn system-message [chat-id message-id timestamp content]
|
(defn system-message [chat-id message-id timestamp content]
|
||||||
{:message-id message-id
|
{:message-id message-id
|
||||||
:outgoing false
|
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:from constants/system
|
:from constants/system
|
||||||
:username constants/system
|
:username constants/system
|
||||||
@ -208,18 +235,12 @@
|
|||||||
(#{:group-user-message :public-group-user-message} message-type))
|
(#{:group-user-message :public-group-user-message} message-type))
|
||||||
|
|
||||||
(defn add-to-chat?
|
(defn add-to-chat?
|
||||||
[{:keys [db]} {:keys [chat-id
|
[{:keys [db]} {:keys [chat-id clock-value message-id] :as message}]
|
||||||
clock-value
|
(let [{:keys [deleted-at-clock-value messages not-loaded-message-ids]}
|
||||||
from
|
(get-in db [:chats chat-id])]
|
||||||
message-id] :as message}]
|
(not (or (get messages message-id)
|
||||||
(let [{:keys [chats current-public-key]} db
|
(get not-loaded-message-ids message-id)
|
||||||
{:keys [deleted-at-clock-value
|
(>= deleted-at-clock-value clock-value)))))
|
||||||
messages
|
|
||||||
not-loaded-message-ids]} (get chats chat-id)]
|
|
||||||
(when (not= from current-public-key)
|
|
||||||
(not (or (get messages message-id)
|
|
||||||
(get not-loaded-message-ids message-id)
|
|
||||||
(>= deleted-at-clock-value clock-value))))))
|
|
||||||
|
|
||||||
;;;; Send message
|
;;;; Send message
|
||||||
|
|
||||||
@ -234,7 +255,6 @@
|
|||||||
{:message-id random-id
|
{:message-id random-id
|
||||||
:content (str message)
|
:content (str message)
|
||||||
:content-type constants/text-content-type
|
:content-type constants/text-content-type
|
||||||
:outgoing false
|
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:from chat-id
|
:from chat-id
|
||||||
:to "me"}
|
:to "me"}
|
||||||
@ -243,7 +263,6 @@
|
|||||||
{:message-id random-id
|
{:message-id random-id
|
||||||
:content (assoc (:content message) :bot chat-id)
|
:content (assoc (:content message) :bot chat-id)
|
||||||
:content-type constants/content-type-command-request
|
:content-type constants/content-type-command-request
|
||||||
:outgoing false
|
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:from chat-id
|
:from chat-id
|
||||||
:to "me"})]
|
:to "me"})]
|
||||||
@ -287,7 +306,6 @@
|
|||||||
:content message-text
|
:content message-text
|
||||||
:from identity
|
:from identity
|
||||||
:content-type constants/text-content-type
|
:content-type constants/text-content-type
|
||||||
:outgoing true
|
|
||||||
:timestamp now
|
:timestamp now
|
||||||
:clock-value (utils.clocks/send last-clock-value)
|
:clock-value (utils.clocks/send last-clock-value)
|
||||||
:show? true}
|
:show? true}
|
||||||
@ -398,7 +416,6 @@
|
|||||||
(if request
|
(if request
|
||||||
constants/content-type-command-request
|
constants/content-type-command-request
|
||||||
constants/content-type-command))
|
constants/content-type-command))
|
||||||
:outgoing true
|
|
||||||
:clock-value (utils.clocks/send last-clock-value)
|
:clock-value (utils.clocks/send last-clock-value)
|
||||||
:show? true}
|
:show? true}
|
||||||
chat)))
|
chat)))
|
||||||
|
@ -34,8 +34,7 @@
|
|||||||
(map #(select-keys % [:content :timestamp]))))
|
(map #(select-keys % [:content :timestamp]))))
|
||||||
|
|
||||||
(def default-values
|
(def default-values
|
||||||
{:outgoing false
|
{:to nil})
|
||||||
:to nil})
|
|
||||||
|
|
||||||
(re-frame/reg-cofx
|
(re-frame/reg-cofx
|
||||||
:data-store/get-messages
|
:data-store/get-messages
|
||||||
|
@ -1,7 +1,94 @@
|
|||||||
(ns status-im.models.contact)
|
(ns status-im.models.contact
|
||||||
|
(:require
|
||||||
|
[status-im.utils.contacts :as utils.contacts]
|
||||||
|
[status-im.data-store.contacts :as contacts-store]
|
||||||
|
[status-im.transport.message.core :as transport]
|
||||||
|
[status-im.transport.message.v1.contact :as message.v1.contact]
|
||||||
|
[status-im.utils.handlers-macro :as handlers-macro]))
|
||||||
|
|
||||||
(defn can-add-to-contacts? [{:keys [pending? dapp?]}]
|
(defn can-add-to-contacts? [{:keys [pending? dapp?]}]
|
||||||
(and (not dapp?)
|
(and (not dapp?)
|
||||||
(or pending?
|
(or pending?
|
||||||
;; it's not in the contact list at all
|
;; it's not in the contact list at all
|
||||||
(nil? pending?))))
|
(nil? pending?))))
|
||||||
|
|
||||||
|
(defn- build-contact [whisper-id {{:keys [chats] :contacts/keys [contacts]} :db}]
|
||||||
|
(assoc (or (get contacts whisper-id)
|
||||||
|
(utils.contacts/whisper-id->new-contact whisper-id))
|
||||||
|
:address (utils.contacts/public-key->address whisper-id)))
|
||||||
|
|
||||||
|
(defn- own-info [db]
|
||||||
|
(let [{:keys [name photo-path address]} (:account/account db)
|
||||||
|
fcm-token (get-in db [:notifications :fcm-token])]
|
||||||
|
{:name name
|
||||||
|
:profile-image photo-path
|
||||||
|
:address address
|
||||||
|
:fcm-token fcm-token}))
|
||||||
|
|
||||||
|
(defn- add-new-contact [{:keys [whisper-identity] :as contact} {:keys [db]}]
|
||||||
|
(let [new-contact (assoc contact
|
||||||
|
:pending? false
|
||||||
|
:public-key whisper-identity)]
|
||||||
|
{:db (-> db
|
||||||
|
(update-in [:contacts/contacts whisper-identity]
|
||||||
|
merge new-contact)
|
||||||
|
(assoc-in [:contacts/new-identity] ""))
|
||||||
|
:data-store/tx [(contacts-store/save-contact-tx new-contact)]}))
|
||||||
|
|
||||||
|
(defn send-contact-request [{:keys [whisper-identity pending? dapp?] :as contact} {:keys [db] :as cofx}]
|
||||||
|
(when-not dapp?
|
||||||
|
(if pending?
|
||||||
|
(transport/send (message.v1.contact/map->ContactRequestConfirmed (own-info db)) whisper-identity cofx)
|
||||||
|
(transport/send (message.v1.contact/map->ContactRequest (own-info db)) whisper-identity cofx))))
|
||||||
|
|
||||||
|
(defn add-contact [whisper-id {:keys [db] :as cofx}]
|
||||||
|
(let [contact (build-contact whisper-id cofx)]
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
(add-new-contact contact)
|
||||||
|
(send-contact-request contact))))
|
||||||
|
|
||||||
|
(defn handle-contact-update
|
||||||
|
[public-key
|
||||||
|
timestamp
|
||||||
|
{:keys [name profile-image address fcm-token] :as m}
|
||||||
|
{{:contacts/keys [contacts] :keys [current-public-key] :as db} :db :as cofx}]
|
||||||
|
;; We need to convert to timestamp ms as before we were using now in ms to
|
||||||
|
;; set last updated
|
||||||
|
;; Using whisper timestamp mostly works but breaks in a few scenarios:
|
||||||
|
;; 2 updates sent in the same second
|
||||||
|
;; when using multi-device & clocks are out of sync
|
||||||
|
;; Using logical clocks is probably the correct way to handle it, but an overkill
|
||||||
|
;; for now
|
||||||
|
(let [timestamp-ms (* timestamp 1000)
|
||||||
|
prev-last-updated (get-in db [:contacts/contacts public-key :last-updated])]
|
||||||
|
(when (and (not= current-public-key public-key)
|
||||||
|
(< prev-last-updated timestamp-ms))
|
||||||
|
(let [contact (get contacts public-key)
|
||||||
|
|
||||||
|
;; Backward compatibility with <= 0.9.21, as they don't send
|
||||||
|
;; fcm-token & address in contact updates
|
||||||
|
contact-props (cond->
|
||||||
|
{:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path profile-image
|
||||||
|
:name name
|
||||||
|
:address (or address
|
||||||
|
(:address contact)
|
||||||
|
(utils.contacts/public-key->address public-key))
|
||||||
|
:last-updated timestamp-ms
|
||||||
|
;;NOTE (yenda) in case of concurrent contact request
|
||||||
|
:pending? (get contact :pending? true)}
|
||||||
|
fcm-token (assoc :fcm-token fcm-token))]
|
||||||
|
;;NOTE (yenda) only update if there is changes to the contact
|
||||||
|
(when-not (= contact-props
|
||||||
|
(select-keys contact [:whisper-identity :public-key :address
|
||||||
|
:photo-path :name :fcm-token :pending?]))
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
{:db (update-in db [:contacts/contacts public-key]
|
||||||
|
merge contact-props)
|
||||||
|
:data-store/tx [(contacts-store/save-contact-tx
|
||||||
|
contact-props)]}))))))
|
||||||
|
|
||||||
|
(def receive-contact-request handle-contact-update)
|
||||||
|
(def receive-contact-request-confirmation handle-contact-update)
|
||||||
|
(def receive-contact-update handle-contact-update)
|
||||||
|
@ -81,6 +81,9 @@
|
|||||||
(defn set-current-mailserver [{:keys [db] :as cofx}]
|
(defn set-current-mailserver [{:keys [db] :as cofx}]
|
||||||
{:db (assoc db :inbox/current-id (selected-or-random-id cofx))})
|
{:db (assoc db :inbox/current-id (selected-or-random-id cofx))})
|
||||||
|
|
||||||
|
(defn set-initial-last-request [{:keys [db now] :as cofx}]
|
||||||
|
{:db (update-in db [:account/account :last-request] (fnil identity (quot now 1000)))})
|
||||||
|
|
||||||
(defn add-custom-mailservers [mailservers {:keys [db]}]
|
(defn add-custom-mailservers [mailservers {:keys [db]}]
|
||||||
{:db (reduce (fn [db {:keys [id chain] :as mailserver}]
|
{:db (reduce (fn [db {:keys [id chain] :as mailserver}]
|
||||||
(assoc-in db [:inbox/wnodes (keyword chain) id]
|
(assoc-in db [:inbox/wnodes (keyword chain) id]
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
(try
|
(try
|
||||||
(handlers-macro/merge-fx
|
(handlers-macro/merge-fx
|
||||||
(assoc cofx :js-obj js-message)
|
(assoc cofx :js-obj js-message)
|
||||||
(message/receive status-message (or chat-id sig) sig)
|
(message/receive status-message (or chat-id sig) sig timestamp)
|
||||||
(update-last-received-from-inbox now-in-s timestamp ttl))
|
(update-last-received-from-inbox now-in-s timestamp ttl))
|
||||||
(catch :default e nil))))) ; ignore unknown message types
|
(catch :default e nil))))) ; ignore unknown message types
|
||||||
|
|
||||||
@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:contact/add-new-sym-key
|
:contact/add-new-sym-key
|
||||||
(fn [{:keys [db] :as cofx} [_ {:keys [sym-key-id sym-key chat-id topic message]}]]
|
(fn [{:keys [db] :as cofx} [_ {:keys [sym-key-id sym-key chat-id topic timestamp message]}]]
|
||||||
(let [{:keys [web3 current-public-key]} db
|
(let [{:keys [web3 current-public-key]} db
|
||||||
chat-transport-info (-> (get-in db [:transport/chats chat-id])
|
chat-transport-info (-> (get-in db [:transport/chats chat-id])
|
||||||
(assoc :sym-key-id sym-key-id
|
(assoc :sym-key-id sym-key-id
|
||||||
@ -106,7 +106,7 @@
|
|||||||
:chat-id chat-id}
|
:chat-id chat-id}
|
||||||
:data-store/tx [(transport-store/save-transport-tx {:chat-id chat-id
|
:data-store/tx [(transport-store/save-transport-tx {:chat-id chat-id
|
||||||
:chat chat-transport-info})]}
|
:chat chat-transport-info})]}
|
||||||
(message/receive message chat-id chat-id)))))
|
(message/receive message chat-id chat-id timestamp)))))
|
||||||
|
|
||||||
#_(handlers/register-handler-fx
|
#_(handlers/register-handler-fx
|
||||||
:send-test-message
|
:send-test-message
|
||||||
@ -155,7 +155,7 @@
|
|||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:group/add-new-sym-key
|
:group/add-new-sym-key
|
||||||
[re-frame/trim-v (re-frame/inject-cofx :random-id)]
|
[re-frame/trim-v (re-frame/inject-cofx :random-id)]
|
||||||
(fn [{:keys [db] :as cofx} [{:keys [sym-key-id sym-key chat-id signature message]}]]
|
(fn [{:keys [db] :as cofx} [{:keys [sym-key-id sym-key chat-id signature timestamp message]}]]
|
||||||
(let [{:keys [web3 current-public-key]} db
|
(let [{:keys [web3 current-public-key]} db
|
||||||
topic (transport.utils/get-topic chat-id)
|
topic (transport.utils/get-topic chat-id)
|
||||||
fx {:db (assoc-in db
|
fx {:db (assoc-in db
|
||||||
@ -174,7 +174,7 @@
|
|||||||
(assoc :sym-key sym-key))})]}]
|
(assoc :sym-key sym-key))})]}]
|
||||||
;; if new sym-key is wrapping some message, call receive on it as well, if not just update the transport layer
|
;; if new sym-key is wrapping some message, call receive on it as well, if not just update the transport layer
|
||||||
(if message
|
(if message
|
||||||
(handlers-macro/merge-fx cofx fx (message/receive message chat-id signature))
|
(handlers-macro/merge-fx cofx fx (message/receive message chat-id signature timestamp))
|
||||||
fx))))
|
fx))))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
|
@ -1,34 +1,32 @@
|
|||||||
(ns status-im.transport.impl.receive
|
(ns status-im.transport.impl.receive
|
||||||
(:require
|
(:require
|
||||||
[status-im.chat.models.group-chat :as models.group-chat]
|
[status-im.chat.models.group-chat :as models.group-chat]
|
||||||
[status-im.ui.screens.contacts.core :as contacts]
|
[status-im.models.contact :as models.contact]
|
||||||
[status-im.transport.message.core :as message]
|
[status-im.transport.message.core :as message]
|
||||||
[status-im.transport.message.v1.contact :as transport.contact]
|
[status-im.transport.message.v1.contact :as transport.contact]
|
||||||
[status-im.transport.message.v1.group-chat :as transport.group-chat]))
|
[status-im.transport.message.v1.group-chat :as transport.group-chat]))
|
||||||
|
|
||||||
(extend-type transport.group-chat/GroupAdminUpdate
|
(extend-type transport.group-chat/GroupAdminUpdate
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this chat-id signature _ cofx]
|
||||||
(models.group-chat/handle-group-admin-update this chat-id signature cofx)))
|
(models.group-chat/handle-group-admin-update this chat-id signature cofx)))
|
||||||
|
|
||||||
(extend-type transport.group-chat/GroupLeave
|
(extend-type transport.group-chat/GroupLeave
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this chat-id signature _ cofx]
|
||||||
(models.group-chat/handle-group-leave chat-id signature cofx)))
|
(models.group-chat/handle-group-leave chat-id signature cofx)))
|
||||||
|
|
||||||
(extend-type transport.contact/ContactRequest
|
(extend-type transport.contact/ContactRequest
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this _ signature timestamp cofx]
|
||||||
(contacts/receive-contact-request signature this cofx)))
|
(models.contact/receive-contact-request signature timestamp this cofx)))
|
||||||
|
|
||||||
(extend-type transport.contact/ContactRequestConfirmed
|
(extend-type transport.contact/ContactRequestConfirmed
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this _ signature timestamp cofx]
|
||||||
(contacts/receive-contact-request-confirmation signature this cofx)))
|
(models.contact/receive-contact-request-confirmation signature timestamp this cofx)))
|
||||||
|
|
||||||
(extend-type transport.contact/ContactUpdate
|
(extend-type transport.contact/ContactUpdate
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this _ signature timestamp cofx]
|
||||||
(contacts/receive-contact-update chat-id
|
(models.contact/receive-contact-update signature timestamp this cofx)))
|
||||||
signature
|
|
||||||
this cofx)))
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
;;
|
;;
|
||||||
;; - We send a request to the mailserver, we are only interested in the
|
;; - We send a request to the mailserver, we are only interested in the
|
||||||
;; messages since `last-request`, the time of the last successful request,
|
;; messages since `last-request`, the time of the last successful request,
|
||||||
;; and the last 7 days for topics that were just joined
|
;; and the last 24 hours for topics that were just joined
|
||||||
;; - The mailserver doesn't directly respond to the request and
|
;; - The mailserver doesn't directly respond to the request and
|
||||||
;; instead we start receiving messages in the filters for the requested
|
;; instead we start receiving messages in the filters for the requested
|
||||||
;; topics.
|
;; topics.
|
||||||
@ -149,20 +149,8 @@
|
|||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
::request-messages
|
::request-messages
|
||||||
(fn [{:keys [wnode topics to from web3]}]
|
(fn [params]
|
||||||
(request-inbox-messages web3
|
(doseq [{:keys [wnode topics to from web3]} params]
|
||||||
wnode
|
|
||||||
topics
|
|
||||||
from
|
|
||||||
to
|
|
||||||
#(log/info "offline inbox: request-messages response" %1 %2 from to)
|
|
||||||
#(log/error "offline inbox: request-messages error" %1 %2 from to))))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::request-history
|
|
||||||
(fn [{:keys [wnode topics now-in-s web3]}]
|
|
||||||
(let [from (- now-in-s seven-days)
|
|
||||||
to now-in-s]
|
|
||||||
(request-inbox-messages web3
|
(request-inbox-messages web3
|
||||||
wnode
|
wnode
|
||||||
topics
|
topics
|
||||||
@ -245,17 +233,20 @@
|
|||||||
(defn get-request-messages-topics
|
(defn get-request-messages-topics
|
||||||
"Returns topics for which full history has already been recovered"
|
"Returns topics for which full history has already been recovered"
|
||||||
[db]
|
[db]
|
||||||
(conj (mapv :topic
|
(conj (map :topic
|
||||||
(remove :fetch-history?
|
(remove :fetch-history?
|
||||||
(vals (:transport/chats db))))
|
(vals (:transport/chats db))))
|
||||||
(transport.utils/get-topic constants/contact-discovery)))
|
(transport.utils/get-topic constants/contact-discovery)))
|
||||||
|
|
||||||
(defn get-request-history-topics
|
(defn get-request-history-topics
|
||||||
"Returns topics for which full history has not been recovered"
|
"Returns topics for which full history has not been recovered"
|
||||||
[db]
|
[db]
|
||||||
(mapv :topic
|
(map :topic
|
||||||
(filter :fetch-history?
|
(filter :fetch-history?
|
||||||
(vals (:transport/chats db)))))
|
(vals (:transport/chats db)))))
|
||||||
|
|
||||||
|
(defn request-history-span [now-in-s]
|
||||||
|
(- now-in-s one-day))
|
||||||
|
|
||||||
(defn request-messages
|
(defn request-messages
|
||||||
([{:keys [db now] :as cofx}]
|
([{:keys [db now] :as cofx}]
|
||||||
@ -268,15 +259,16 @@
|
|||||||
request-messages-topics (get-request-messages-topics db)
|
request-messages-topics (get-request-messages-topics db)
|
||||||
request-history-topics (get-request-history-topics db)]
|
request-history-topics (get-request-history-topics db)]
|
||||||
(when (inbox-ready? wnode cofx)
|
(when (inbox-ready? wnode cofx)
|
||||||
{::request-messages {:wnode wnode
|
{::request-messages [{:wnode wnode
|
||||||
:topics request-messages-topics
|
:topics request-messages-topics
|
||||||
:from last-request
|
:from last-request
|
||||||
:to now-in-s
|
:to now-in-s
|
||||||
:web3 web3}
|
:web3 web3}
|
||||||
::request-history {:wnode wnode
|
{:wnode wnode
|
||||||
:now-in-s now-in-s
|
:from (request-history-span now-in-s)
|
||||||
:topics request-history-topics
|
:to now-in-s
|
||||||
:web3 web3}
|
:topics request-history-topics
|
||||||
|
:web3 web3}]
|
||||||
:db (assoc db :inbox/fetching? true)
|
:db (assoc db :inbox/fetching? true)
|
||||||
:dispatch-later [{:ms fetching-timeout
|
:dispatch-later [{:ms fetching-timeout
|
||||||
:dispatch [:inbox/check-fetching now-in-s]}]})))
|
:dispatch [:inbox/check-fetching now-in-s]}]})))
|
||||||
@ -290,10 +282,11 @@
|
|||||||
topic (get-in db [:transport/chats chat-id :topic])
|
topic (get-in db [:transport/chats chat-id :topic])
|
||||||
now-in-s (quot now 1000)]
|
now-in-s (quot now 1000)]
|
||||||
(when (inbox-ready? wnode cofx)
|
(when (inbox-ready? wnode cofx)
|
||||||
{::request-history {:wnode wnode
|
{::request-messages [{:wnode wnode
|
||||||
:topics [topic]
|
:topics [topic]
|
||||||
:now-in-s now-in-s
|
:from (request-history-span now-in-s)
|
||||||
:web3 web3}
|
:to now-in-s
|
||||||
|
:web3 web3}]
|
||||||
:db (assoc db :inbox/fetching? true)
|
:db (assoc db :inbox/fetching? true)
|
||||||
:dispatch-later [{:ms fetching-timeout
|
:dispatch-later [{:ms fetching-timeout
|
||||||
:dispatch [:inbox/check-fetching now-in-s chat-id]}]})))
|
:dispatch [:inbox/check-fetching now-in-s chat-id]}]})))
|
||||||
@ -364,6 +357,7 @@
|
|||||||
(defn initialize-offline-inbox [custom-mailservers cofx]
|
(defn initialize-offline-inbox [custom-mailservers cofx]
|
||||||
(handlers-macro/merge-fx cofx
|
(handlers-macro/merge-fx cofx
|
||||||
(models.mailserver/add-custom-mailservers custom-mailservers)
|
(models.mailserver/add-custom-mailservers custom-mailservers)
|
||||||
|
(models.mailserver/set-initial-last-request)
|
||||||
(models.mailserver/set-current-mailserver)))
|
(models.mailserver/set-current-mailserver)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
|
@ -4,4 +4,4 @@
|
|||||||
(defprotocol StatusMessage
|
(defprotocol StatusMessage
|
||||||
"Protocol for the messages that are sent through the transport layer"
|
"Protocol for the messages that are sent through the transport layer"
|
||||||
(send [this chat-id cofx] "Method producing all effects necessary for sending the message record")
|
(send [this chat-id cofx] "Method producing all effects necessary for sending the message record")
|
||||||
(receive [this chat-id signature cofx] "Method producing all effects necessary for receiving the message record"))
|
(receive [this chat-id signature timestamp cofx] "Method producing all effects necessary for receiving the message record"))
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
(deftype ContactUpdateHandler []
|
(deftype ContactUpdateHandler []
|
||||||
Object
|
Object
|
||||||
(tag [this v] "c6")
|
(tag [this v] "c6")
|
||||||
(rep [this {:keys [name profile-image]}]
|
(rep [this {:keys [name profile-image address fcm-token]}]
|
||||||
#js [name profile-image]))
|
#js [name profile-image address fcm-token]))
|
||||||
|
|
||||||
(deftype MessageHandler []
|
(deftype MessageHandler []
|
||||||
Object
|
Object
|
||||||
@ -102,8 +102,8 @@
|
|||||||
(v1.protocol/Message. content content-type message-type clock-value timestamp))
|
(v1.protocol/Message. content content-type message-type clock-value timestamp))
|
||||||
"c5" (fn [message-ids]
|
"c5" (fn [message-ids]
|
||||||
(v1.protocol/MessagesSeen. message-ids))
|
(v1.protocol/MessagesSeen. message-ids))
|
||||||
"c6" (fn [[name profile-image]]
|
"c6" (fn [[name profile-image address fcm-token]]
|
||||||
(v1.contact/ContactUpdate. name profile-image))}})) ; removed group chat handlers for https://github.com/status-im/status-react/issues/4506
|
(v1.contact/ContactUpdate. name profile-image address fcm-token))}})) ; removed group chat handlers for https://github.com/status-im/status-react/issues/4506
|
||||||
|
|
||||||
(defn serialize
|
(defn serialize
|
||||||
"Serializes a record implementing the StatusMessage protocol using the custom writers"
|
"Serializes a record implementing the StatusMessage protocol using the custom writers"
|
||||||
|
@ -38,11 +38,11 @@
|
|||||||
"contact-request-confirmation")
|
"contact-request-confirmation")
|
||||||
:data-store/tx [(transport-store/save-transport-tx {:chat-id chat-id
|
:data-store/tx [(transport-store/save-transport-tx {:chat-id chat-id
|
||||||
:chat updated-chat})]}
|
:chat updated-chat})]}
|
||||||
(protocol/send {:chat-id chat-id
|
(protocol/send-with-pubkey {:chat-id chat-id
|
||||||
:payload this
|
:payload this
|
||||||
:success-event success-event})))))
|
:success-event success-event})))))
|
||||||
|
|
||||||
(defrecord ContactUpdate [name profile-image]
|
(defrecord ContactUpdate [name profile-image address fcm-token]
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(send [this _ {:keys [db] :as cofx}]
|
(send [this _ {:keys [db] :as cofx}]
|
||||||
(let [public-keys (reduce (fn [acc [_ {:keys [public-key pending?]}]]
|
(let [public-keys (reduce (fn [acc [_ {:keys [public-key pending?]}]]
|
||||||
@ -65,9 +65,9 @@
|
|||||||
[:transport/chats chat-id :resend?]
|
[:transport/chats chat-id :resend?]
|
||||||
"contact-update")
|
"contact-update")
|
||||||
:data-store/tx tx}
|
:data-store/tx tx}
|
||||||
(protocol/send {:chat-id chat-id
|
(protocol/send-with-pubkey {:chat-id chat-id
|
||||||
:payload this
|
:payload this
|
||||||
:success-event success-event}))))
|
:success-event success-event}))))
|
||||||
recipients))))
|
recipients))))
|
||||||
|
|
||||||
(defn remove-chat-filter
|
(defn remove-chat-filter
|
||||||
@ -90,7 +90,7 @@
|
|||||||
:payload this
|
:payload this
|
||||||
:success-event success-event}
|
:success-event success-event}
|
||||||
cofx)))
|
cofx)))
|
||||||
(receive [this chat-id signature {:keys [db] :as cofx}]
|
(receive [this chat-id _ timestamp {:keys [db] :as cofx}]
|
||||||
(let [current-sym-key (get-in db [:transport/chats chat-id :sym-key])
|
(let [current-sym-key (get-in db [:transport/chats chat-id :sym-key])
|
||||||
;; NOTE(yenda) to support concurrent contact request without additional
|
;; NOTE(yenda) to support concurrent contact request without additional
|
||||||
;; interactions we don't save the new key if these conditions are met:
|
;; interactions we don't save the new key if these conditions are met:
|
||||||
@ -105,6 +105,7 @@
|
|||||||
(let [on-success (fn [sym-key sym-key-id]
|
(let [on-success (fn [sym-key sym-key-id]
|
||||||
(re-frame/dispatch [:contact/add-new-sym-key
|
(re-frame/dispatch [:contact/add-new-sym-key
|
||||||
{:sym-key-id sym-key-id
|
{:sym-key-id sym-key-id
|
||||||
|
:timestamp timestamp
|
||||||
:sym-key sym-key
|
:sym-key sym-key
|
||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:topic topic
|
:topic topic
|
||||||
@ -119,4 +120,4 @@
|
|||||||
;; dereferrencing it
|
;; dereferrencing it
|
||||||
(remove-chat-filter chat-id)))
|
(remove-chat-filter chat-id)))
|
||||||
;; if we don't save the key, we read the message directly
|
;; if we don't save the key, we read the message directly
|
||||||
(message/receive message chat-id chat-id cofx)))))
|
(message/receive message chat-id chat-id timestamp cofx)))))
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
:chat-id chat-id
|
:chat-id chat-id
|
||||||
:payload this}
|
:payload this}
|
||||||
cofx)))
|
cofx)))
|
||||||
(receive [this _ signature {:keys [db] :as cofx}]
|
(receive [this _ signature timestamp {:keys [db] :as cofx}]
|
||||||
(handlers-macro/merge-fx
|
(handlers-macro/merge-fx
|
||||||
cofx
|
cofx
|
||||||
{:shh/add-new-sym-keys
|
{:shh/add-new-sym-keys
|
||||||
@ -30,6 +30,7 @@
|
|||||||
[:group/add-new-sym-key
|
[:group/add-new-sym-key
|
||||||
{:chat-id chat-id
|
{:chat-id chat-id
|
||||||
:signature signature
|
:signature signature
|
||||||
|
:timestamp timestamp
|
||||||
:sym-key sym-key
|
:sym-key sym-key
|
||||||
:sym-key-id sym-key-id
|
:sym-key-id sym-key-id
|
||||||
:message message}]))}]}
|
:message message}]))}]}
|
||||||
|
@ -76,12 +76,12 @@
|
|||||||
(defrecord Ack [message-ids]
|
(defrecord Ack [message-ids]
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(send [this cofx chat-id])
|
(send [this cofx chat-id])
|
||||||
(receive [this db chat-id sig]))
|
(receive [this chat-id sig timestamp cofx]))
|
||||||
|
|
||||||
(defrecord Seen [message-ids]
|
(defrecord Seen [message-ids]
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
(send [this cofx chat-id])
|
(send [this cofx chat-id])
|
||||||
(receive [this cofx chat-id sig]))
|
(receive [this chat-id sig timestamp cofx]))
|
||||||
|
|
||||||
(defrecord Message [content content-type message-type clock-value timestamp]
|
(defrecord Message [content content-type message-type clock-value timestamp]
|
||||||
message/StatusMessage
|
message/StatusMessage
|
||||||
@ -97,7 +97,7 @@
|
|||||||
config/use-sym-key)
|
config/use-sym-key)
|
||||||
(send params cofx)
|
(send params cofx)
|
||||||
(send-with-pubkey params cofx))))
|
(send-with-pubkey params cofx))))
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this chat-id signature _ cofx]
|
||||||
{:chat-received-message/add-fx
|
{:chat-received-message/add-fx
|
||||||
[(assoc (into {} this)
|
[(assoc (into {} this)
|
||||||
:message-id (transport.utils/message-id this)
|
:message-id (transport.utils/message-id this)
|
||||||
@ -112,5 +112,5 @@
|
|||||||
(send {:chat-id chat-id
|
(send {:chat-id chat-id
|
||||||
:payload this}
|
:payload this}
|
||||||
cofx))
|
cofx))
|
||||||
(receive [this chat-id signature cofx]
|
(receive [this chat-id signature _ cofx]
|
||||||
(chat/receive-seen chat-id signature this cofx)))
|
(chat/receive-seen chat-id signature this cofx)))
|
||||||
|
@ -12,14 +12,18 @@
|
|||||||
([new-account-fields after-update-event {:keys [db] :as cofx}]
|
([new-account-fields after-update-event {:keys [db] :as cofx}]
|
||||||
(let [current-account (:account/account db)
|
(let [current-account (:account/account db)
|
||||||
new-account (merge current-account new-account-fields)
|
new-account (merge current-account new-account-fields)
|
||||||
|
fcm-token (get-in db [:notifications :fcm-token])
|
||||||
fx {:db (assoc db :account/account new-account)
|
fx {:db (assoc db :account/account new-account)
|
||||||
:data-store/base-tx [(accounts-store/save-account-tx
|
:data-store/base-tx [(accounts-store/save-account-tx
|
||||||
(assoc new-account
|
(assoc new-account
|
||||||
:after-update-event
|
:after-update-event
|
||||||
after-update-event))]}
|
after-update-event))]}
|
||||||
{:keys [name photo-path]} new-account]
|
{:keys [name photo-path address]} new-account]
|
||||||
(if (or (:name new-account-fields) (:photo-path new-account-fields))
|
(if (or (:name new-account-fields) (:photo-path new-account-fields))
|
||||||
(handlers-macro/merge-fx cofx fx (transport/send (message.contact/ContactUpdate. name photo-path) nil))
|
(handlers-macro/merge-fx
|
||||||
|
cofx
|
||||||
|
fx
|
||||||
|
(transport/send (message.contact/ContactUpdate. name photo-path address fcm-token) nil))
|
||||||
fx))))
|
fx))))
|
||||||
|
|
||||||
(defn clean-seed-phrase
|
(defn clean-seed-phrase
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
(ns status-im.ui.screens.contacts.core
|
|
||||||
(:require [status-im.utils.handlers-macro :as handlers-macro]
|
|
||||||
[status-im.chat.models :as chat.models]
|
|
||||||
[status-im.data-store.contacts :as contacts-store]))
|
|
||||||
|
|
||||||
(defn receive-contact-request
|
|
||||||
[public-key
|
|
||||||
{:keys [name profile-image address fcm-token]}
|
|
||||||
{{:contacts/keys [contacts] :as db} :db :as cofx}]
|
|
||||||
(let [contact (get contacts public-key)
|
|
||||||
contact-props {:whisper-identity public-key
|
|
||||||
:public-key public-key
|
|
||||||
:address address
|
|
||||||
:photo-path profile-image
|
|
||||||
:name name
|
|
||||||
:fcm-token fcm-token
|
|
||||||
;;NOTE (yenda) in case of concurrent contact request
|
|
||||||
:pending? (get contact :pending? true)}]
|
|
||||||
;;NOTE (yenda) only update if there is changes to the contact
|
|
||||||
(when-not (= contact-props
|
|
||||||
(select-keys contact [:whisper-identity :public-key :address
|
|
||||||
:photo-path :name :fcm-token :pending?]))
|
|
||||||
(handlers-macro/merge-fx cofx
|
|
||||||
{:db (update-in db [:contacts/contacts public-key]
|
|
||||||
merge contact-props)
|
|
||||||
:data-store/tx [(contacts-store/save-contact-tx
|
|
||||||
contact-props)]}))))
|
|
||||||
|
|
||||||
(defn receive-contact-request-confirmation
|
|
||||||
[public-key {:keys [name profile-image address fcm-token]}
|
|
||||||
{{:contacts/keys [contacts] :as db} :db :as cofx}]
|
|
||||||
(when-let [contact (get contacts public-key)]
|
|
||||||
(let [contact-props {:whisper-identity public-key
|
|
||||||
:public-key public-key
|
|
||||||
:address address
|
|
||||||
:photo-path profile-image
|
|
||||||
:name name
|
|
||||||
:fcm-token fcm-token}]
|
|
||||||
(handlers-macro/merge-fx cofx
|
|
||||||
{:db (update-in db [:contacts/contacts public-key]
|
|
||||||
merge contact-props)
|
|
||||||
:data-store/tx [(contacts-store/save-contact-tx
|
|
||||||
contact-props)]}))))
|
|
||||||
|
|
||||||
(defn- update-contact [{:keys [whisper-identity] :as contact} {:keys [db]}]
|
|
||||||
(when (get-in db [:contacts/contacts whisper-identity])
|
|
||||||
{:db (update-in db [:contacts/contacts whisper-identity] merge contact)
|
|
||||||
:data-store/tx [(contacts-store/save-contact-tx contact)]}))
|
|
||||||
|
|
||||||
(defn receive-contact-update [chat-id public-key {:keys [name profile-image]} {:keys [db now] :as cofx}]
|
|
||||||
(let [{:keys [chats current-public-key]} db]
|
|
||||||
(when (not= current-public-key public-key)
|
|
||||||
(let [prev-last-updated (get-in db [:contacts/contacts public-key :last-updated])]
|
|
||||||
(when (<= prev-last-updated now)
|
|
||||||
(let [contact {:whisper-identity public-key
|
|
||||||
:name name
|
|
||||||
:photo-path profile-image
|
|
||||||
:last-updated now}]
|
|
||||||
(update-contact contact cofx)))))))
|
|
@ -1,18 +1,21 @@
|
|||||||
(ns status-im.ui.screens.contacts.events
|
(ns status-im.ui.screens.contacts.events
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.chat.events :as chat.events]
|
|
||||||
[status-im.data-store.contacts :as contacts-store]
|
|
||||||
[status-im.transport.message.core :as transport]
|
|
||||||
[status-im.transport.message.v1.contact :as message.v1.contact]
|
|
||||||
[status-im.ui.screens.add-new.new-chat.db :as new-chat.db]
|
[status-im.ui.screens.add-new.new-chat.db :as new-chat.db]
|
||||||
[status-im.ui.screens.contacts.default-dapps :as default-dapps]
|
[status-im.ui.screens.contacts.default-dapps :as default-dapps]
|
||||||
[status-im.ui.screens.navigation :as navigation]
|
|
||||||
[status-im.utils.contacts :as utils.contacts]
|
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.utils.handlers-macro :as handlers-macro]
|
[status-im.utils.handlers-macro :as handlers-macro]
|
||||||
[status-im.utils.js-resources :as js-res]
|
[status-im.utils.js-resources :as js-res]
|
||||||
[status-im.utils.utils :as utils]))
|
[status-im.chat.events :as chat.events]
|
||||||
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
|
[status-im.models.contact :as models.contact]))
|
||||||
|
|
||||||
|
(defn add-contact-and-open-chat [whisper-id cofx]
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
(navigation/navigate-to-clean :home)
|
||||||
|
(models.contact/add-contact whisper-id)
|
||||||
|
(chat.events/start-chat whisper-id {})))
|
||||||
|
|
||||||
(re-frame/reg-cofx
|
(re-frame/reg-cofx
|
||||||
:get-default-contacts
|
:get-default-contacts
|
||||||
@ -26,11 +29,6 @@
|
|||||||
|
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
||||||
(defn- update-contact [{:keys [whisper-identity] :as contact} {:keys [db]}]
|
|
||||||
(when (get-in db [:contacts/contacts whisper-identity])
|
|
||||||
{:db (update-in db [:contacts/contacts whisper-identity] merge contact)
|
|
||||||
:data-store/tx [(contacts-store/save-contact-tx contact)]}))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:load-contacts
|
:load-contacts
|
||||||
[(re-frame/inject-cofx :data-store/get-all-contacts)]
|
[(re-frame/inject-cofx :data-store/get-all-contacts)]
|
||||||
@ -39,52 +37,11 @@
|
|||||||
contacts (into {} contacts-list)]
|
contacts (into {} contacts-list)]
|
||||||
{:db (update db :contacts/contacts #(merge contacts %))})))
|
{:db (update db :contacts/contacts #(merge contacts %))})))
|
||||||
|
|
||||||
(defn- add-new-contact [{:keys [whisper-identity] :as contact} {:keys [db]}]
|
|
||||||
(let [new-contact (assoc contact
|
|
||||||
:pending? false
|
|
||||||
:public-key whisper-identity)]
|
|
||||||
{:db (-> db
|
|
||||||
(update-in [:contacts/contacts whisper-identity]
|
|
||||||
merge new-contact)
|
|
||||||
(assoc-in [:contacts/new-identity] ""))
|
|
||||||
:data-store/tx [(contacts-store/save-contact-tx new-contact)]}))
|
|
||||||
|
|
||||||
(defn- own-info [db]
|
|
||||||
(let [{:keys [name photo-path address]} (:account/account db)
|
|
||||||
fcm-token (get-in db [:notifications :fcm-token])]
|
|
||||||
{:name name
|
|
||||||
:profile-image photo-path
|
|
||||||
:address address
|
|
||||||
:fcm-token fcm-token}))
|
|
||||||
|
|
||||||
(defn send-contact-request [{:keys [whisper-identity pending? dapp?] :as contact} {:keys [db] :as cofx}]
|
|
||||||
(when-not dapp?
|
|
||||||
(if pending?
|
|
||||||
(transport/send (message.v1.contact/map->ContactRequestConfirmed (own-info db)) whisper-identity cofx)
|
|
||||||
(transport/send (message.v1.contact/map->ContactRequest (own-info db)) whisper-identity cofx))))
|
|
||||||
|
|
||||||
(defn- build-contact [whisper-id {{:keys [chats] :contacts/keys [contacts]} :db}]
|
|
||||||
(assoc (or (get contacts whisper-id)
|
|
||||||
(utils.contacts/whisper-id->new-contact whisper-id))
|
|
||||||
:address (utils.contacts/public-key->address whisper-id)))
|
|
||||||
|
|
||||||
(defn add-contact [whisper-id {:keys [db] :as cofx}]
|
|
||||||
(let [contact (build-contact whisper-id cofx)]
|
|
||||||
(handlers-macro/merge-fx cofx
|
|
||||||
(add-new-contact contact)
|
|
||||||
(send-contact-request contact))))
|
|
||||||
|
|
||||||
(defn add-contact-and-open-chat [whisper-id cofx]
|
|
||||||
(handlers-macro/merge-fx cofx
|
|
||||||
(navigation/navigate-to-clean :home)
|
|
||||||
(add-contact whisper-id)
|
|
||||||
(chat.events/start-chat whisper-id {})))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:add-contact
|
:add-contact
|
||||||
[(re-frame/inject-cofx :random-id)]
|
[(re-frame/inject-cofx :random-id)]
|
||||||
(fn [cofx [_ whisper-id]]
|
(fn [cofx [_ whisper-id]]
|
||||||
(add-contact whisper-id cofx)))
|
(models.contact/add-contact whisper-id cofx)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:set-contact-identity-from-qr
|
:set-contact-identity-from-qr
|
||||||
@ -111,10 +68,7 @@
|
|||||||
:open-chat-with-contact
|
:open-chat-with-contact
|
||||||
[(re-frame/inject-cofx :random-id)]
|
[(re-frame/inject-cofx :random-id)]
|
||||||
(fn [cofx [_ {:keys [whisper-identity]}]]
|
(fn [cofx [_ {:keys [whisper-identity]}]]
|
||||||
(handlers-macro/merge-fx cofx
|
(add-contact-and-open-chat whisper-identity cofx)))
|
||||||
(navigation/navigate-to-clean :home)
|
|
||||||
(add-contact whisper-identity)
|
|
||||||
(chat.events/start-chat whisper-identity {}))))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:add-contact-handler
|
:add-contact-handler
|
||||||
|
@ -11,13 +11,6 @@
|
|||||||
:from "a"
|
:from "a"
|
||||||
:clock-value 1
|
:clock-value 1
|
||||||
:chat-id "a"})))
|
:chat-id "a"})))
|
||||||
(testing "it returns false when from is the same as pk"
|
|
||||||
(is (not (message/add-to-chat? {:db {:current-public-key "pk"
|
|
||||||
:chats {"a" {}}}}
|
|
||||||
{:message-id "message-id"
|
|
||||||
:from "pk"
|
|
||||||
:clock-value 1
|
|
||||||
:chat-id "a"}))))
|
|
||||||
(testing "it returns false when it's already in the loaded message"
|
(testing "it returns false when it's already in the loaded message"
|
||||||
(is (not (message/add-to-chat? {:db {:chats {"a" {:messages {"message-id" {}}}}}}
|
(is (not (message/add-to-chat? {:db {:chats {"a" {:messages {"message-id" {}}}}}}
|
||||||
{:message-id "message-id"
|
{:message-id "message-id"
|
||||||
@ -49,6 +42,34 @@
|
|||||||
:clock-value 0
|
:clock-value 0
|
||||||
:chat-id "a"})))))
|
:chat-id "a"})))))
|
||||||
|
|
||||||
|
(deftest add-own-received-message
|
||||||
|
(let [db {:current-public-key "me"
|
||||||
|
:view-id :chat
|
||||||
|
:current-chat-id "chat-id"
|
||||||
|
:chats {"chat-id" {:messages {}}}}]
|
||||||
|
(testing "a message coming from you!"
|
||||||
|
(let [actual (message/receive
|
||||||
|
{:from "me"
|
||||||
|
:message-id "id"
|
||||||
|
:chat-id "chat-id"
|
||||||
|
:content "b"
|
||||||
|
:clock-value 1}
|
||||||
|
{:db db})
|
||||||
|
message (get-in actual [:db :chats "chat-id" :messages "id"])
|
||||||
|
status (get-in actual [:db :chats "chat-id" :message-statuses "id" "me" :status])]
|
||||||
|
(testing "it adds the message"
|
||||||
|
(is message))
|
||||||
|
(testing "it marks the message as outgoing"
|
||||||
|
(is (= true (:outgoing message))))
|
||||||
|
(testing "it confirm the message as processed"
|
||||||
|
(is (:confirm-messages-processed actual)))
|
||||||
|
(testing "it stores the message"
|
||||||
|
(is (:data-store/tx actual)))
|
||||||
|
(testing "it does not send a seen confirmation"
|
||||||
|
(is (not (:shh/post actual))))
|
||||||
|
(testing "it marks it as sent"
|
||||||
|
(is (= :sent status)))))))
|
||||||
|
|
||||||
(deftest receive-send-seen
|
(deftest receive-send-seen
|
||||||
(let [db {:db {:chats {"chat-id" {}}
|
(let [db {:db {:chats {"chat-id" {}}
|
||||||
:account/account {:public-key "a"}
|
:account/account {:public-key "a"}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
[status-im.models.contact :as model]))
|
[status-im.models.contact :as model]))
|
||||||
|
|
||||||
|
(def public-key "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917")
|
||||||
|
(def address "71adb0644e2b590e37dafdfea8bd58f0c7668c7f")
|
||||||
|
|
||||||
(deftest can-add-to-contact-test
|
(deftest can-add-to-contact-test
|
||||||
(testing "a user is already in contacts"
|
(testing "a user is already in contacts"
|
||||||
(is (not (model/can-add-to-contacts? {:pending? false}))))
|
(is (not (model/can-add-to-contacts? {:pending? false}))))
|
||||||
@ -16,3 +19,123 @@
|
|||||||
(is (model/can-add-to-contacts? {})))
|
(is (model/can-add-to-contacts? {})))
|
||||||
(testing "a dapp"
|
(testing "a dapp"
|
||||||
(is (not (model/can-add-to-contacts? {:dapp? true}))))))
|
(is (not (model/can-add-to-contacts? {:dapp? true}))))))
|
||||||
|
|
||||||
|
(deftest handle-contact-update-test
|
||||||
|
(testing "the contact is not in contacts"
|
||||||
|
(let [actual (model/handle-contact-update
|
||||||
|
public-key
|
||||||
|
1
|
||||||
|
{:name "name"
|
||||||
|
:profile-image "image"
|
||||||
|
:address "address"
|
||||||
|
:fcm-token "token"}
|
||||||
|
{})
|
||||||
|
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||||
|
(testing "it stores the contact in the database"
|
||||||
|
(is (:data-store/tx actual)))
|
||||||
|
(testing "it adds a new contact with pending? true"
|
||||||
|
(is (= {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "image"
|
||||||
|
:name "name"
|
||||||
|
:last-updated 1000
|
||||||
|
:pending? true
|
||||||
|
:fcm-token "token"
|
||||||
|
:address "address"} contact)))))
|
||||||
|
(testing "the contact is already in contacts"
|
||||||
|
(testing "timestamp is greather than last-updated"
|
||||||
|
(let [actual (model/handle-contact-update
|
||||||
|
public-key
|
||||||
|
1
|
||||||
|
{:name "new-name"
|
||||||
|
:profile-image "new-image"
|
||||||
|
:address "new-address"
|
||||||
|
:fcm-token "new-token"}
|
||||||
|
{:db {:contacts/contacts
|
||||||
|
{public-key {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "old-image"
|
||||||
|
:name "old-name"
|
||||||
|
:last-updated 0
|
||||||
|
:pending? false
|
||||||
|
:fcm-token "old-token"
|
||||||
|
:address "old-address"}}}})
|
||||||
|
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||||
|
(testing "it stores the contact in the database"
|
||||||
|
(is (:data-store/tx actual)))
|
||||||
|
(testing "it updates the contact leaving pending unchanged"
|
||||||
|
(is (= {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "new-image"
|
||||||
|
:name "new-name"
|
||||||
|
:last-updated 1000
|
||||||
|
:pending? false
|
||||||
|
:fcm-token "new-token"
|
||||||
|
:address "new-address"} contact)))))
|
||||||
|
(testing "timestamp is equal than last-updated"
|
||||||
|
(let [actual (model/handle-contact-update
|
||||||
|
public-key
|
||||||
|
1
|
||||||
|
{:name "new-name"
|
||||||
|
:profile-image "new-image"
|
||||||
|
:address "new-address"
|
||||||
|
:fcm-token "new-token"}
|
||||||
|
{:db {:contacts/contacts
|
||||||
|
{public-key {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "old-image"
|
||||||
|
:name "old-name"
|
||||||
|
:last-updated 1000
|
||||||
|
:pending? false
|
||||||
|
:fcm-token "old-token"
|
||||||
|
:address "old-address"}}}})
|
||||||
|
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||||
|
(testing "it does nothing"
|
||||||
|
(is (nil? actual)))))
|
||||||
|
(testing "timestamp is less than last-updated"
|
||||||
|
(let [actual (model/handle-contact-update
|
||||||
|
public-key
|
||||||
|
0
|
||||||
|
{:name "new-name"
|
||||||
|
:profile-image "new-image"
|
||||||
|
:address "new-address"
|
||||||
|
:fcm-token "new-token"}
|
||||||
|
{:db {:contacts/contacts
|
||||||
|
{public-key {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "old-image"
|
||||||
|
:name "old-name"
|
||||||
|
:last-updated 1000
|
||||||
|
:pending? false
|
||||||
|
:fcm-token "old-token"
|
||||||
|
:address "old-address"}}}})
|
||||||
|
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||||
|
(testing "it does nothing"
|
||||||
|
(is (nil? actual))))))
|
||||||
|
(testing "backward compatibility"
|
||||||
|
(let [actual (model/handle-contact-update
|
||||||
|
public-key
|
||||||
|
1
|
||||||
|
{:name "new-name"
|
||||||
|
:profile-image "new-image"}
|
||||||
|
{:db {:contacts/contacts
|
||||||
|
{public-key {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "old-image"
|
||||||
|
:name "old-name"
|
||||||
|
:last-updated 0
|
||||||
|
:pending? false}}}})
|
||||||
|
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||||
|
(testing "it stores the contact in the database"
|
||||||
|
(is (:data-store/tx actual)))
|
||||||
|
(testing "it updates the contact leaving pending unchanged"
|
||||||
|
(is (= {:whisper-identity public-key
|
||||||
|
:public-key public-key
|
||||||
|
:photo-path "new-image"
|
||||||
|
:name "new-name"
|
||||||
|
:last-updated 1000
|
||||||
|
:pending? false
|
||||||
|
:address address} contact)))))
|
||||||
|
(testing "the message is coming from us"
|
||||||
|
(testing "it does not update contacts"
|
||||||
|
(is (nil? (model/handle-contact-update "me" 1 {} {:db {:current-public-key "me"}}))))))
|
||||||
|
@ -77,29 +77,32 @@
|
|||||||
:sym-key-id "something"
|
:sym-key-id "something"
|
||||||
:password "wnode-password"}}}
|
:password "wnode-password"}}}
|
||||||
:account/account
|
:account/account
|
||||||
{:networks {"mainnet" {:config {:NetworkId 1}}}}}
|
{:networks {"mainnet" {:config {:NetworkId 1}}}}
|
||||||
|
:transport/chats
|
||||||
|
{:dont-fetch-history {:topic "dont-fetch-history"}
|
||||||
|
:fetch-history {:topic "fetch-history"
|
||||||
|
:fetch-history? true}}}
|
||||||
cofx {:db db :now 1000000000}]
|
cofx {:db db :now 1000000000}]
|
||||||
(testing "inbox is ready"
|
(testing "inbox is ready"
|
||||||
(testing "last-request is set"
|
(testing "last request is > the 7 days ago"
|
||||||
(testing "last request is > the 7 days ago"
|
(let [cofx-with-last-request (assoc-in cofx [:db :account/account :last-request] 400000)
|
||||||
(let [cofx-with-last-request (assoc-in cofx [:db :account/account :last-request] 400000)
|
|
||||||
actual (inbox/request-messages cofx-with-last-request)]
|
|
||||||
(testing "it uses last request"
|
|
||||||
(is (= 400000 (get-in actual [::inbox/request-messages :from]))))))
|
|
||||||
(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)]
|
|
||||||
(testing "it uses last 7 days"
|
|
||||||
(is (= 395200 (get-in actual [::inbox/request-messages :from])))))))
|
|
||||||
(testing "last-request is not set"
|
|
||||||
(let [actual (inbox/request-messages cofx)]
|
|
||||||
(testing "it defaults to the last 7 days"
|
|
||||||
(is (= 395200 (get-in actual [::inbox/request-messages :from]))))))
|
|
||||||
(testing "last-request is nil"
|
|
||||||
(let [cofx-with-last-request (assoc-in cofx [:db :account/account :last-request] nil)
|
|
||||||
actual (inbox/request-messages cofx-with-last-request)]
|
actual (inbox/request-messages cofx-with-last-request)]
|
||||||
(testing "it defaults to the last 7 days"
|
(testing "it uses last request"
|
||||||
(is (= 395200 (get-in actual [::inbox/request-messages :from])))))))
|
(is (= 400000 (get-in actual [::inbox/request-messages 0 :from]))))))
|
||||||
|
(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)]
|
||||||
|
(testing "it uses last 7 days for catching up"
|
||||||
|
(is (= 395200 (get-in actual [::inbox/request-messages 0 :from]))))
|
||||||
|
(testing "it only uses topics that dont have fetch history set"
|
||||||
|
(is (= ["0xf8946aac" "dont-fetch-history"]
|
||||||
|
(get-in actual [::inbox/request-messages 0 :topics]))))
|
||||||
|
(testing "it uses the last 24 hours to request history"
|
||||||
|
(is (= 913600
|
||||||
|
(get-in actual [::inbox/request-messages 1 :from]))))
|
||||||
|
(testing "it fetches the right topic for history"
|
||||||
|
(is (= ["fetch-history"]
|
||||||
|
(get-in actual [::inbox/request-messages 1 :topics])))))))
|
||||||
(testing "inbox is not ready"
|
(testing "inbox is not ready"
|
||||||
(testing "it does not do anything"
|
(testing "it does not do anything"
|
||||||
(is (nil? (inbox/request-messages {})))))))
|
(is (nil? (inbox/request-messages {})))))))
|
||||||
@ -159,3 +162,29 @@
|
|||||||
:from 86400
|
:from 86400
|
||||||
:to 90000}}
|
:to 90000}}
|
||||||
(into #{} (inbox/request-inbox-messages-params mailserver 0 90000 ["a" "b"])))))))
|
(into #{} (inbox/request-inbox-messages-params mailserver 0 90000 ["a" "b"])))))))
|
||||||
|
|
||||||
|
(deftest initialize-offline-inbox
|
||||||
|
(let [db {:network "mainnet"
|
||||||
|
:mailserver-status :connected
|
||||||
|
:inbox/current-id "wnodeid"
|
||||||
|
:inbox/wnodes
|
||||||
|
{:mainnet {"wnodeid" {:address "wnode-address"
|
||||||
|
:sym-key-id "something"
|
||||||
|
:password "wnode-password"}}}
|
||||||
|
:account/account
|
||||||
|
{:networks {"mainnet" {:config {:NetworkId 1}}}}}]
|
||||||
|
(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])))))))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user