Skip to content

Commit

Permalink
fix(messagesStore): ease messages list around last read message
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy authored and backportbot[bot] committed Jan 27, 2025
1 parent a64d6ea commit a72a8de
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
25 changes: 21 additions & 4 deletions src/store/messagesStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,26 +490,42 @@ const mutations = {
})
},

easeMessageList(state, { token }) {
easeMessageList(state, { token, lastReadMessage }) {
if (!state.messages[token]) {
return
}

const messageIds = Object.keys(state.messages[token])
const messageIds = Object.keys(state.messages[token]).sort((a, b) => b - a)
if (messageIds.length < 300) {
return
}

const messagesToRemove = messageIds.sort((a, b) => b - a).slice(199)
// If lastReadMessage is rendered, keep it and +- 100 messages, otherwise only newest 200 messages
const lastReadMessageIndex = messageIds.findIndex(id => +id === lastReadMessage)

const messagesToRemove = lastReadMessageIndex !== -1
? messageIds.slice(lastReadMessageIndex + 99)
: messageIds.slice(199)
const newFirstKnown = messagesToRemove.shift()

const newMessagesToRemove = (lastReadMessageIndex !== -1 && lastReadMessageIndex > 100)
? messageIds.slice(0, lastReadMessageIndex - 99)
: []
const newLastKnown = newMessagesToRemove.pop()

messagesToRemove.forEach((messageId) => {
Vue.delete(state.messages[token], messageId)
})
newMessagesToRemove.forEach((messageId) => {
Vue.delete(state.messages[token], messageId)
})

if (state.firstKnown[token] && messagesToRemove.includes(state.firstKnown[token].toString())) {
Vue.set(state.firstKnown, token, +newFirstKnown)
}
if (state.lastKnown[token] && newMessagesToRemove.includes(state.lastKnown[token].toString())) {
Vue.set(state.lastKnown, token, +newLastKnown)
}
},
}

Expand Down Expand Up @@ -1378,7 +1394,8 @@ const actions = {
},

async easeMessageList(context, { token }) {
context.commit('easeMessageList', { token })
const lastReadMessage = context.getters.conversation(token)?.lastReadMessage
context.commit('easeMessageList', { token, lastReadMessage })
},

loadedMessagesOfConversation(context, { token }) {
Expand Down
28 changes: 23 additions & 5 deletions src/store/messagesStore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,28 @@ describe('messagesStore', () => {
})

const testCases = [
[1, 200, 1, 200],
[1, 400, 201, 400],
// Default
[1, 200, 1, 200, 200, undefined],
[1, 400, 201, 400, 200, undefined],
// with lastReadMessage
[201, 600, 401, 600, 200, 200],
[1, 400, 101, 300, 200, 200],
[1, 400, 201, 400, 200, 300],
// Border values
[1, 400, 1, 101, 101, 1],
[1, 400, 301, 400, 100, 400],
[1, 400, 1, 199, 199, 99],
[1, 400, 1, 200, 200, 100],
[1, 400, 2, 201, 200, 101],
[1, 400, 202, 400, 199, 301],
[1, 400, 201, 400, 200, 300],
[1, 400, 200, 399, 200, 299],
]

it.each(testCases)('eases messages list from %s - %s to %s - %s',
(oldFirst, oldLast, newFirst, newLast) => {
it.each(testCases)('eases list from [%s - %s] to [%s - %s] (length: %s) with lastReadMessage %s',
(oldFirst, oldLast, newFirst, newLast, length, lastReadMessage) => {
// Arrange
conversationMock.mockReturnValue({ lastReadMessage })
for (let id = oldFirst; id <= oldLast; id++) {
store.dispatch('processMessage', { token: TOKEN, message: { token: TOKEN, id } })
}
Expand All @@ -308,11 +323,14 @@ describe('messagesStore', () => {
store.dispatch('easeMessageList', { token: TOKEN })

// Assert
expect(store.getters.messagesList(TOKEN)).toHaveLength(200)
expect(store.getters.messagesList(TOKEN)).toHaveLength(length)
expect(store.getters.messagesList(TOKEN).at(0)).toStrictEqual({ token: TOKEN, id: newFirst })
expect(store.getters.messagesList(TOKEN).at(-1)).toStrictEqual({ token: TOKEN, id: newLast })
expect(store.getters.getFirstKnownMessageId(TOKEN)).toStrictEqual(newFirst)
expect(store.getters.getLastKnownMessageId(TOKEN)).toStrictEqual(newLast)
if (oldFirst < lastReadMessage && lastReadMessage < oldLast) {
expect(store.getters.message(TOKEN, lastReadMessage)).toBeDefined()
}
})
})

Expand Down

0 comments on commit a72a8de

Please sign in to comment.