Fix incorrect loading of messages
In some instances when receiving messages from a mailsever in the chat you are in, the flag `all-loaded?` would not be reset, meaning that messages not in the current view would be added to the db, but would not be seen until actually reloading the chat (go back home, open again). Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
749faaeb1b
commit
a914334fed
|
@ -162,7 +162,7 @@
|
||||||
(when-let [current-chat-id (:current-chat-id db)]
|
(when-let [current-chat-id (:current-chat-id db)]
|
||||||
(if-not (get-in db [:chats current-chat-id :messages-initialized?])
|
(if-not (get-in db [:chats current-chat-id :messages-initialized?])
|
||||||
(do
|
(do
|
||||||
; reset chat viewable-items state
|
; reset chat first-not-visible-items state
|
||||||
(chat.state/reset)
|
(chat.state/reset)
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
|
|
|
@ -104,33 +104,32 @@
|
||||||
|
|
||||||
(fx/defn add-received-message
|
(fx/defn add-received-message
|
||||||
[{:keys [db] :as cofx}
|
[{:keys [db] :as cofx}
|
||||||
{:keys [from
|
{:keys [chat-id
|
||||||
message-id
|
clock-value] :as message}]
|
||||||
chat-id
|
|
||||||
clock-value
|
|
||||||
content] :as message}]
|
|
||||||
(let [{:keys [loaded-chat-id
|
(let [{:keys [loaded-chat-id
|
||||||
view-id
|
view-id
|
||||||
current-chat-id]} db
|
current-chat-id]} db
|
||||||
cursor-clock-value (get-in db [:chats current-chat-id :cursor-clock-value])
|
cursor-clock-value (get-in db [:chats current-chat-id :cursor-clock-value])
|
||||||
current-chat? (= chat-id loaded-chat-id)]
|
current-chat? (= chat-id loaded-chat-id)]
|
||||||
(when (and current-chat?
|
(when current-chat?
|
||||||
(or (not cursor-clock-value)
|
;; If we don't have any hidden message or the hidden message is before
|
||||||
(<= cursor-clock-value clock-value)))
|
;; this one, we add the message to the UI
|
||||||
(if (or (not @view.state/viewable-item)
|
(if (or (not @view.state/first-not-visible-item)
|
||||||
(not= current-chat-id
|
(<= (:clock-value @view.state/first-not-visible-item)
|
||||||
(:chat-id @view.state/viewable-item))
|
|
||||||
(<= (:clock-value @view.state/viewable-item)
|
|
||||||
clock-value))
|
clock-value))
|
||||||
(add-message cofx {:message message
|
(add-message cofx {:message message
|
||||||
:seen-by-user? (and current-chat?
|
:seen-by-user? (and current-chat?
|
||||||
(= view-id :chat))})
|
(= view-id :chat))})
|
||||||
;; Not in the current view, offload to db and update cursor if necessary
|
;; Not in the current view, set all-loaded to false
|
||||||
(when (and (< clock-value
|
;; and offload to db and update cursor if necessary
|
||||||
cursor-clock-value)
|
{:db (cond-> db
|
||||||
(= current-chat-id
|
(>= clock-value
|
||||||
(:chat-id @view.state/viewable-item)))
|
cursor-clock-value)
|
||||||
{:db (assoc-in db [:chats chat-id :cursor] (chat-loading/clock-value->cursor clock-value))})))))
|
(update-in [:chats chat-id] assoc
|
||||||
|
:cursor (chat-loading/clock-value->cursor clock-value)
|
||||||
|
:cursor-clock-value clock-value)
|
||||||
|
:always
|
||||||
|
(assoc-in [:chats chat-id :all-loaded?] false))}))))
|
||||||
|
|
||||||
(defn- add-to-chat?
|
(defn- add-to-chat?
|
||||||
[{:keys [db]} {:keys [chat-id clock-value message-id from]}]
|
[{:keys [db]} {:keys [chat-id clock-value message-id from]}]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns status-im.ui.screens.chat.state)
|
(ns status-im.ui.screens.chat.state)
|
||||||
|
|
||||||
(defonce viewable-item (atom nil))
|
(defonce first-not-visible-item (atom nil))
|
||||||
|
|
||||||
(defn reset []
|
(defn reset []
|
||||||
(reset! viewable-item nil))
|
(reset! first-not-visible-item nil))
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
|
|
||||||
(defn on-viewable-items-changed [e]
|
(defn on-viewable-items-changed [e]
|
||||||
(when @messages-list-ref
|
(when @messages-list-ref
|
||||||
(reset! state/viewable-item
|
(reset! state/first-not-visible-item
|
||||||
(when-let [last-visible-element (aget (.-viewableItems e) (dec (.-length (.-viewableItems e))))]
|
(when-let [last-visible-element (aget (.-viewableItems e) (dec (.-length (.-viewableItems e))))]
|
||||||
(let [index (.-index last-visible-element)
|
(let [index (.-index last-visible-element)
|
||||||
;; Get first not visible element, if it's a datemark/gap
|
;; Get first not visible element, if it's a datemark/gap
|
||||||
|
|
|
@ -3,13 +3,91 @@
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
[status-im.utils.identicon :as identicon]
|
[status-im.utils.identicon :as identicon]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.chat.models.loading :as chat-loading]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
[status-im.transport.message.protocol :as protocol]
|
[status-im.transport.message.protocol :as protocol]
|
||||||
[status-im.chat.models.message-list :as models.message-list]
|
[status-im.chat.models.message-list :as models.message-list]
|
||||||
|
[status-im.ui.screens.chat.state :as view.state]
|
||||||
[status-im.chat.models.message :as message]
|
[status-im.chat.models.message :as message]
|
||||||
[status-im.utils.datetime :as time]))
|
[status-im.utils.datetime :as time]))
|
||||||
|
|
||||||
|
(deftest add-received-message-test
|
||||||
|
(with-redefs [message/add-message (constantly :added)]
|
||||||
|
(let [chat-id "chat-id"
|
||||||
|
clock-value 10
|
||||||
|
cursor-clock-value (dec clock-value)
|
||||||
|
cursor (chat-loading/clock-value->cursor cursor-clock-value)
|
||||||
|
cofx {:now 0
|
||||||
|
:db {:loaded-chat-id chat-id
|
||||||
|
:current-chat-id chat-id
|
||||||
|
:all-loaded? true
|
||||||
|
:chats {chat-id {:cursor cursor
|
||||||
|
:cursor-clock-value cursor-clock-value}}}}
|
||||||
|
message {:chat-id chat-id
|
||||||
|
:clock-value clock-value}]
|
||||||
|
(testing "not current-chat"
|
||||||
|
(is (nil? (message/add-received-message
|
||||||
|
(update cofx :db dissoc :loaded-chat-id)
|
||||||
|
message))))
|
||||||
|
;; <- cursor
|
||||||
|
;; <- message
|
||||||
|
;; <- top of the chat
|
||||||
|
(testing "there's no hidden item"
|
||||||
|
(with-redefs [view.state/first-not-visible-item (atom nil)]
|
||||||
|
(is (= :added (message/add-received-message
|
||||||
|
cofx
|
||||||
|
message)))))
|
||||||
|
;; <- cursor
|
||||||
|
;; <- first-hidden-item
|
||||||
|
;; <- message
|
||||||
|
;; <- top of the chat
|
||||||
|
(testing "the hidden item has a clock value less than the current"
|
||||||
|
(with-redefs [view.state/first-not-visible-item (atom {:clock-value (dec clock-value)})]
|
||||||
|
(is (= :added (message/add-received-message
|
||||||
|
cofx
|
||||||
|
message)))))
|
||||||
|
;; <- cursor
|
||||||
|
;; <- message
|
||||||
|
;; <- first-hidden-item
|
||||||
|
;; <- top of the chat
|
||||||
|
(testing "the message falls between the first-hidden-item and cursor"
|
||||||
|
(with-redefs [view.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
|
||||||
|
(let [result (message/add-received-message
|
||||||
|
cofx
|
||||||
|
message)]
|
||||||
|
(testing "it sets all-loaded? to false"
|
||||||
|
(is (not (get-in result [:db :chats chat-id :all-loaded?]))))
|
||||||
|
(testing "it updates cursor-clock-value & cursor"
|
||||||
|
(is (= clock-value (get-in result [:db :chats chat-id :cursor-clock-value])))
|
||||||
|
(is (= (chat-loading/clock-value->cursor clock-value) (get-in result [:db :chats chat-id :cursor])))))))
|
||||||
|
;; <- message
|
||||||
|
;; <- first-hidden-item
|
||||||
|
;; <- top of the chat
|
||||||
|
(testing "the message falls between the first-hidden-item and cursor is nil"
|
||||||
|
(with-redefs [view.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
|
||||||
|
(let [result (message/add-received-message
|
||||||
|
(update-in cofx [:db :chats chat-id] dissoc :cursor :cursor-clock-value)
|
||||||
|
message)]
|
||||||
|
(testing "it sets all-loaded? to false"
|
||||||
|
(is (not (get-in result [:db :chats chat-id :all-loaded?]))))
|
||||||
|
(testing "it updates cursor-clock-value & cursor"
|
||||||
|
(is (= clock-value (get-in result [:db :chats chat-id :cursor-clock-value])))
|
||||||
|
(is (= (chat-loading/clock-value->cursor clock-value) (get-in result [:db :chats chat-id :cursor])))))))
|
||||||
|
;; <- message
|
||||||
|
;; <- cursor
|
||||||
|
;; <- first-hidden-item
|
||||||
|
;; <- top of the chat
|
||||||
|
(testing "the message falls before both the first-hidden-item and cursor"
|
||||||
|
(with-redefs [view.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
|
||||||
|
(let [result (message/add-received-message
|
||||||
|
cofx
|
||||||
|
(update message :clock-value #(- % 2)))]
|
||||||
|
(testing "it sets all-loaded? to false"
|
||||||
|
(is (not (get-in result [:db :chats chat-id :all-loaded?]))))
|
||||||
|
(testing "it does not update cursor-clock-value & cursor"
|
||||||
|
(is (= cursor-clock-value (get-in result [:db :chats chat-id :cursor-clock-value])))
|
||||||
|
(is (= cursor (get-in result [:db :chats chat-id :cursor]))))))))))
|
||||||
|
|
||||||
(deftest add-to-chat?
|
(deftest add-to-chat?
|
||||||
(testing "it returns true when it's not in loaded message"
|
(testing "it returns true when it's not in loaded message"
|
||||||
(is (message/add-to-chat? {:db {:chats {"a" {}}}}
|
(is (message/add-to-chat? {:db {:chats {"a" {}}}}
|
||||||
|
|
Loading…
Reference in New Issue