fix bugs at adding/removing to/from group chat related to inconsistent order of incoming messages

This commit is contained in:
Roman Volosovskyi 2016-12-02 18:59:14 +02:00
parent e06ef1cd68
commit 3d72c6f300
4 changed files with 71 additions and 58 deletions

View File

@ -586,17 +586,14 @@
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id keypair timestamp]} :payload}]] {:keys [group-id keypair timestamp]} :payload}]]
(let [{:keys [private public]} keypair] (let [{:keys [private public]} keypair]
(let [{:keys [updated-at removed-at]} (chats/get-by-id group-id) (let [is-active (chats/is-active? group-id)
is-active (chats/is-active? group-id)
chat {:chat-id group-id chat {:chat-id group-id
:public-key public :public-key public
:private-key private :private-key private
:updated-at timestamp}] :updated-at timestamp}]
(when (and (= from (get-in chats [group-id :group-admin])) (when (and (= from (get-in chats [group-id :group-admin]))
(or (not (chats/exists? group-id)) (or (not (chats/exists? group-id))
is-active (chats/new-update? timestamp group-id)))
(> timestamp removed-at)
(> timestamp updated-at)))
(dispatch [:update-chat! chat]) (dispatch [:update-chat! chat])
(when is-active (when is-active
(protocol/start-watching-group! (protocol/start-watching-group!

View File

@ -71,3 +71,13 @@
(defn set-active (defn set-active
[chat-id active?] [chat-id active?]
(save-property chat-id :is-active active?)) (save-property chat-id :is-active active?))
(defn new-update?
[timestamp chat-id]
(let
[{:keys [added-to-at removed-at removed-from-at added-at]}
(get-by-id chat-id)]
(and (> timestamp added-to-at)
(> timestamp removed-at)
(> timestamp removed-from-at)
(> timestamp added-at))))

View File

@ -97,24 +97,25 @@
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id group-name contacts keypair timestamp]} :payload}]] {:keys [group-id group-name contacts keypair timestamp]} :payload}]]
(let [{:keys [private public]} keypair] (let [{:keys [private public]} keypair]
(let [removed-at (chats/removed-at group-id) (let [contacts' (keep (fn [ident]
contacts' (keep (fn [ident] (when (not= ident current-public-key)
(when (not= ident current-public-key) {:identity ident})) contacts)
{:identity ident})) contacts) chat {:chat-id group-id
chat {:name group-name :name group-name
:group-chat true :group-chat true
:group-admin from :group-admin from
:public-key public :public-key public
:private-key private :private-key private
:contacts contacts' :contacts contacts'
:added-to-at timestamp :added-to-at timestamp
:timestamp timestamp :timestamp timestamp
:is-active true} :is-active true}
{:keys [removed-from-at] :as chat-from-db} (chats/get-by-id group-id)]
(when (or (not chat-from-db) exists? (chats/exists? group-id)]
(and (> timestamp removed-at) (when (or (not exists?) (chats/new-update? timestamp group-id))
(> timestamp removed-from-at))) (if exists?
(dispatch [:add-chat group-id chat]) (dispatch [:update-chat! chat])
(dispatch [:add-chat group-id chat]))
(protocol/start-watching-group! (protocol/start-watching-group!
{:web3 web3 {:web3 web3
:group-id group-id :group-id group-id

View File

@ -101,11 +101,13 @@
(dispatch [:message-sent message'])) (dispatch [:message-sent message']))
(debug "Unknown message type" type))))) (debug "Unknown message type" type)))))
(defn system-message [message-id content] (defn system-message
{:from "system" ([message-id timestamp content]
:message-id message-id {:from "system"
:content content :message-id message-id
:content-type text-content-type}) :timestamp timestamp
:content content
:content-type text-content-type}))
(defn joined-chat-message [chat-id from message-id] (defn joined-chat-message [chat-id from message-id]
(let [contact-name (:name (contacts/get-by-id from))] (let [contact-name (:name (contacts/get-by-id from))]
@ -114,32 +116,36 @@
:content (str (or contact-name from) " " (label :t/received-invitation)) :content (str (or contact-name from) " " (label :t/received-invitation))
:content-type text-content-type}))) :content-type text-content-type})))
(defn participant-invited-to-group-message [chat-id current-identity identity from message-id] (defn participant-invited-to-group-message [chat-id current-identity identity from message-id timestamp]
(let [inviter-name (:name (contacts/get-by-id from)) (let [inviter-name (:name (contacts/get-by-id from))
invitee-name (if (= identity current-identity) invitee-name (if (= identity current-identity)
(label :t/You) (label :t/You)
(:name (contacts/get-by-id identity)))] (:name (contacts/get-by-id identity)))]
{:from "system" {:from "system"
:group-id chat-id :group-id chat-id
:timestamp timestamp
:message-id message-id :message-id message-id
:content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity)) :content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity))
:content-type text-content-type})) :content-type text-content-type}))
(defn participant-removed-from-group-message [identity from message-id] (defn participant-removed-from-group-message
[identity from {:keys [message-id timestamp]}]
(let [remover-name (:name (contacts/get-by-id from)) (let [remover-name (:name (contacts/get-by-id from))
removed-name (:name (contacts/get-by-id identity))] removed-name (:name (contacts/get-by-id identity))]
(->> (str (or remover-name from) " " (label :t/removed) " " (or removed-name identity)) (->> (str (or remover-name from) " " (label :t/removed) " " (or removed-name identity))
(system-message message-id)))) (system-message message-id timestamp))))
(defn you-removed-from-group-message [from message-id] (defn you-removed-from-group-message
[from {:keys [message-id timestamp]}]
(let [remover-name (:name (contacts/get-by-id from))] (let [remover-name (:name (contacts/get-by-id from))]
(->> (str (or remover-name from) " " (label :t/removed-from-chat)) (->> (str (or remover-name from) " " (label :t/removed-from-chat))
(system-message message-id)))) (system-message message-id timestamp))))
(defn participant-left-group-message [chat-id from message-id] (defn participant-left-group-message
[chat-id from {:keys [message-id timestamp]}]
(let [left-name (:name (contacts/get-by-id from))] (let [left-name (:name (contacts/get-by-id from))]
(->> (str (or left-name from) " " (label :t/left)) (->> (str (or left-name from) " " (label :t/left))
(system-message message-id) (system-message message-id timestamp)
(messages/save chat-id)))) (messages/save chat-id))))
(register-handler :group-chat-invite-acked (register-handler :group-chat-invite-acked
@ -151,9 +157,9 @@
(register-handler :participant-removed-from-group (register-handler :participant-removed-from-group
(u/side-effect! (u/side-effect!
(fn [{:keys [current-public-key chats]} (fn [{:keys [current-public-key chats]}
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id identity message-id]} :payload {:keys [group-id identity message-id] :as payload} :payload
:as message}]] :as message}]]
(when-not (messages/get-by-id message-id) (when-not (messages/get-by-id message-id)
(let [admin (get-in chats [group-id :group-admin])] (let [admin (get-in chats [group-id :group-admin])]
(when (= admin from) (when (= admin from)
@ -161,7 +167,7 @@
(dispatch [::you-removed-from-group message]) (dispatch [::you-removed-from-group message])
(let [message (let [message
(assoc (assoc
(participant-removed-from-group-message identity from message-id) (participant-removed-from-group-message identity from payload)
:group-id group-id)] :group-id group-id)]
(chats/remove-contacts group-id [identity]) (chats/remove-contacts group-id [identity])
(dispatch [:received-message message]))))))))) (dispatch [:received-message message])))))))))
@ -169,29 +175,28 @@
(register-handler ::you-removed-from-group (register-handler ::you-removed-from-group
(u/side-effect! (u/side-effect!
(fn [{:keys [web3]} (fn [{:keys [web3]}
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id message-id timestamp]} :payload}]] {:keys [group-id timestamp] :as payload} :payload}]]
(let [{:keys [added-to-at]} (chats/get-by-id group-id)] (when (chats/new-update? timestamp group-id)
(when (> timestamp added-to-at) (let [message
(let [message (-> (you-removed-from-group-message from payload)
(-> (you-removed-from-group-message from message-id) (assoc :group-id group-id))]
(assoc :group-id group-id))] (dispatch [:received-message message]))
(dispatch [:received-message message])) (protocol/stop-watching-group! {:web3 web3
(protocol/stop-watching-group! {:web3 web3 :group-id group-id})
:group-id group-id}) (dispatch [:update-chat! {:chat-id group-id
(dispatch [:update-chat! {:chat-id group-id :removed-from-at timestamp
:removed-from-at timestamp :is-active false}])))))
:is-active false}]))))))
(register-handler :participant-left-group (register-handler :participant-left-group
(u/side-effect! (u/side-effect!
(fn [{:keys [current-public-key]} (fn [{:keys [current-public-key]}
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id message-id timestamp]} :payload}]] {:keys [group-id timestamp] :as payload} :payload}]]
(when (and (not= current-public-key from) (when (and (not= current-public-key from)
(chats/is-active? group-id) (chats/is-active? group-id)
(> timestamp (chats/get-property group-id :timestamp))) (> timestamp (chats/get-property group-id :timestamp)))
(participant-left-group-message group-id from message-id) (participant-left-group-message group-id from payload)
(dispatch [::remove-identity-from-chat group-id from]) (dispatch [::remove-identity-from-chat group-id from])
(dispatch [::remove-identity-from-chat! group-id from]))))) (dispatch [::remove-identity-from-chat! group-id from])))))
@ -209,13 +214,13 @@
(register-handler :participant-invited-to-group (register-handler :participant-invited-to-group
(u/side-effect! (u/side-effect!
(fn [{:keys [current-public-key chats]} (fn [{:keys [current-public-key chats]}
[_ {:keys [from] [_ {:keys [from]
{:keys [group-id identity message-id]} :payload}]] {:keys [group-id identity message-id timestamp]} :payload}]]
(let [admin (get-in chats [group-id :group-admin])] (let [admin (get-in chats [group-id :group-admin])]
(when (= from admin) (when (= from admin)
(dispatch (dispatch
[:received-message [:received-message
(participant-invited-to-group-message group-id current-public-key identity from message-id)]) (participant-invited-to-group-message group-id current-public-key identity from message-id timestamp)])
(when-not (= current-public-key identity) (when-not (= current-public-key identity)
(dispatch [:add-contact-to-group! group-id identity]))))))) (dispatch [:add-contact-to-group! group-id identity])))))))