Move messages to status-go
This commit does a few things: 1) Move messages to status-go 2) Use message-id computed from status-go 3) Remove old replies Old message id was used for compatibility of replies with older clients. Given that v1 is breaking, this is not needed anymore and simplifies moving messages to status-go. No protocol/data-store change is made, to minimize changes. Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
b67eda9bc3
commit
dcb7415208
|
@ -5,6 +5,7 @@
|
|||
[status-im.chat.commands.impl.transactions.styles
|
||||
:as
|
||||
transactions-styles]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.chat.commands.protocol :as protocol]
|
||||
[status-im.data-store.messages :as messages-store]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
|
@ -287,13 +288,14 @@
|
|||
;; Only superficial/formatting validation, "real validation" will be performed
|
||||
;; by the wallet, where we yield control in the next step
|
||||
(personal-send-request-validation parameters cofx))
|
||||
(on-send [_ {:keys [chat-id] :as send-message} {:keys [db]}]
|
||||
(on-send [_ {:keys [chat-id] :as send-message} {:keys [db] :as cofx}]
|
||||
(when-let [responding-to (get-in db [:chats chat-id :metadata :responding-to-command])]
|
||||
(when-let [request-message (get-in db [:chats chat-id :messages responding-to])]
|
||||
(when (params-unchanged? send-message request-message)
|
||||
(let [updated-request-message (assoc-in request-message [:content :params :answered?] true)]
|
||||
{:db (assoc-in db [:chats chat-id :messages responding-to] updated-request-message)
|
||||
:data-store/tx [(messages-store/save-message-tx updated-request-message)]})))))
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:chats chat-id :messages responding-to] updated-request-message)}
|
||||
(messages-store/save-message updated-request-message)))))))
|
||||
(on-receive [_ command-message cofx])
|
||||
(short-preview [_ command-message]
|
||||
(personal-send-request-short-preview :command-sending command-message))
|
||||
|
|
|
@ -62,9 +62,8 @@
|
|||
|
||||
(defn quoted-message-data
|
||||
"Selects certain data from quoted message which must be available in the view"
|
||||
[message-id messages referenced-messages]
|
||||
(when-let [{:keys [from content]} (get messages message-id
|
||||
(get referenced-messages message-id))]
|
||||
[message-id messages]
|
||||
(when-let [{:keys [from content]} (get messages message-id)]
|
||||
{:from from
|
||||
:text (:text content)}))
|
||||
|
||||
|
@ -85,15 +84,17 @@
|
|||
(= type :gap))
|
||||
|
||||
(defn transform-message
|
||||
[messages referenced-messages]
|
||||
[messages]
|
||||
(fn [{:keys [message-id timestamp-str] :as reference}]
|
||||
(if (or (datemark? reference)
|
||||
(gap? reference))
|
||||
reference
|
||||
(let [{:keys [content] :as message} (get messages message-id)
|
||||
(let [{:keys [content quoted-message] :as message} (get messages message-id)
|
||||
{:keys [response-to response-to-v2]} content
|
||||
quote (some-> (or response-to-v2 response-to)
|
||||
(quoted-message-data messages referenced-messages))]
|
||||
quote (if quoted-message
|
||||
quoted-message
|
||||
(some-> (or response-to-v2 response-to)
|
||||
(quoted-message-data messages)))]
|
||||
(cond-> (-> message
|
||||
(update :content dissoc :response-to :response-to-v2)
|
||||
(assoc :timestamp-str timestamp-str))
|
||||
|
@ -139,12 +140,12 @@
|
|||
(defn messages-with-datemarks
|
||||
"Converts message groups into sequence of messages interspersed with datemarks,
|
||||
with correct user statuses associated into message"
|
||||
[message-groups messages referenced-messages messages-gaps
|
||||
[message-groups messages messages-gaps
|
||||
{:keys [highest-request-to lowest-request-from]} all-loaded? public?]
|
||||
(transduce
|
||||
(comp
|
||||
(mapcat add-datemark)
|
||||
(map (transform-message messages referenced-messages)))
|
||||
(map (transform-message messages)))
|
||||
(fn
|
||||
([]
|
||||
(let [acc {:messages (list)
|
||||
|
|
|
@ -147,8 +147,8 @@
|
|||
:last-message-content nil
|
||||
:last-message-content-type nil
|
||||
:unviewed-messages-count 0
|
||||
:deleted-at-clock-value last-message-clock-value})
|
||||
:data-store/tx [(messages-store/delete-chat-messages-tx chat-id)]}
|
||||
:deleted-at-clock-value last-message-clock-value})}
|
||||
(messages-store/delete-messages-by-chat-id chat-id)
|
||||
#(chats-store/save-chat-rpc % (get-in % [:db :chats chat-id])))))
|
||||
|
||||
(fx/defn deactivate-chat
|
||||
|
@ -207,27 +207,21 @@
|
|||
(max 0 (- old-count (count new-seen-messages-ids))))
|
||||
|
||||
(fx/defn update-chats-unviewed-messages-count
|
||||
[{:keys [db] :as cofx} {:keys [chat-id new-loaded-unviewed-messages-ids]}]
|
||||
[{:keys [db] :as cofx} {:keys [chat-id loaded-unviewed-messages-ids]}]
|
||||
(let [{:keys [loaded-unviewed-messages-ids unviewed-messages-count]}
|
||||
(get-in db [:chats chat-id])
|
||||
|
||||
unviewed-messages-ids (if (seq new-loaded-unviewed-messages-ids)
|
||||
new-loaded-unviewed-messages-ids
|
||||
loaded-unviewed-messages-ids)]
|
||||
(get-in db [:chats chat-id])]
|
||||
(upsert-chat
|
||||
cofx
|
||||
{:chat-id chat-id
|
||||
:unviewed-messages-count (subtract-seen-messages
|
||||
unviewed-messages-count
|
||||
unviewed-messages-ids)
|
||||
loaded-unviewed-messages-ids)
|
||||
:loaded-unviewed-messages-ids #{}})))
|
||||
|
||||
;; TODO (janherich) - ressurect `constants/system` messages for group chats in the future
|
||||
(fx/defn mark-messages-seen
|
||||
"Marks all unviewed loaded messages as seen in particular chat"
|
||||
[{:keys [db] :as cofx} chat-id]
|
||||
(let [public-key (multiaccounts.model/current-public-key cofx)
|
||||
loaded-unviewed-ids (get-in db [:chats chat-id :loaded-unviewed-messages-ids])]
|
||||
(let [loaded-unviewed-ids (get-in db [:chats chat-id :loaded-unviewed-messages-ids])]
|
||||
(when (seq loaded-unviewed-ids)
|
||||
(fx/merge cofx
|
||||
{:db (reduce (fn [acc message-id]
|
||||
|
@ -235,8 +229,8 @@
|
|||
message-id :seen]
|
||||
true))
|
||||
db
|
||||
loaded-unviewed-ids)
|
||||
:data-store/tx [(messages-store/mark-messages-seen-tx loaded-unviewed-ids)]}
|
||||
loaded-unviewed-ids)}
|
||||
(messages-store/mark-messages-seen loaded-unviewed-ids)
|
||||
(update-chats-unviewed-messages-count {:chat-id chat-id})
|
||||
(when platform/desktop?
|
||||
(update-dock-badge-label))))))
|
||||
|
|
|
@ -87,12 +87,11 @@
|
|||
|
||||
(fx/defn reply-to-message
|
||||
"Sets reference to previous chat message and focuses on input"
|
||||
[{:keys [db] :as cofx} message-id old-message-id]
|
||||
[{:keys [db] :as cofx} message-id]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message]
|
||||
{:message-id message-id
|
||||
:old-message-id old-message-id})}
|
||||
{:message-id message-id})}
|
||||
(chat-input-focus :input-ref))))
|
||||
|
||||
(fx/defn cancel-message-reply
|
||||
|
@ -123,7 +122,7 @@
|
|||
"no command detected, when not empty, proceed by sending text message without command processing"
|
||||
[input-text current-chat-id {:keys [db] :as cofx}]
|
||||
(when-not (string/blank? input-text)
|
||||
(let [{:keys [message-id old-message-id]}
|
||||
(let [{:keys [message-id]}
|
||||
(get-in db [:chats current-chat-id :metadata :responding-to-message])
|
||||
show-name? (get-in db [:multiaccount :show-name?])
|
||||
preferred-name (when show-name? (get-in db [:multiaccount :preferred-name]))]
|
||||
|
@ -134,8 +133,7 @@
|
|||
:content (cond-> {:chat-id current-chat-id
|
||||
:text input-text}
|
||||
message-id
|
||||
(assoc :response-to old-message-id
|
||||
:response-to-v2 message-id)
|
||||
(assoc :response-to-v2 message-id)
|
||||
preferred-name
|
||||
(assoc :name preferred-name))})
|
||||
(commands.input/set-command-reference nil)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(ns status-im.chat.models.loading
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.data-store.chats :as data-store.chats]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.chat.commands.core :as commands]
|
||||
[status-im.transport.filters.core :as filters]
|
||||
[status-im.chat.models :as chat-model]
|
||||
|
@ -43,13 +45,13 @@
|
|||
|
||||
(defn- get-referenced-ids
|
||||
"Takes map of `message-id->messages` and returns set of maps of
|
||||
`{:response-to old-message-id :response-to-v2 message-id}`,
|
||||
`{:response-to-v2 message-id}`,
|
||||
excluding any `message-id` which is already in the original map"
|
||||
[message-id->messages]
|
||||
(into #{}
|
||||
(comp (keep (fn [{:keys [content]}]
|
||||
(let [response-to-id
|
||||
(select-keys content [:response-to :response-to-v2])]
|
||||
(select-keys content [:response-to-v2])]
|
||||
(when (some (complement nil?) (vals response-to-id))
|
||||
response-to-id))))
|
||||
(remove #(some message-id->messages (vals %))))
|
||||
|
@ -63,7 +65,6 @@
|
|||
(assoc acc chat-id
|
||||
(assoc chat
|
||||
:messages-initialized? false
|
||||
:referenced-messages {}
|
||||
:messages empty-message-map)))
|
||||
{}
|
||||
new-chats)
|
||||
|
@ -87,41 +88,47 @@
|
|||
{:keys [from to] :or {from 0 to nil}}]
|
||||
(load-chats-from-rpc cofx from -1))
|
||||
|
||||
(defn load-more-messages
|
||||
(fx/defn messages-loaded
|
||||
"Loads more messages for current chat"
|
||||
[{{:keys [current-chat-id] :as db} :db
|
||||
get-stored-messages :get-stored-messages
|
||||
get-referenced-messages :get-referenced-messages
|
||||
get-unviewed-message-ids :get-unviewed-message-ids :as cofx}]
|
||||
;; TODO: re-implement functionality for status-go protocol
|
||||
(when-not (or config/use-status-go-protocol?
|
||||
(nil? current-chat-id)
|
||||
(get-in db [:chats current-chat-id :all-loaded?]))
|
||||
(let [previous-pagination-info (get-in db [:chats current-chat-id :pagination-info])
|
||||
{:keys [messages
|
||||
pagination-info
|
||||
all-loaded?]} (get-stored-messages current-chat-id previous-pagination-info)
|
||||
already-loaded-messages (get-in db [:chats current-chat-id :messages])
|
||||
{:events [::messages-loaded]
|
||||
:interceptors [(re-frame/inject-cofx :data-store/all-gaps)]}
|
||||
[{{:keys [current-chat-id] :as db} :db :as cofx}
|
||||
chat-id
|
||||
{:keys [cursor messages]}]
|
||||
(when-not (or (nil? current-chat-id)
|
||||
(not= chat-id current-chat-id))
|
||||
(let [already-loaded-messages (get-in db [:chats current-chat-id :messages])
|
||||
;; We remove those messages that are already loaded, as we might get some duplicates
|
||||
new-messages (remove (comp already-loaded-messages :message-id)
|
||||
messages)
|
||||
unviewed-message-ids (reduce
|
||||
(fn [acc {:keys [seen message-id] :as message}]
|
||||
(if (not seen)
|
||||
(conj acc message-id)
|
||||
acc))
|
||||
#{}
|
||||
new-messages)
|
||||
|
||||
indexed-messages (index-messages new-messages)
|
||||
referenced-messages (into empty-message-map
|
||||
(get-referenced-messages (get-referenced-ids indexed-messages)))
|
||||
new-message-ids (keys indexed-messages)
|
||||
loaded-unviewed-messages (get-unviewed-message-ids)]
|
||||
new-message-ids (keys indexed-messages)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update-in [:chats current-chat-id :loaded-unviewed-messages-ids] clojure.set/union unviewed-message-ids)
|
||||
(assoc-in [:chats current-chat-id :messages-initialized?] true)
|
||||
(update-in [:chats current-chat-id :messages] merge indexed-messages)
|
||||
(update-in [:chats current-chat-id :referenced-messages]
|
||||
#(into (apply dissoc % new-message-ids) referenced-messages))
|
||||
(assoc-in [:chats current-chat-id :pagination-info] pagination-info)
|
||||
(assoc-in [:chats current-chat-id :cursor] cursor)
|
||||
(assoc-in [:chats current-chat-id :all-loaded?]
|
||||
all-loaded?))}
|
||||
(chat-model/update-chats-unviewed-messages-count
|
||||
{:chat-id current-chat-id
|
||||
:new-loaded-unviewed-messages-ids loaded-unviewed-messages})
|
||||
(empty? cursor)))}
|
||||
(mailserver/load-gaps current-chat-id)
|
||||
(group-chat-messages current-chat-id new-messages)
|
||||
(chat-model/mark-messages-seen current-chat-id)))))
|
||||
|
||||
(defn load-more-messages
|
||||
[{:keys [db]}]
|
||||
(when-let [current-chat-id (:current-chat-id db)]
|
||||
(when-not (get-in db [:chats current-chat-id :all-loaded?])
|
||||
(let [cursor (get-in db [:chats current-chat-id :cursor])]
|
||||
(data-store.messages/messages-by-chat-id-rpc current-chat-id
|
||||
cursor
|
||||
constants/default-number-of-messages
|
||||
#(re-frame/dispatch [::messages-loaded current-chat-id %]))))))
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
(fx/defn add-message
|
||||
[{:keys [db] :as cofx}
|
||||
{{:keys [chat-id message-id clock-value timestamp from] :as message} :message
|
||||
:keys [current-chat? batch? dedup-id raw-message]}]
|
||||
:keys [current-chat? batch? metadata raw-message]}]
|
||||
(let [current-public-key (multiaccounts.model/current-public-key cofx)
|
||||
prepared-message (-> message
|
||||
(prepare-message chat-id current-chat?)
|
||||
|
@ -126,12 +126,8 @@
|
|||
(and (not current-chat?)
|
||||
(not= from current-public-key))
|
||||
(update-in [:chats chat-id :loaded-unviewed-messages-ids]
|
||||
(fnil conj #{}) message-id))
|
||||
:data-store/tx [(merge
|
||||
{:transaction (messages-store/save-message-tx prepared-message)}
|
||||
(when (or dedup-id raw-message)
|
||||
{:success-event
|
||||
[:message/messages-persisted [(or dedup-id raw-message)]]}))]}
|
||||
(fnil conj #{}) message-id))}
|
||||
#(messages-store/save-message % prepared-message)
|
||||
(when (and platform/desktop?
|
||||
(not batch?)
|
||||
(not (system-message? prepared-message)))
|
||||
|
@ -146,20 +142,9 @@
|
|||
message
|
||||
(assoc message :clock-value (utils.clocks/send last-clock-value))))
|
||||
|
||||
(defn check-response-to
|
||||
[{{:keys [response-to response-to-v2]} :content :as message}
|
||||
old-id->message]
|
||||
(if (and response-to (not response-to-v2))
|
||||
(let [response-to-v2
|
||||
(or (get-in old-id->message [response-to :message-id])
|
||||
(messages-store/get-message-id-by-old response-to))]
|
||||
(assoc-in message [:content :response-to-v2] response-to-v2))
|
||||
message))
|
||||
|
||||
(fx/defn add-received-message
|
||||
[{:keys [db] :as cofx}
|
||||
old-id->message
|
||||
{:keys [from message-id chat-id js-obj content dedup-id] :as raw-message}]
|
||||
{:keys [from message-id chat-id js-obj content metadata] :as raw-message}]
|
||||
(let [{:keys [web3 current-chat-id view-id]} db
|
||||
current-public-key (multiaccounts.model/current-public-key cofx)
|
||||
current-chat? (and (or (= :chat view-id)
|
||||
|
@ -169,13 +154,12 @@
|
|||
{:keys [outgoing] :as message} (-> raw-message
|
||||
(commands-receiving/enhance-receive-parameters cofx)
|
||||
(ensure-clock-value chat)
|
||||
(check-response-to old-id->message)
|
||||
;; TODO (cammellos): Refactor so it's not computed twice
|
||||
(add-outgoing-status current-public-key))]
|
||||
(fx/merge cofx
|
||||
(add-message {:batch? true
|
||||
:message message
|
||||
:dedup-id dedup-id
|
||||
:metadata metadata
|
||||
:current-chat current-chat?
|
||||
:raw-message js-obj})
|
||||
(commands-receiving/receive message))))
|
||||
|
@ -190,27 +174,22 @@
|
|||
(let [{:keys [deleted-at-clock-value messages]}
|
||||
(get-in db [:chats chat-id])]
|
||||
(not (or (get messages message-id)
|
||||
(>= deleted-at-clock-value clock-value)
|
||||
(messages-store/message-exists? message-id)))))
|
||||
(>= deleted-at-clock-value clock-value)))))
|
||||
|
||||
(defn- filter-messages [cofx messages]
|
||||
(:accumulated
|
||||
(reduce (fn [{:keys [seen-ids] :as acc}
|
||||
{:keys [message-id old-message-id] :as message}]
|
||||
{:keys [message-id] :as message}]
|
||||
(if (and (add-to-chat? cofx message)
|
||||
(not (seen-ids message-id)))
|
||||
(-> acc
|
||||
(update :seen-ids conj message-id)
|
||||
(update :accumulated
|
||||
(fn [acc]
|
||||
(-> acc
|
||||
(update :messages conj message)
|
||||
(assoc-in [:by-old-message-id old-message-id]
|
||||
message)))))
|
||||
(update acc :messages conj message))))
|
||||
acc))
|
||||
{:seen-ids #{}
|
||||
:accumulated {:messages []
|
||||
:by-old-message-id {}}}
|
||||
:accumulated {:messages []}}
|
||||
messages)))
|
||||
|
||||
(defn extract-chat-id [cofx {:keys [chat-id from message-type]}]
|
||||
|
@ -280,7 +259,6 @@
|
|||
(assoc % :chat-id chat-id)) messages)
|
||||
filtered-messages (filter-messages cofx valid-messages)
|
||||
deduped-messages (:messages filtered-messages)
|
||||
old-id->message (:by-old-message-id filtered-messages)
|
||||
chat->message (group-by :chat-id deduped-messages)
|
||||
chat-ids (keys chat->message)
|
||||
never-synced-public-chat-ids (chat-ids->never-synced-public-chat-ids
|
||||
|
@ -297,7 +275,7 @@
|
|||
:timestamp now
|
||||
:unviewed-messages-count unviewed-messages-count})))
|
||||
chat-ids)
|
||||
messages-fx-fns (map #(add-received-message old-id->message %) deduped-messages)
|
||||
messages-fx-fns (map add-received-message deduped-messages)
|
||||
groups-fx-fns (map #(update-group-messages chat->message %) chat-ids)]
|
||||
(apply fx/merge cofx (concat chats-fx-fns
|
||||
messages-fx-fns
|
||||
|
@ -320,7 +298,6 @@
|
|||
:content-type constants/content-type-status}]
|
||||
(assoc message
|
||||
:message-id (transport.utils/system-message-id message)
|
||||
:old-message-id "system"
|
||||
:raw-payload-hash "system")))
|
||||
|
||||
(defn group-message? [{:keys [message-type]}]
|
||||
|
@ -329,11 +306,8 @@
|
|||
;;;; Send message
|
||||
|
||||
(fx/defn send
|
||||
[{{:keys [peers-count]} :db :as cofx} chat-id message-id send-record]
|
||||
(if (zero? peers-count)
|
||||
{:dispatch-later [{:ms 10000
|
||||
:dispatch [:message/update-message-status chat-id message-id :not-sent]}]}
|
||||
(protocol/send send-record chat-id (assoc cofx :message-id message-id))))
|
||||
[{{:keys [peers-count]} :db :as cofx} chat-id message send-record]
|
||||
(protocol/send send-record chat-id (assoc cofx :message message)))
|
||||
|
||||
(defn add-message-type [message {:keys [chat-id group-chat public?]}]
|
||||
(cond-> message
|
||||
|
@ -354,21 +328,21 @@
|
|||
(get-in message [:content :params :coin :icon :source])
|
||||
(update-in [:content :params :coin] dissoc :icon)))
|
||||
|
||||
(fx/defn add-message-with-id [cofx message chat-id]
|
||||
(when (and message
|
||||
(not (get-in cofx [:db :chats chat-id :messages (:message-id message)])))
|
||||
(add-message cofx {:batch? false
|
||||
:message message
|
||||
:current-chat? (= (get-in cofx [:db :current-chat-id]) chat-id)})))
|
||||
|
||||
(fx/defn upsert-and-send
|
||||
[{:keys [now] :as cofx} {:keys [chat-id from] :as message}]
|
||||
(let [message (remove-icon message)
|
||||
send-record (protocol/map->Message (select-keys message transport-keys))
|
||||
old-message-id (transport.utils/old-message-id send-record)
|
||||
wrapped-record (if (= (:message-type send-record) :group-user-message)
|
||||
(wrap-group-message cofx chat-id send-record)
|
||||
send-record)
|
||||
raw-payload (ethereum/utf8-to-hex (transit/serialize wrapped-record))
|
||||
message-id (transport.utils/message-id from raw-payload)
|
||||
message-with-id (assoc message
|
||||
:outgoing-status :sending
|
||||
:message-id message-id
|
||||
:old-message-id old-message-id
|
||||
:raw-payload-hash (ethereum/sha3 raw-payload))]
|
||||
message (assoc message :outgoing-status :sending)]
|
||||
|
||||
(fx/merge cofx
|
||||
(chat-model/upsert-chat
|
||||
|
@ -377,10 +351,7 @@
|
|||
:last-message-content (:content message)
|
||||
:last-message-content-type (:content-type message)
|
||||
:last-clock-value (:clock-value message)})
|
||||
(add-message {:batch? false
|
||||
:message message-with-id
|
||||
:current-chat? true})
|
||||
(send chat-id message-id wrapped-record))))
|
||||
(send chat-id message wrapped-record))))
|
||||
|
||||
(fx/defn send-push-notification
|
||||
[cofx chat-id message-id fcm-tokens status]
|
||||
|
@ -393,11 +364,12 @@
|
|||
:tokens fcm-tokens}})))
|
||||
|
||||
(fx/defn update-message-status
|
||||
[{:keys [db]} chat-id message-id status]
|
||||
{:db (assoc-in db
|
||||
[:chats chat-id :messages message-id :outgoing-status]
|
||||
status)
|
||||
:data-store/tx [(messages-store/update-outgoing-status-tx message-id status)]})
|
||||
[{:keys [db] :as cofx} chat-id message-id status]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:chats chat-id :messages message-id :outgoing-status]
|
||||
status)}
|
||||
(messages-store/update-outgoing-status message-id status)))
|
||||
|
||||
(fx/defn resend-message
|
||||
[cofx chat-id message-id]
|
||||
|
@ -432,8 +404,8 @@
|
|||
"Deletes chat message, along its occurence in all references, like `:message-groups`"
|
||||
[{:keys [db] :as cofx} chat-id message-id]
|
||||
(fx/merge cofx
|
||||
{:db (update-in db [:chats chat-id :messages] dissoc message-id)
|
||||
:data-store/tx [(messages-store/delete-message-tx message-id)]}
|
||||
{:db (update-in db [:chats chat-id :messages] dissoc message-id)}
|
||||
(messages-store/delete-message message-id)
|
||||
(remove-message-from-group chat-id (get-in db [:chats chat-id :messages message-id]))))
|
||||
|
||||
(fx/defn add-system-messages [cofx messages]
|
||||
|
@ -463,9 +435,8 @@
|
|||
{:db (update-in db [:chats chat-id :messages message-id :expanded?] not)})
|
||||
|
||||
(fx/defn confirm-message-processed
|
||||
[{:keys [db]} raw-message]
|
||||
{:transport/confirm-messages-processed [{:web3 (:web3 db)
|
||||
:js-obj raw-message}]})
|
||||
[_ raw-message]
|
||||
{:transport/confirm-messages-processed [raw-message]})
|
||||
|
||||
;; effects
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
|
||||
(defn emoji-only-content?
|
||||
"Determines if text is just an emoji"
|
||||
[{:keys [text response-to]}]
|
||||
(and (not response-to)
|
||||
[{:keys [text response-to-v2]}]
|
||||
(and (not response-to-v2)
|
||||
(string? text)
|
||||
(re-matches constants/regx-emoji text)))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[status-im.chat.models.loading :as chat.models.loading]
|
||||
[status-im.chat.models.message :as chat.models.message]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
|
@ -16,51 +17,49 @@
|
|||
(navigation/navigate-to-cofx :home {})))
|
||||
|
||||
(fx/defn clean-up-chat
|
||||
[{:keys [db] :as cofx} chat-id removed-chat-messages]
|
||||
(let [removed-messages-ids (map :message-id removed-chat-messages)
|
||||
removed-unseen-count (count (remove :seen removed-chat-messages))
|
||||
unviewed-messages-count (- (get-in db [:chats chat-id :unviewed-messages-count])
|
||||
removed-unseen-count)
|
||||
[{:keys [db] :as cofx}
|
||||
public-key
|
||||
{:keys [chat-id
|
||||
unviewed-messages-count
|
||||
last-message-content
|
||||
last-message-content-type]}]
|
||||
(let [removed-messages-ids (keep
|
||||
(fn [[message-id {:keys [from]}]]
|
||||
(when (= from public-key)
|
||||
message-id))
|
||||
(get-in db [:chats chat-id :messages]))
|
||||
db (-> db
|
||||
;; remove messages
|
||||
(update-in [:chats chat-id :messages]
|
||||
#(apply dissoc % removed-messages-ids))
|
||||
;; remove message groups
|
||||
(update-in [:chats chat-id]
|
||||
dissoc :message-groups))]
|
||||
dissoc :message-groups)
|
||||
(update-in [:chats chat-id]
|
||||
assoc
|
||||
:unviewed-messages-count unviewed-messages-count
|
||||
:last-message-content last-message-content
|
||||
:last-message-content-type last-message-content-type))]
|
||||
(fx/merge cofx
|
||||
{:db db}
|
||||
;; update unviewed messages count
|
||||
(chat.models/upsert-chat
|
||||
{:chat-id chat-id
|
||||
:unviewed-messages-count
|
||||
(if (pos? unviewed-messages-count)
|
||||
unviewed-messages-count
|
||||
0)})
|
||||
;; recompute message group
|
||||
(chat.models.loading/group-chat-messages
|
||||
chat-id
|
||||
(vals (get-in db [:chats chat-id :messages]))))))
|
||||
|
||||
(fx/defn clean-up-chats
|
||||
[cofx removed-messages-by-chat]
|
||||
(apply fx/merge cofx
|
||||
(map (fn [[chat-id messages]]
|
||||
(clean-up-chat chat-id messages))
|
||||
removed-messages-by-chat)))
|
||||
(fx/defn contact-blocked
|
||||
{:events [::contact-blocked]}
|
||||
[{:keys [db] :as cofx} {:keys [public-key]} chats]
|
||||
(let [fxs (map #(clean-up-chat public-key %) chats)]
|
||||
(apply fx/merge cofx fxs)))
|
||||
|
||||
(fx/defn block-contact
|
||||
[{:keys [db get-user-messages now] :as cofx} public-key]
|
||||
[{:keys [db now] :as cofx} public-key]
|
||||
(let [contact (-> (contact.db/public-key->contact
|
||||
(:contacts/contacts db)
|
||||
public-key)
|
||||
(assoc :last-updated now)
|
||||
(update :system-tags conj :contact/blocked))
|
||||
user-messages (get-user-messages public-key)
|
||||
user-messages-ids (map :message-id user-messages)
|
||||
;; we make sure to remove the 1-1 chat which we delete entirely
|
||||
removed-messages-by-chat (-> (group-by :chat-id user-messages)
|
||||
(dissoc public-key))
|
||||
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
|
@ -69,13 +68,8 @@
|
|||
;; update the contact in contacts list
|
||||
(assoc-in [:contacts/contacts public-key] contact)
|
||||
;; remove the 1-1 chat if it exists
|
||||
(update-in [:chats] dissoc public-key))
|
||||
:data-store/tx [(contacts-store/block-user-tx contact
|
||||
user-messages-ids)]}
|
||||
;;remove the messages from chat
|
||||
(clean-up-chats removed-messages-by-chat)
|
||||
(chat.models.message/update-last-messages
|
||||
(keys removed-messages-by-chat))
|
||||
(update-in [:chats] dissoc public-key))}
|
||||
(contacts-store/block contact #(re-frame/dispatch [::contact-blocked contact (map chats-store/<-rpc %)]))
|
||||
;; reset navigation to avoid going back to non existing one to one chat
|
||||
(if from-one-to-one-chat?
|
||||
remove-current-chat-id
|
||||
|
@ -90,7 +84,7 @@
|
|||
{:db (-> db
|
||||
(update :contacts/blocked disj public-key)
|
||||
(assoc-in [:contacts/contacts public-key] contact))}
|
||||
(contacts-store/save-contact-tx contact))))
|
||||
(contacts-store/save-contact contact))))
|
||||
|
||||
(fx/defn block-contact-confirmation
|
||||
[cofx public-key]
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
{:db (-> db
|
||||
(update-in [:contacts/contacts public-key] merge contact))}
|
||||
(transport.filters/load-contact contact)
|
||||
(contacts-store/save-contact-tx contact)))
|
||||
(contacts-store/save-contact contact)))
|
||||
|
||||
(fx/defn send-contact-request
|
||||
[{:keys [db] :as cofx} {:keys [public-key] :as contact}]
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
:group-chat-local-version :loaded-unviewed-messages-ids
|
||||
:messages-initialized? :contacts :admins :members-joined)))
|
||||
|
||||
(defn- <-rpc [chat]
|
||||
(defn <-rpc [chat]
|
||||
(-> chat
|
||||
rpc->type
|
||||
unmarshal-members
|
||||
|
@ -158,3 +158,11 @@
|
|||
:params [chat-id chat-type]
|
||||
:on-success #(log/debug "deleteed chat" chat-id chat-type)
|
||||
:on-failure #(log/error "failed to delete chat" chat-id chat-type %)}))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::delete-chat
|
||||
(fn [[chat-id chat-type]]
|
||||
(delete-chat-rpc chat-id chat-type)))
|
||||
|
||||
(fx/defn delete-chat [cofx chat-id chat-type]
|
||||
{::delete-chat [chat-id chat-type]})
|
||||
|
|
|
@ -49,21 +49,16 @@
|
|||
:last-updated :lastUpdated})))
|
||||
|
||||
(defn save-contact-rpc [{:keys [public-key] :as contact}]
|
||||
(json-rpc/call {:method "shhext_saveContact"
|
||||
:params [(->rpc contact)]
|
||||
:on-success #(log/debug "saved contact" public-key "successfuly")
|
||||
:on-failure #(log/error "failed to save contact" public-key %)}))
|
||||
{::json-rpc/call [{:method "shhext_saveContact"
|
||||
:params [(->rpc contact)]
|
||||
:on-success #(log/debug "saved contact" public-key "successfuly")
|
||||
:on-failure #(log/error "failed to save contact" public-key %)}]})
|
||||
|
||||
(defn fetch-contacts-rpc [on-success]
|
||||
(json-rpc/call {:method "shhext_contacts"
|
||||
:params []
|
||||
:on-success #(on-success (map <-rpc %))
|
||||
:on-failure #(log/error "failed to fetch contacts" %)}))
|
||||
|
||||
(defn save-contact-tx
|
||||
"Returns tx function for saving contact"
|
||||
[{:keys [public-key] :as contact}]
|
||||
(save-contact-rpc contact))
|
||||
{::json-rpc/call [{:method "shhext_contacts"
|
||||
:params []
|
||||
:on-success #(on-success (map <-rpc %))
|
||||
:on-failure #(log/error "failed to fetch contacts" %)}]})
|
||||
|
||||
(defn- get-messages-by-messages-ids
|
||||
[message-ids]
|
||||
|
@ -72,13 +67,12 @@
|
|||
(.objects "message")
|
||||
(.filtered (str "(" (core/in-query "message-id" message-ids) ")")))))
|
||||
|
||||
(defn block-user-tx
|
||||
"Returns tx function for deleting user messages"
|
||||
[{:keys [public-key] :as contact} messages-ids]
|
||||
(fn [realm]
|
||||
(data-store.chats/delete-chat-rpc public-key data-store.chats/one-to-one-chat-type)
|
||||
(save-contact-rpc contact)
|
||||
(when-let [user-messages
|
||||
(get-messages-by-messages-ids messages-ids)]
|
||||
(core/delete realm user-messages))))
|
||||
(fx/defn block [cofx contact on-success]
|
||||
{::json-rpc/call [{:method "shhext_blockContact"
|
||||
:params [(->rpc contact)]
|
||||
:on-success on-success
|
||||
:on-failure #(log/error "failed to block contact" % contact)}]})
|
||||
|
||||
(fx/defn save-contact [cofx contact]
|
||||
(save-contact-rpc contact))
|
||||
|
||||
|
|
|
@ -1,177 +1,127 @@
|
|||
(ns status-im.data-store.messages
|
||||
(:require [clojure.set :as clojure.set]
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.utils.fx :as fx]
|
||||
[clojure.string :as string]
|
||||
[taoensso.timbre :as log]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.data-store.realm.core :as core]
|
||||
[status-im.utils.core :as utils]))
|
||||
|
||||
(defn get-message-by-id
|
||||
[message-id realm]
|
||||
(.objectForPrimaryKey realm "message" message-id))
|
||||
|
||||
(defn- transform-message
|
||||
[{:keys [content outgoing-status] :as message}]
|
||||
(when-let [parsed-content (utils/safe-read-message-content content)]
|
||||
(let [outgoing-status (when-not (empty? outgoing-status)
|
||||
(keyword outgoing-status))]
|
||||
(-> message
|
||||
(update :message-type keyword)
|
||||
(assoc :content parsed-content
|
||||
:outgoing-status outgoing-status
|
||||
:outgoing outgoing-status)))))
|
||||
|
||||
(defn- exclude-messages [query message-ids]
|
||||
(let [string-queries (map #(str "message-id != \"" % "\"") message-ids)]
|
||||
(core/filtered query (string/join " AND " string-queries))))
|
||||
|
||||
(defn- get-by-chat-id
|
||||
([chat-id]
|
||||
(get-by-chat-id chat-id nil))
|
||||
([chat-id {:keys [last-clock-value message-ids]}]
|
||||
(let [messages (cond-> (core/get-by-field @core/account-realm :message :chat-id chat-id)
|
||||
:always (core/multi-field-sorted [["clock-value" true] ["message-id" true]])
|
||||
last-clock-value (core/filtered (str "clock-value <= \"" last-clock-value "\""))
|
||||
(seq message-ids) (exclude-messages message-ids)
|
||||
:always (core/page 0 constants/default-number-of-messages)
|
||||
:always (core/all-clj :message))
|
||||
clock-value (-> messages last :clock-value)
|
||||
new-message-ids (->> messages
|
||||
(filter #(= clock-value (:clock-value %)))
|
||||
(map :message-id)
|
||||
(into #{}))]
|
||||
{:all-loaded? (> constants/default-number-of-messages (count messages))
|
||||
;; We paginate using clock-value + message-id to break ties, we need
|
||||
;; to exclude previously loaded messages with identical clock value
|
||||
;; otherwise we might fetch exactly the same page if all the messages
|
||||
;; in a page have the same clock-value. The initial idea was to use a
|
||||
;; cursor clock-value-message-id but realm does not support </> operators
|
||||
;; on strings
|
||||
:pagination-info {:last-clock-value clock-value
|
||||
:message-ids (if (= clock-value last-clock-value)
|
||||
(clojure.set/union message-ids new-message-ids)
|
||||
new-message-ids)}
|
||||
:messages (keep transform-message messages)})))
|
||||
|
||||
(defn get-message-id-by-old [old-message-id]
|
||||
(when-let
|
||||
[js-message (core/single
|
||||
(core/get-by-field
|
||||
@core/account-realm
|
||||
:message :old-message-id old-message-id))]
|
||||
(aget js-message "message-id")))
|
||||
|
||||
(defn- get-references-by-ids
|
||||
[message-ids]
|
||||
(when (seq message-ids)
|
||||
(keep (fn [{:keys [response-to response-to-v2]}]
|
||||
(when-let [js-message
|
||||
(if response-to-v2
|
||||
(get-message-by-id response-to-v2 @core/account-realm)
|
||||
(core/single (core/get-by-field
|
||||
@core/account-realm
|
||||
:message :old-message-id response-to)))]
|
||||
(when-let [deserialized-message (-> js-message
|
||||
(core/realm-obj->clj :message)
|
||||
transform-message)]
|
||||
[(or response-to-v2 response-to) deserialized-message])))
|
||||
message-ids)))
|
||||
|
||||
(def default-values
|
||||
{:to nil})
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:data-store/get-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-messages get-by-chat-id)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:data-store/get-referenced-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-referenced-messages get-references-by-ids)))
|
||||
|
||||
(defn get-user-messages
|
||||
[public-key]
|
||||
(.reduce (core/get-by-field @core/account-realm
|
||||
:message :from public-key)
|
||||
(fn [acc message-object _ _]
|
||||
(conj acc
|
||||
{:message-id (aget message-object "message-id")
|
||||
:chat-id (aget message-object "chat-id")}))
|
||||
[]))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:data-store/get-user-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-user-messages get-user-messages)))
|
||||
|
||||
(defn get-unviewed-message-ids
|
||||
[]
|
||||
(.reduce (core/get-by-field @core/account-realm
|
||||
:message :seen false)
|
||||
(fn [acc message-object _ _]
|
||||
(aget message-object "message-id"))
|
||||
[]))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:data-store/get-unviewed-message-ids
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-unviewed-message-ids get-unviewed-message-ids)))
|
||||
|
||||
(defn prepare-content [content]
|
||||
(if (string? content)
|
||||
content
|
||||
(pr-str content)))
|
||||
|
||||
(defn- prepare-message [message]
|
||||
(utils/update-if-present message :content prepare-content))
|
||||
(defn ->rpc [message]
|
||||
(-> message
|
||||
(dissoc :js-obj :dedup-id)
|
||||
(update :message-type name)
|
||||
(update :outgoing-status #(if % (name %) ""))
|
||||
(utils/update-if-present :content prepare-content)
|
||||
(clojure.set/rename-keys {:message-id :id
|
||||
:whisper-timestamp :whisperTimestamp
|
||||
:message-type :messageType
|
||||
:chat-id :chatId
|
||||
:content-type :contentType
|
||||
:clock-value :clockValue
|
||||
:outgoing-status :outgoingStatus})
|
||||
(assoc :replyTo (get-in message [:content :response-to-v2]))))
|
||||
|
||||
(defn save-message-tx
|
||||
"Returns tx function for saving message"
|
||||
[{:keys [message-id from] :as message}]
|
||||
(fn [realm]
|
||||
(core/create realm
|
||||
:message
|
||||
(prepare-message (merge default-values
|
||||
message
|
||||
{:from (or from "anonymous")}))
|
||||
true)))
|
||||
(defn update-quoted-message [message]
|
||||
(let [parsed-content (utils/safe-read-message-content (get-in message [:quotedMessage :content]))]
|
||||
(cond-> message
|
||||
parsed-content
|
||||
(assoc :quoted-message {:from (get-in message [:quotedMessage :from])
|
||||
:text (:text parsed-content)})
|
||||
:always
|
||||
(dissoc message :quotedMessage))))
|
||||
|
||||
(defn delete-message-tx
|
||||
"Returns tx function for deleting message"
|
||||
[message-id]
|
||||
(fn [realm]
|
||||
(core/delete realm (get-message-by-id message-id realm))))
|
||||
(defn <-rpc [message]
|
||||
(when-let [parsed-content (utils/safe-read-message-content (:content message))]
|
||||
(let [outgoing-status (when-not (empty? (:outgoingStatus message))
|
||||
(keyword (:outgoingStatus message)))]
|
||||
|
||||
(defn delete-chat-messages-tx
|
||||
"Returns tx function for deleting messages with user statuses for given chat-id"
|
||||
[chat-id]
|
||||
(fn [realm]
|
||||
(core/delete realm (core/get-by-field realm :message :chat-id chat-id))))
|
||||
(-> message
|
||||
(update :messageType keyword)
|
||||
(update :outgoingStatus keyword)
|
||||
(assoc :content parsed-content
|
||||
:outgoingStatus outgoing-status
|
||||
:outgoing outgoing-status)
|
||||
(update-quoted-message)
|
||||
(clojure.set/rename-keys {:id :message-id
|
||||
:whisperTimestamp :whisper-timestamp
|
||||
:messageType :message-type
|
||||
:chatId :chat-id
|
||||
:contentType :content-type
|
||||
:replyTo :reply-to
|
||||
:clockValue :clock-value
|
||||
:outgoingStatus :outgoing-status})))))
|
||||
|
||||
(defn message-exists? [message-id]
|
||||
(if @core/account-realm
|
||||
(not (nil? (get-message-by-id message-id @core/account-realm)))
|
||||
false))
|
||||
(defn update-outgoing-status-rpc [message-id status]
|
||||
{::json-rpc/call [{:method "shhext_updateMessageOutgoingStatus"
|
||||
:params [message-id status]
|
||||
:on-success #(log/debug "updated message outgoing stauts" message-id status)
|
||||
:on-failure #(log/error "failed to update message outgoing status" message-id status %)}]})
|
||||
|
||||
(defn mark-messages-seen-tx
|
||||
"Returns tx function for marking messages as seen"
|
||||
[message-ids]
|
||||
(fn [realm]
|
||||
(doseq [message-id message-ids]
|
||||
(let [message (get-message-by-id message-id realm)]
|
||||
(aset message "seen" true)))))
|
||||
(defn save-messages-rpc [messages]
|
||||
(let [confirmations (keep :metadata messages)]
|
||||
(json-rpc/call {:method "shhext_saveMessages"
|
||||
:params [(map ->rpc messages)]
|
||||
:on-success #(re-frame/dispatch [:message/messages-persisted confirmations])
|
||||
:on-failure #(log/error "failed to save messages" %)})))
|
||||
|
||||
(defn mark-message-seen-tx
|
||||
"Returns tx function for marking messages as seen"
|
||||
[message-id]
|
||||
(fn [realm]
|
||||
(let [message (get-message-by-id message-id realm)]
|
||||
(aset message "seen" true))))
|
||||
(defn messages-by-chat-id-rpc [chat-id cursor limit on-success]
|
||||
{::json-rpc/call [{:method "shhext_chatMessages"
|
||||
:params [chat-id cursor limit]
|
||||
:on-success (fn [result]
|
||||
(on-success (update result :messages #(map <-rpc %))))
|
||||
:on-failure #(log/error "failed to get messages" %)}]})
|
||||
|
||||
(defn update-outgoing-status-tx
|
||||
"Returns tx function for marking messages as seen"
|
||||
[message-id outgoing-status]
|
||||
(fn [realm]
|
||||
(let [message (get-message-by-id message-id realm)]
|
||||
(aset message "outgoing-status" (name outgoing-status)))))
|
||||
(defn mark-seen-rpc [ids]
|
||||
{::json-rpc/call [{:method "shhext_markMessagesSeen"
|
||||
:params [ids]
|
||||
:on-success #(log/debug "successfully marked as seen")
|
||||
:on-failure #(log/error "failed to get messages" %)}]})
|
||||
|
||||
(defn delete-message-rpc [id]
|
||||
{::json-rpc/call [{:method "shhext_deleteMessage"
|
||||
:params [id]
|
||||
:on-success #(log/debug "successfully deleted message" id)
|
||||
:on-failure #(log/error "failed to delete message" % id)}]})
|
||||
|
||||
(defn delete-messages-from-rpc [author]
|
||||
{::json-rpc/call [{:method "shhext_deleteMessagesFrom"
|
||||
:params [author]
|
||||
:on-success #(log/debug "successfully deleted messages from" author)
|
||||
:on-failure #(log/error "failed to delete messages from" % author)}]})
|
||||
|
||||
(defn delete-messages-by-chat-id-rpc [chat-id]
|
||||
{::json-rpc/call [{:method "shhext_deleteMessagesByChatID"
|
||||
:params [chat-id]
|
||||
:on-success #(log/debug "successfully deleted messages by chat-id" chat-id)
|
||||
:on-failure #(log/error "failed to delete messages by chat-id" % chat-id)}]})
|
||||
|
||||
(re-frame/reg-fx
|
||||
::save-message
|
||||
(fn [messages]
|
||||
(save-messages-rpc messages)))
|
||||
|
||||
(fx/defn save-message [cofx message]
|
||||
{::save-message [message]})
|
||||
|
||||
(fx/defn delete-message [cofx id]
|
||||
(delete-message-rpc id))
|
||||
|
||||
(fx/defn delete-messages-from [cofx author]
|
||||
(delete-messages-from-rpc author))
|
||||
|
||||
(fx/defn mark-messages-seen [_ ids]
|
||||
(mark-seen-rpc ids))
|
||||
|
||||
(fx/defn update-outgoing-status [cofx message-id status]
|
||||
(update-outgoing-status-rpc message-id status))
|
||||
|
||||
(fx/defn delete-messages-by-chat-id [cofx chat-id]
|
||||
(delete-messages-by-chat-id-rpc chat-id))
|
||||
|
|
|
@ -575,6 +575,21 @@
|
|||
contact-recovery/v1
|
||||
mailserver-requests-gap/v1])
|
||||
|
||||
(def v48 [chat/v15
|
||||
chat-requests-range/v1
|
||||
transport/v10
|
||||
contact/v8
|
||||
message/v12
|
||||
mailserver/v11
|
||||
mailserver-topic/v2
|
||||
membership-update/v1
|
||||
installation/v3
|
||||
browser/v8
|
||||
dapp-permissions/v9
|
||||
contact-device-info/v1
|
||||
contact-recovery/v1
|
||||
mailserver-requests-gap/v1])
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1
|
||||
:schemaVersion 1
|
||||
|
@ -716,4 +731,7 @@
|
|||
:migration migrations/v46}
|
||||
{:schema v47
|
||||
:schemaVersion 47
|
||||
:migration (constantly nil)}
|
||||
{:schema v48
|
||||
:schemaVersion 48
|
||||
:migration (constantly nil)}])
|
||||
|
|
|
@ -78,3 +78,6 @@
|
|||
(assoc-in [:properties :outgoing-status]
|
||||
{:type :string
|
||||
:optional true})))
|
||||
|
||||
(def v12
|
||||
(update v11 :properties dissoc :old-message-id))
|
||||
|
|
|
@ -33,8 +33,17 @@
|
|||
"shhext_loadFilter" {}
|
||||
"shhext_removeFilters" {}
|
||||
"shhext_chats" {}
|
||||
"shhext_saveMessages" {}
|
||||
"shhext_deleteMessagesFrom" {}
|
||||
"shhext_deleteMessagesByChatID" {}
|
||||
"shhext_deleteMessage" {}
|
||||
"shhext_markMessagesSeen" {}
|
||||
"shhext_confirmMessagesProcessedByID" {}
|
||||
"shhext_updateMessageOutgoingStatus" {}
|
||||
"shhext_chatMessages" {}
|
||||
"shhext_saveChat" {}
|
||||
"shhext_contacts" {}
|
||||
"shhext_blockContact" {}
|
||||
"shhext_deleteChat" {}
|
||||
"shhext_saveContact" {}
|
||||
"status_joinPublicChat" {}
|
||||
|
@ -51,8 +60,8 @@
|
|||
"permissions_deleteDappPermissions" {}})
|
||||
|
||||
(defn call
|
||||
[{:keys [method params on-success on-error]}]
|
||||
(when-let [method-options (json-rpc-api method)]
|
||||
[{:keys [method params on-success on-error] :as p}]
|
||||
(if-let [method-options (json-rpc-api method)]
|
||||
(let [{:keys [id on-result subscription?]
|
||||
:or {on-result identity
|
||||
id 1
|
||||
|
@ -80,7 +89,9 @@
|
|||
(re-frame/dispatch
|
||||
[:ethereum.callback/subscription-success
|
||||
result on-success])
|
||||
(on-success (on-result result))))))))))))
|
||||
(on-success (on-result result))))))))))
|
||||
|
||||
(log/warn "method" method "not found" p)))
|
||||
|
||||
(defn eth-call
|
||||
[{:keys [contract method params outputs on-success on-error block]
|
||||
|
|
|
@ -696,10 +696,6 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/load-more-messages
|
||||
[(re-frame/inject-cofx :data-store/get-messages)
|
||||
(re-frame/inject-cofx :data-store/get-referenced-messages)
|
||||
(re-frame/inject-cofx :data-store/get-unviewed-message-ids)
|
||||
(re-frame/inject-cofx :data-store/all-gaps)]
|
||||
(fn [cofx _]
|
||||
(chat.loading/load-more-messages cofx)))
|
||||
|
||||
|
@ -763,8 +759,8 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/reply-to-message
|
||||
(fn [cofx [_ message-id old-message-id]]
|
||||
(chat.input/reply-to-message cofx message-id old-message-id)))
|
||||
(fn [cofx [_ message-id]]
|
||||
(chat.input/reply-to-message cofx message-id)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/send-current-message
|
||||
|
@ -1484,8 +1480,11 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:transport/message-sent
|
||||
(fn [cofx [_ chat-id message-id message-type envelope-hash-js messages-count]]
|
||||
(transport.message/set-message-envelope-hash cofx chat-id message-id message-type envelope-hash-js messages-count)))
|
||||
(fn [cofx [_ chat-id message message-type message-id messages-count]]
|
||||
(fx/merge cofx
|
||||
(when message (chat.message/add-message-with-id (assoc message :message-id message-id) chat-id))
|
||||
|
||||
(transport.message/set-message-envelope-hash chat-id message-id message-type messages-count))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:transport/contact-message-sent
|
||||
|
@ -1512,7 +1511,6 @@
|
|||
|
||||
(handlers/register-handler-fx
|
||||
:contact.ui/block-contact-confirmed
|
||||
[(re-frame/inject-cofx :data-store/get-user-messages)]
|
||||
(fn [cofx [_ public-key]]
|
||||
(contact.block/block-contact cofx public-key)))
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
:dsts destinations
|
||||
:success-event [:transport/message-sent
|
||||
chat-id
|
||||
message-id
|
||||
(:message cofx)
|
||||
:group-user-message]
|
||||
:payload payload}}))))
|
||||
|
||||
|
@ -471,7 +471,7 @@
|
|||
[cofx {:keys [chat-id
|
||||
message
|
||||
membership-updates] :as membership-update}
|
||||
{:keys [raw-payload dedup-id]}
|
||||
{:keys [raw-payload metadata]}
|
||||
sender-signature]
|
||||
(let [dev-mode? (get-in cofx [:db :multiaccount :dev-mode?])]
|
||||
(when (valid-chat-id? chat-id (extract-creator membership-update))
|
||||
|
@ -502,7 +502,7 @@
|
|||
(= :group-user-message (:message-type message)))
|
||||
(protocol/receive message chat-id sender-signature nil
|
||||
(assoc %
|
||||
:dedup-id dedup-id
|
||||
:metadata metadata
|
||||
:js-obj #js {:payload raw-payload}))))))))
|
||||
|
||||
(defn handle-sign-success
|
||||
|
|
|
@ -76,9 +76,8 @@
|
|||
(protocol/send (transport.pairing/PairInstallation. installation-id device-type installation-name fcm-token) nil cofx)))
|
||||
|
||||
(fx/defn confirm-message-processed
|
||||
[{:keys [db]} raw-message]
|
||||
{:transport/confirm-messages-processed [{:web3 (:web3 db)
|
||||
:js-obj raw-message}]})
|
||||
[{:keys [db]} confirmation]
|
||||
{:transport/confirm-messages-processed [confirmation]})
|
||||
|
||||
(defn send-pair-installation [cofx payload]
|
||||
(let [{:keys [web3]} (:db cofx)
|
||||
|
@ -353,25 +352,25 @@
|
|||
contacts))
|
||||
|
||||
(defn handle-sync-installation [{:keys [db] :as cofx} {:keys [contacts multiaccount chat]} sender]
|
||||
(if (= sender (multiaccounts.model/current-public-key cofx))
|
||||
(let [success-event [:message/messages-persisted [(or (:dedup-id cofx) (:js-obj cofx))]]
|
||||
new-contacts (when (seq contacts)
|
||||
(vals (merge-contacts (:contacts/contacts db)
|
||||
((comp ensure-photo-path
|
||||
ensure-system-tags) contacts))))
|
||||
new-multiaccount (merge-multiaccount (:multiaccount db) multiaccount)
|
||||
contacts-fx (when new-contacts (mapv contact/upsert-contact new-contacts))]
|
||||
(apply fx/merge
|
||||
cofx
|
||||
(concat
|
||||
[{:db (assoc db :multiaccount new-multiaccount)
|
||||
:data-store/base-tx [{:transaction (data-store.multiaccounts/save-multiaccount-tx new-multiaccount)
|
||||
:success-event success-event}]}
|
||||
#(when (:public? chat)
|
||||
(models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true}))]
|
||||
contacts-fx)))
|
||||
(confirm-message-processed cofx (or (:dedup-id cofx)
|
||||
(:js-obj cofx)))))
|
||||
(let [confirmation (:metadata cofx)]
|
||||
(if (= sender (multiaccounts.model/current-public-key cofx))
|
||||
(let [success-event [:message/messages-persisted [confirmation]]
|
||||
new-contacts (when (seq contacts)
|
||||
(vals (merge-contacts (:contacts/contacts db)
|
||||
((comp ensure-photo-path
|
||||
ensure-system-tags) contacts))))
|
||||
new-multiaccount (merge-multiaccount (:multiaccount db) multiaccount)
|
||||
contacts-fx (when new-contacts (mapv contact/upsert-contact new-contacts))]
|
||||
(apply fx/merge
|
||||
cofx
|
||||
(concat
|
||||
[{:db (assoc db :multiaccount new-multiaccount)
|
||||
:data-store/base-tx [{:transaction (data-store.multiaccounts/save-multiaccount-tx new-multiaccount)
|
||||
:success-event success-event}]}
|
||||
#(when (:public? chat)
|
||||
(models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true}))]
|
||||
contacts-fx)))
|
||||
(confirm-message-processed cofx confirmation))))
|
||||
|
||||
(defn handle-pair-installation [{:keys [db] :as cofx} {:keys [name
|
||||
fcm-token
|
||||
|
@ -382,8 +381,7 @@
|
|||
{:pairing/set-installation-metadata [[installation-id {:name name
|
||||
:deviceType device-type
|
||||
:fcmToken fcm-token}]]}
|
||||
(confirm-message-processed cofx (or (:dedup-id cofx)
|
||||
(:js-obj cofx)))))
|
||||
(confirm-message-processed cofx (:metadata cofx))))
|
||||
|
||||
(fx/defn update-installation [{:keys [db]} installation-id metadata]
|
||||
{:db (update-in db [:pairing/installations installation-id]
|
||||
|
|
|
@ -619,12 +619,6 @@
|
|||
(fn [{:keys [message-groups]}]
|
||||
(or message-groups {})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-referenced-messages
|
||||
:<- [:chats/current-chat]
|
||||
(fn [{:keys [referenced-messages]}]
|
||||
(or referenced-messages {})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/messages-gaps
|
||||
:<- [:mailserver/gaps]
|
||||
|
@ -655,17 +649,14 @@
|
|||
:chats/current-chat-messages-stream
|
||||
:<- [:chats/current-chat-messages]
|
||||
:<- [:chats/current-chat-message-groups]
|
||||
:<- [:chats/current-chat-referenced-messages]
|
||||
:<- [:chats/messages-gaps]
|
||||
:<- [:chats/range]
|
||||
:<- [:chats/all-loaded?]
|
||||
:<- [:chats/public?]
|
||||
(fn [[messages message-groups referenced-messages
|
||||
messages-gaps range all-loaded? public?]]
|
||||
(fn [[messages message-groups messages-gaps range all-loaded? public?]]
|
||||
(-> (chat.db/sort-message-groups message-groups messages)
|
||||
(chat.db/messages-with-datemarks
|
||||
messages referenced-messages
|
||||
messages-gaps range all-loaded? public?)
|
||||
messages messages-gaps range all-loaded? public?)
|
||||
chat.db/messages-stream)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
(extend-type transport.group-chat/GroupMembershipUpdate
|
||||
protocol/StatusMessage
|
||||
(receive [this _ signature _ {:keys [dedup-id js-obj] :as cofx}]
|
||||
(group-chats/handle-membership-update-received cofx this signature {:dedup-id dedup-id
|
||||
(receive [this _ signature _ {:keys [metadata js-obj] :as cofx}]
|
||||
(group-chats/handle-membership-update-received cofx this signature {:metadata metadata
|
||||
:raw-payload (.-payload js-obj)})))
|
||||
|
||||
(extend-type transport.contact/ContactRequest
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models.message :as models.message]
|
||||
[status-im.contact.device-info :as device-info]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.data-store.transport :as transport-store]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.transport.message.contact :as contact]
|
||||
|
@ -14,6 +15,12 @@
|
|||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn confirm-messages [confirmations]
|
||||
(json-rpc/call {:method "shhext_confirmMessagesProcessedByID"
|
||||
:params [confirmations]
|
||||
:on-success #(log/debug "successfully confirmed messages")
|
||||
:on-failure #(log/error "failed to confirm messages" %)}))
|
||||
|
||||
(defn add-raw-payload
|
||||
"Add raw payload for id calculation"
|
||||
[{:keys [message] :as m}]
|
||||
|
@ -26,8 +33,8 @@
|
|||
in order to stop receiving that message"
|
||||
[cofx now-in-s filter-chat-id message]
|
||||
(let [blocked-contacts (get-in cofx [:db :contacts/blocked] #{})
|
||||
{{:keys [payload sig timestamp ttl]} :message
|
||||
dedup-id :id
|
||||
{{:keys [payload sig timestamp ttl hash]} :message
|
||||
metadata :metadata
|
||||
raw-payload :raw-payload} (add-raw-payload message)
|
||||
status-message (-> payload
|
||||
ethereum/hex-to-utf8
|
||||
|
@ -37,8 +44,9 @@
|
|||
(not (blocked-contacts sig)))
|
||||
(try
|
||||
(when-let [valid-message (protocol/validate status-message)]
|
||||
(fx/merge (assoc cofx :js-obj raw-payload :dedup-id dedup-id)
|
||||
#(protocol/receive valid-message
|
||||
(fx/merge (assoc cofx :js-obj raw-payload :metadata metadata)
|
||||
#(protocol/receive (assoc valid-message
|
||||
:metadata metadata)
|
||||
(or
|
||||
filter-chat-id
|
||||
(get-in valid-message [:content :chat-id])
|
||||
|
@ -67,18 +75,19 @@
|
|||
(log/error "Something went wrong" error messages)))
|
||||
|
||||
(fx/defn receive-messages [cofx event]
|
||||
(let [fxs (map
|
||||
(let [fxs (keep
|
||||
(fn [{:keys [chat messages error]}]
|
||||
(receive-whisper-messages
|
||||
error
|
||||
messages
|
||||
;; For discovery and negotiated filters we don't
|
||||
;; set a chatID, and we use the signature of the message
|
||||
;; to indicate which chat it is for
|
||||
(if (or (:discovery chat)
|
||||
(:negotiated chat))
|
||||
nil
|
||||
(:chatId chat))))
|
||||
(when (seq messages)
|
||||
(receive-whisper-messages
|
||||
error
|
||||
messages
|
||||
;; For discovery and negotiated filters we don't
|
||||
;; set a chatID, and we use the signature of the message
|
||||
;; to indicate which chat it is for
|
||||
(if (or (:discovery chat)
|
||||
(:negotiated chat))
|
||||
nil
|
||||
(:chatId chat)))))
|
||||
(:messages event))]
|
||||
(apply fx/merge cofx fxs)))
|
||||
|
||||
|
@ -107,7 +116,8 @@
|
|||
message-id
|
||||
(if not-sent
|
||||
:not-sent
|
||||
status)))
|
||||
status))
|
||||
(remove-hash message-id))
|
||||
(let [confirmations {:pending-confirmations (dec pending-confirmations)
|
||||
:not-sent (or not-sent
|
||||
(= :not-sent status))}]
|
||||
|
@ -140,7 +150,6 @@
|
|||
(filter identity $)
|
||||
(take (inc config/max-installations) $))]
|
||||
(fx/merge cofx
|
||||
(remove-hash envelope-hash)
|
||||
(check-confirmations status chat-id message-id)
|
||||
(models.message/send-push-notification chat-id message-id fcm-tokens status)))))))
|
||||
|
||||
|
@ -156,18 +165,14 @@
|
|||
|
||||
(fx/defn set-message-envelope-hash
|
||||
"message-type is used for tracking"
|
||||
[{:keys [db] :as cofx} chat-id message-id message-type envelope-hash-js messages-count]
|
||||
(let [envelope-hash (js->clj envelope-hash-js)
|
||||
hash (if (vector? envelope-hash)
|
||||
(last envelope-hash)
|
||||
envelope-hash)]
|
||||
{:db (-> db
|
||||
(assoc-in [:transport/message-envelopes hash]
|
||||
{:chat-id chat-id
|
||||
:message-id message-id
|
||||
:message-type message-type})
|
||||
(update-in [:transport/message-ids->confirmations message-id]
|
||||
#(or % {:pending-confirmations messages-count})))}))
|
||||
[{:keys [db] :as cofx} chat-id message-id message-type messages-count]
|
||||
{:db (-> db
|
||||
(assoc-in [:transport/message-envelopes message-id]
|
||||
{:chat-id chat-id
|
||||
:message-id message-id
|
||||
:message-type message-type})
|
||||
(update-in [:transport/message-ids->confirmations message-id]
|
||||
#(or % {:pending-confirmations messages-count})))})
|
||||
|
||||
(defn- own-info [db]
|
||||
(let [{:keys [name photo-path address]} (:multiaccount db)
|
||||
|
@ -211,20 +216,6 @@
|
|||
|
||||
(re-frame/reg-fx
|
||||
:transport/confirm-messages-processed
|
||||
(fn [messages]
|
||||
(let [{:keys [web3]} (first messages)
|
||||
js-messages (->> messages
|
||||
(keep :js-obj)
|
||||
(apply array))]
|
||||
(when (pos? (.-length js-messages))
|
||||
(if (string? (first js-messages))
|
||||
(.confirmMessagesProcessedByID (transport.utils/shh web3)
|
||||
js-messages
|
||||
(fn [err resp]
|
||||
(when err
|
||||
(log/warn "Confirming messages processed failed" err))))
|
||||
(.confirmMessagesProcessed (transport.utils/shh web3)
|
||||
js-messages
|
||||
(fn [err resp]
|
||||
(when err
|
||||
(log/warn "Confirming messages processed failed" err)))))))))
|
||||
(fn [confirmations]
|
||||
(when (seq confirmations)
|
||||
(confirm-messages confirmations))))
|
||||
|
|
|
@ -78,18 +78,17 @@
|
|||
|
||||
(defrecord Message [content content-type message-type clock-value timestamp]
|
||||
StatusMessage
|
||||
(send [this chat-id {:keys [message-id] :as cofx}]
|
||||
(send [this chat-id {:keys [message] :as cofx}]
|
||||
(let [current-public-key (multiaccounts.model/current-public-key cofx)
|
||||
params {:chat-id chat-id
|
||||
:payload this
|
||||
:success-event [:transport/message-sent
|
||||
chat-id
|
||||
message-id
|
||||
message
|
||||
message-type]}]
|
||||
(case message-type
|
||||
:public-group-user-message
|
||||
(send-public-message cofx chat-id (:success-event params) this)
|
||||
|
||||
:user-message
|
||||
(fx/merge cofx
|
||||
(when (pairing.utils/has-paired-installations? cofx)
|
||||
|
@ -98,16 +97,17 @@
|
|||
(receive [this chat-id signature timestamp cofx]
|
||||
(let [received-message-fx {:chat-received-message/add-fx
|
||||
[(assoc (into {} this)
|
||||
:old-message-id (transport.utils/old-message-id this)
|
||||
:message-id (transport.utils/message-id
|
||||
signature
|
||||
(.-payload (:js-obj cofx)))
|
||||
:message-id
|
||||
(or (get-in cofx [:metadata :messageId])
|
||||
(transport.utils/message-id
|
||||
signature
|
||||
(.-payload (:js-obj cofx))))
|
||||
:chat-id chat-id
|
||||
:whisper-timestamp timestamp
|
||||
:raw-payload-hash (ethereum/sha3
|
||||
(.-payload (:js-obj cofx)))
|
||||
:from signature
|
||||
:dedup-id (:dedup-id cofx)
|
||||
:metadata (:metadata cofx)
|
||||
:js-obj (:js-obj cofx))]}]
|
||||
(whitelist/filter-message cofx
|
||||
received-message-fx
|
||||
|
|
|
@ -4,18 +4,16 @@
|
|||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.js-dependencies :as dependencies]))
|
||||
|
||||
(defn old-message-id
|
||||
[message]
|
||||
(ethereum/sha3 (pr-str message)))
|
||||
|
||||
(defn system-message-id
|
||||
[{:keys [from chat-id clock-value]}]
|
||||
(ethereum/sha3 (str from chat-id clock-value)))
|
||||
|
||||
(defn message-id
|
||||
"Get a message-id"
|
||||
"Get a message-id by appending the hex-encoded pk of the sender to the raw-payload.
|
||||
We strip 0x from the payload so web3 understand that the whole thing is to be
|
||||
decoded as raw bytes"
|
||||
[from raw-payload]
|
||||
(ethereum/sha3 (str from (ethereum/sha3 raw-payload))))
|
||||
(ethereum/sha3 (str from (subs raw-payload 2))))
|
||||
|
||||
(defn get-topic
|
||||
"Get the topic of a group chat or public chat from the chat-id"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:contacts/contacts public-key] contact))}
|
||||
(contacts-store/save-contact-tx contact)
|
||||
(contacts-store/save-contact contact)
|
||||
(add-to-whitelist public-key))))
|
||||
|
||||
(fx/defn mark-tribute-paid
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
(:url content))
|
||||
(.share react/sharing (clj->js content))))
|
||||
|
||||
(defn- message-options [message-id old-message-id text]
|
||||
(defn- message-options [message-id text]
|
||||
[{:label (i18n/label :t/message-reply)
|
||||
:action #(re-frame/dispatch [:chat.ui/reply-to-message message-id old-message-id])}
|
||||
:action #(re-frame/dispatch [:chat.ui/reply-to-message message-id])}
|
||||
{:label (i18n/label :t/sharing-copy-to-clipboard)
|
||||
:action #(react/copy-to-clipboard text)}
|
||||
(when-not platform/desktop?
|
||||
|
@ -28,9 +28,9 @@
|
|||
platform/android? (dialog/show options)
|
||||
platform/desktop? (show-desktop-menu (->> (:options options) (remove nil?)))))
|
||||
|
||||
(defn chat-message [message-id old-message-id text dialog-title]
|
||||
(defn chat-message [message-id text dialog-title]
|
||||
(show {:title dialog-title
|
||||
:options (message-options message-id old-message-id text)
|
||||
:options (message-options message-id text)
|
||||
:cancel-text (i18n/label :t/message-options-cancel)}))
|
||||
|
||||
(defn- platform-web-browser []
|
||||
|
|
|
@ -114,10 +114,13 @@
|
|||
{:justify-timestamp? true}])
|
||||
|
||||
(defn emoji-message
|
||||
[{:keys [content] :as message}]
|
||||
[{:keys [content current-public-key] :as message}]
|
||||
[message-view message
|
||||
[react/text {:style (style/emoji-message message)}
|
||||
(:text content)]])
|
||||
[react/view {:style (style/style-message-text false)}
|
||||
(when (:response-to content)
|
||||
[quoted-message (:response-to content) false current-public-key])
|
||||
[react/text {:style (style/emoji-message message)}
|
||||
(:text content)]]])
|
||||
|
||||
(defmulti message-content (fn [_ message _] (message :content-type)))
|
||||
|
||||
|
@ -249,8 +252,8 @@
|
|||
[message-delivery-status message]]])
|
||||
|
||||
(defn open-chat-context-menu
|
||||
[{:keys [message-id old-message-id content] :as message}]
|
||||
(list-selection/chat-message message-id old-message-id (:text content) (i18n/label :t/message)))
|
||||
[{:keys [message-id content] :as message}]
|
||||
(list-selection/chat-message message-id (:text content) (i18n/label :t/message)))
|
||||
|
||||
(defn chat-message
|
||||
[{:keys [outgoing group-chat modal? current-public-key content-type content] :as message}]
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
(not (#{:not-sent :sending} outgoing-status)))
|
||||
|
||||
(views/defview message-without-timestamp
|
||||
[text {:keys [chat-id message-id old-message-id content group-chat expanded? current-public-key outgoing-status] :as message} style]
|
||||
[text {:keys [chat-id message-id content group-chat expanded? current-public-key outgoing-status] :as message} style]
|
||||
[react/view {:flex 1 :margin-vertical 5}
|
||||
[react/touchable-highlight {:on-press (fn [arg]
|
||||
(when (= "right" (.-button (.-nativeEvent arg)))
|
||||
|
@ -110,7 +110,7 @@
|
|||
:on-select #(do (utils/show-popup "" "Message copied to clipboard") (react/copy-to-clipboard text))}
|
||||
{:text (i18n/label :t/message-reply)
|
||||
:on-select #(when (message-sent? outgoing-status)
|
||||
(re-frame/dispatch [:chat.ui/reply-to-message message-id old-message-id]))}])))}
|
||||
(re-frame/dispatch [:chat.ui/reply-to-message message-id]))}])))}
|
||||
(let [collapsible? (and (:should-collapse? content) group-chat)
|
||||
char-limit (if (and collapsible? (not expanded?))
|
||||
constants/chars-collapse-threshold constants/desktop-msg-chars-hard-limit)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#{:data-store/tx :data-store/base-tx :chat-received-message/add-fx
|
||||
:shh/post :filters/load-filters
|
||||
:pairing/set-installation-metadata
|
||||
:status-im.data-store.messages/save-message
|
||||
:shh/send-direct-message :shh/remove-filter
|
||||
:shh/generate-sym-key-from-password :transport/confirm-messages-processed
|
||||
:group-chats/extract-membership-signature :utils/dispatch-later ::json-rpc/call})
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "8383feea04004adb967ce879e42adce7cbcd300c",
|
||||
"commit-sha1": "8383feea04004adb967ce879e42adce7cbcd300c",
|
||||
"src-sha256": "1sb0irq1h1xzclqfabhhmf680gia3v763kii6avsamv3r1yw0kx1"
|
||||
"version": "06dc227071708d10988203de8b3787362d5f40d1",
|
||||
"commit-sha1": "06dc227071708d10988203de8b3787362d5f40d1",
|
||||
"src-sha256": "1imf5rb35938vwmi96yas9lykcrd2r487kv0di6dj4cz590vx8ws"
|
||||
}
|
||||
|
|
|
@ -115,230 +115,230 @@
|
|||
(is (= #{"1" "2"}
|
||||
(set (keys (db/active-chats {} chats {}))))))))
|
||||
|
||||
(deftest messages-with-datemarks
|
||||
(testing "empty state"
|
||||
(is (empty?
|
||||
(db/messages-with-datemarks
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
false
|
||||
false))))
|
||||
(testing "empty state pub-chat"
|
||||
(is (=
|
||||
[{:type :gap
|
||||
:value ":first-gap"
|
||||
:first-gap? true}]
|
||||
(db/messages-with-datemarks
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
{:lowest-request-from 10
|
||||
:highest-request-to 30}
|
||||
true
|
||||
true))))
|
||||
(testing "simple case"
|
||||
(is (=
|
||||
'({:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil))))
|
||||
(testing "simple case with gap"
|
||||
(is (=
|
||||
'({:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:type :gap
|
||||
:value ":gapid1"
|
||||
:gaps {:ids [:gapid1]}}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
[{:from 25
|
||||
:to 30
|
||||
:id :gapid1}]
|
||||
nil
|
||||
nil
|
||||
nil))))
|
||||
(testing "simple case with gap after all messages"
|
||||
(is (=
|
||||
'({:type :gap
|
||||
:value ":gapid1"
|
||||
:gaps {:ids (:gapid1)}}
|
||||
{:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
[{:from 100
|
||||
:to 110
|
||||
:id :gapid1}]
|
||||
nil
|
||||
nil
|
||||
nil)))))
|
||||
#_(deftest messages-with-datemarks
|
||||
(testing "empty state"
|
||||
(is (empty?
|
||||
(db/messages-with-datemarks
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
false
|
||||
false))))
|
||||
(testing "empty state pub-chat"
|
||||
(is (=
|
||||
[{:type :gap
|
||||
:value ":first-gap"
|
||||
:first-gap? true}]
|
||||
(db/messages-with-datemarks
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
{:lowest-request-from 10
|
||||
:highest-request-to 30}
|
||||
true
|
||||
true))))
|
||||
(testing "simple case"
|
||||
(is (=
|
||||
'({:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil
|
||||
nil))))
|
||||
(testing "simple case with gap"
|
||||
(is (=
|
||||
'({:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:type :gap
|
||||
:value ":gapid1"
|
||||
:gaps {:ids [:gapid1]}}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
[{:from 25
|
||||
:to 30
|
||||
:id :gapid1}]
|
||||
nil
|
||||
nil
|
||||
nil))))
|
||||
(testing "simple case with gap after all messages"
|
||||
(is (=
|
||||
'({:type :gap
|
||||
:value ":gapid1"
|
||||
:gaps {:ids (:gapid1)}}
|
||||
{:whisper-timestamp 40
|
||||
:timestamp 40
|
||||
:content nil
|
||||
:timestamp-str "14:00"
|
||||
:datemark "today"}
|
||||
{:whisper-timestamp 30
|
||||
:timestamp 30
|
||||
:content nil
|
||||
:timestamp-str "13:00"
|
||||
:datemark "today"}
|
||||
{:value "today"
|
||||
:type :datemark
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:whisper-timestamp 20
|
||||
:timestamp 20
|
||||
:content nil
|
||||
:timestamp-str "12:00"
|
||||
:datemark "yesterday"}
|
||||
{:whisper-timestamp 10
|
||||
:timestamp 10
|
||||
:content nil
|
||||
:timestamp-str "11:00"
|
||||
:datemark "yesterday"}
|
||||
{:value "yesterday"
|
||||
:type :datemark
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10})
|
||||
(db/messages-with-datemarks
|
||||
{"yesterday"
|
||||
(list
|
||||
{:message-id :m1
|
||||
:timestamp-str "11:00"
|
||||
:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
{:message-id :m2
|
||||
:timestamp-str "12:00"
|
||||
:whisper-timestamp 20
|
||||
:timestamp 20})
|
||||
"today"
|
||||
(list
|
||||
{:message-id :m3
|
||||
:timestamp-str "13:00"
|
||||
:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
{:message-id :m4
|
||||
:timestamp-str "14:00"
|
||||
:whisper-timestamp 40
|
||||
:timestamp 40})}
|
||||
{:m1 {:whisper-timestamp 10
|
||||
:timestamp 10}
|
||||
:m2 {:whisper-timestamp 20
|
||||
:timestamp 20}
|
||||
:m3 {:whisper-timestamp 30
|
||||
:timestamp 30}
|
||||
:m4 {:whisper-timestamp 40
|
||||
:timestamp 40}}
|
||||
nil
|
||||
[{:from 100
|
||||
:to 110
|
||||
:id :gapid1}]
|
||||
nil
|
||||
nil
|
||||
nil)))))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.test.chat.models
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.chat.models :as chat]))
|
||||
|
||||
|
@ -93,10 +94,10 @@
|
|||
:messages {})
|
||||
chat-id)]
|
||||
(is (= 42 (get-in actual [:db :chats chat-id :deleted-at-clock-value]))))))
|
||||
(testing "it adds the relevant transactions for realm"
|
||||
(testing "it adds the relevant rpc calls"
|
||||
(let [actual (chat/clear-history cofx chat-id)]
|
||||
(is (:data-store/tx actual))
|
||||
(is (= 1 (count (:data-store/tx actual))))))))
|
||||
(is (::json-rpc/call actual))
|
||||
(is (= 1 (count (::json-rpc/call actual))))))))
|
||||
|
||||
(deftest remove-chat-test
|
||||
(let [chat-id "1"
|
||||
|
@ -134,7 +135,7 @@
|
|||
(testing "it adds the relevant transactions for realm"
|
||||
(let [actual (chat/remove-chat cofx chat-id)]
|
||||
(is (:data-store/tx actual))
|
||||
(is (= 4 (count (:data-store/tx actual))))))))
|
||||
(is (= 3 (count (:data-store/tx actual))))))))
|
||||
|
||||
(deftest multi-user-chat?
|
||||
(let [chat-id "1"]
|
||||
|
@ -169,24 +170,24 @@
|
|||
"opened" {:loaded-unviewed-messages-ids #{}}
|
||||
"1-1" {:loaded-unviewed-messages-ids #{"6" "5" "4"}}}})
|
||||
|
||||
(deftest mark-messages-seen
|
||||
(testing "Marking messages seen correctly marks loaded messages as seen and updates absolute unviewed set"
|
||||
(let [fx (chat/mark-messages-seen {:db test-db} "status")
|
||||
me (get-in test-db [:multiaccount :public-key])]
|
||||
(is (= '(true true true)
|
||||
(map (comp :seen second) (get-in fx [:db :chats "status" :messages]))))
|
||||
(is (= 1 (count (:data-store/tx fx))))
|
||||
#_(deftest mark-messages-seen
|
||||
(testing "Marking messages seen correctly marks loaded messages as seen and updates absolute unviewed set"
|
||||
(let [fx (chat/mark-messages-seen {:db test-db} "status")
|
||||
me (get-in test-db [:multiaccount :public-key])]
|
||||
(is (= '(true true true)
|
||||
(map (comp :seen second) (get-in fx [:db :chats "status" :messages]))))
|
||||
(is (= 1 (count (:data-store/tx fx))))
|
||||
;; for public chats, no confirmation is sent out
|
||||
(is (= nil (:shh/post fx)))))
|
||||
(is (= nil (:shh/post fx)))))
|
||||
|
||||
(testing "With empty unviewed set, no effects are produced"
|
||||
(is (= nil (chat/mark-messages-seen {:db test-db} "opened"))))
|
||||
(testing "With empty unviewed set, no effects are produced"
|
||||
(is (= nil (chat/mark-messages-seen {:db test-db} "opened"))))
|
||||
|
||||
#_(testing "For 1-1 chat, we send seen messages confirmation to the
|
||||
#_(testing "For 1-1 chat, we send seen messages confirmation to the
|
||||
recipient as well"
|
||||
(is (= #{"4" "5" "6"}
|
||||
(set (get-in (chat/mark-messages-seen {:db test-db} "1-1")
|
||||
[:shh/post 0 :message :payload :message-ids]))))))
|
||||
(is (= #{"4" "5" "6"}
|
||||
(set (get-in (chat/mark-messages-seen {:db test-db} "1-1")
|
||||
[:shh/post 0 :message :payload :message-ids]))))))
|
||||
|
||||
(deftest update-dock-badge-label
|
||||
(testing "When user has unseen private messages"
|
||||
|
|
|
@ -55,8 +55,6 @@
|
|||
(is message))
|
||||
(testing "it marks the message as outgoing"
|
||||
(is (= true (:outgoing message))))
|
||||
(testing "it stores the message"
|
||||
(is (:data-store/tx actual)))
|
||||
(testing "it does not send a seen confirmation"
|
||||
(is (not (:shh/post actual))))))))
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
(ns status-im.test.data-store.messages
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.data-store.messages :as m]))
|
||||
|
||||
(def message-id "0xfe96d03da2159e632a6653d04028b0de8b55f78f03521b26ce10dc5f48a16aee")
|
||||
(def chat-id "chat-id")
|
||||
(def from "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1")
|
||||
|
||||
(deftest message->rpc
|
||||
(testing "message to rpc"
|
||||
(let [message {:message-id message-id
|
||||
:content {:chat-id chat-id
|
||||
:response-to-v2 "id-2"
|
||||
:text "hta"}
|
||||
:whisper-timestamp 1
|
||||
:js-obj {}
|
||||
:dedup-id "ATIwMTkwODE0YTdkNWZhZGY1N2E0ZDU3MzUxZmJkNDZkZGM1ZTU4ZjRlYzUyYWYyMDA5NTc2NWYyYmIxOTQ2OTM3NGUwNjdiMvEpTIGEjHOTAyqsrN39wST4npnSAv1AR8jJWeubanjkoGIyJooD5RVRnx6ZMt+/JzBOD2hoZzlHQWA0bC6XbdU="
|
||||
:outgoing-status :sending
|
||||
:message-type :public-group-user-message
|
||||
:clock-value 2
|
||||
:from from
|
||||
:chat-id chat-id
|
||||
:content-type "text/plain"
|
||||
:timestamp 3}
|
||||
expected {:id message-id
|
||||
:whisperTimestamp 1
|
||||
:from from
|
||||
:chatId chat-id
|
||||
:replyTo "id-2"
|
||||
:content "{:chat-id \"chat-id\", :response-to-v2 \"id-2\", :text \"hta\"}"
|
||||
:contentType "text/plain"
|
||||
:messageType "public-group-user-message"
|
||||
:clockValue 2
|
||||
:timestamp 3
|
||||
:outgoingStatus "sending"}]
|
||||
(is (= expected (m/->rpc message))))))
|
||||
|
||||
(deftest message<-rpc
|
||||
(testing "message to rpc"
|
||||
(let [expected {:message-id message-id
|
||||
:content {:chat-id chat-id
|
||||
:text "hta"}
|
||||
:whisper-timestamp 1
|
||||
:outgoing-status :sending
|
||||
:outgoing :sending
|
||||
:message-type :public-group-user-message
|
||||
:clock-value 2
|
||||
:from from
|
||||
:chat-id chat-id
|
||||
:quoted-message {:from "from"
|
||||
:text "reply"}
|
||||
:content-type "text/plain"
|
||||
:timestamp 3}
|
||||
message {:id message-id
|
||||
:whisperTimestamp 1
|
||||
:from from
|
||||
:chatId chat-id
|
||||
:content "{:chat-id \"chat-id\", :text \"hta\"}"
|
||||
:contentType "text/plain"
|
||||
:messageType "public-group-user-message"
|
||||
:clockValue 2
|
||||
:quotedMessage {:from "from"
|
||||
:content "{:chat-id \"chat-id\", :text \"reply\"}"}
|
||||
:timestamp 3
|
||||
:outgoingStatus "sending"}]
|
||||
(is (= expected (m/<-rpc message))))))
|
|
@ -16,6 +16,7 @@
|
|||
[status-im.test.contact-recovery.core]
|
||||
[status-im.test.contacts.device-info]
|
||||
[status-im.test.data-store.chats]
|
||||
[status-im.test.data-store.messages]
|
||||
[status-im.test.data-store.contacts]
|
||||
[status-im.test.data-store.core]
|
||||
[status-im.test.data-store.realm.core]
|
||||
|
@ -47,6 +48,7 @@
|
|||
[status-im.test.sign-in.flow]
|
||||
[status-im.test.stickers.core]
|
||||
[status-im.test.transport.core]
|
||||
[status-im.test.transport.utils]
|
||||
[status-im.test.tribute-to-talk.core]
|
||||
[status-im.test.tribute-to-talk.db]
|
||||
[status-im.test.tribute-to-talk.whitelist]
|
||||
|
@ -101,6 +103,7 @@
|
|||
'status-im.test.contacts.db
|
||||
'status-im.test.contacts.device-info
|
||||
'status-im.test.data-store.chats
|
||||
'status-im.test.data-store.messages
|
||||
'status-im.test.data-store.contacts
|
||||
'status-im.test.data-store.core
|
||||
'status-im.test.data-store.realm.core
|
||||
|
@ -133,6 +136,7 @@
|
|||
'status-im.test.signing.core
|
||||
'status-im.test.signing.gas
|
||||
'status-im.test.transport.core
|
||||
'status-im.test.transport.utils
|
||||
'status-im.test.tribute-to-talk.core
|
||||
'status-im.test.tribute-to-talk.db
|
||||
'status-im.test.tribute-to-talk.whitelist
|
||||
|
|
|
@ -81,42 +81,42 @@
|
|||
initial-cofx {:db {:chats {chat-id {:messages {message-id {:from from}}}}}}]
|
||||
|
||||
(testing "a single envelope message"
|
||||
(let [cofx (message/set-message-envelope-hash initial-cofx chat-id message-id :message-type "hash-1" 1)]
|
||||
(let [cofx (message/set-message-envelope-hash initial-cofx chat-id message-id :message-type 1)]
|
||||
(testing "it sets the message-infos"
|
||||
(is (= {:chat-id chat-id
|
||||
:message-id message-id
|
||||
:message-type :message-type}
|
||||
(get-in cofx [:db :transport/message-envelopes "hash-1"]))))
|
||||
(get-in cofx [:db :transport/message-envelopes message-id]))))
|
||||
(testing "the message is sent"
|
||||
(is (= :sent
|
||||
(get-in
|
||||
(message/update-envelope-status cofx "hash-1" :sent)
|
||||
(message/update-envelope-status cofx message-id :sent)
|
||||
[:db :chats chat-id :messages message-id :outgoing-status]))))
|
||||
|
||||
(testing "the message is not sent"
|
||||
(is (= :not-sent
|
||||
(get-in
|
||||
(message/update-envelope-status cofx "hash-1" :not-sent)
|
||||
(message/update-envelope-status cofx message-id :not-sent)
|
||||
[:db :chats chat-id :messages message-id :outgoing-status]))))))
|
||||
(testing "multi envelope message"
|
||||
(testing "only inserts"
|
||||
(let [cofx (fx/merge
|
||||
initial-cofx
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-1" 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-2" 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-3" 3))]
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3))]
|
||||
(testing "it sets the message count"
|
||||
(is (= {:pending-confirmations 3}
|
||||
(get-in cofx [:db :transport/message-ids->confirmations message-id]))))))
|
||||
(testing "message sent correctly"
|
||||
(let [cofx (fx/merge
|
||||
initial-cofx
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-1" 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-2" 3)
|
||||
(message/update-envelope-status "hash-1" :sent)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-3" 3)
|
||||
(message/update-envelope-status "hash-2" :sent)
|
||||
(message/update-envelope-status "hash-3" :sent))]
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/update-envelope-status message-id :sent)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/update-envelope-status message-id :sent)
|
||||
(message/update-envelope-status message-id :sent))]
|
||||
(testing "it removes the confirmations"
|
||||
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
|
||||
(testing "the message is sent"
|
||||
|
@ -127,12 +127,12 @@
|
|||
(testing "message not sent"
|
||||
(let [cofx (fx/merge
|
||||
initial-cofx
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-1" 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-2" 3)
|
||||
(message/update-envelope-status "hash-1" :sent)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type "hash-3" 3)
|
||||
(message/update-envelope-status "hash-2" :not-sent)
|
||||
(message/update-envelope-status "hash-3" :sent))]
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/update-envelope-status message-id :sent)
|
||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
||||
(message/update-envelope-status message-id :not-sent)
|
||||
(message/update-envelope-status message-id :sent))]
|
||||
(testing "it removes the confirmations"
|
||||
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
|
||||
(testing "the message is sent"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
(ns status-im.test.transport.utils
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.transport.utils :as transport]))
|
||||
|
||||
(deftest test-message-id
|
||||
(testing "test"
|
||||
(let [pk "0x03d0370306168850aa1f06a2f22c9a756c7dd00e35dd797fcdf351e53ff6ae7b9f"
|
||||
payload "0x74657374"
|
||||
expected-message-id "0x642b7f39873aab69d5aee686f4ed0ca02f82e025242ea57569a70640a94aea34"]
|
||||
(is (= expected-message-id (transport/message-id pk payload))))))
|
Loading…
Reference in New Issue