Skip to content

Commit

Permalink
Merge pull request #11678 from nextcloud/followup/11674/frontend-util…
Browse files Browse the repository at this point in the history
…izing-the-return-data

feat(federation): Use the returned data from POST|DELETE of /…/read requests
  • Loading branch information
Antreesy committed Mar 14, 2024
2 parents b553b17 + 1a7460b commit 8b1f791
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,6 @@ describe('MessageButtonsBar.vue', () => {
id: 100,
updateVisually: true,
})

expect(fetchConversationAction).toHaveBeenCalledWith(expect.anything(), {
token: TOKEN,
})
})

test('copies message link', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,6 @@ export default {
id: this.previousMessageId,
updateVisually: true,
})
// reload conversation to update additional attributes that have computed values
await this.$store.dispatch('fetchConversation', { token: this.token })
},
handleReactionClick(selectedEmoji) {
Expand Down
13 changes: 2 additions & 11 deletions src/store/conversationsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,23 +649,14 @@ const actions = {
commit('addConversation', conversation)
},

async markConversationRead({ commit, getters }, token) {
if (!getters.conversations[token]) {
return
}

commit('updateUnreadMessages', { token, unreadMessages: 0, unreadMention: false, unreadMentionDirect: false })
},

async markConversationUnread({ commit, dispatch, getters }, { token }) {
if (!getters.conversations[token]) {
return
}

try {
await setConversationUnread(token)
commit('updateUnreadMessages', { token, unreadMessages: 1 })
await dispatch('fetchConversation', { token })
const response = await setConversationUnread(token)
dispatch('addConversation', response.data.ocs.data)
} catch (error) {
console.error('Error while setting the conversation as unread: ', error)
}
Expand Down
34 changes: 27 additions & 7 deletions src/store/conversationsStore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
setCallPermissions,
setConversationUnread,
} from '../services/conversationsService.js'
import { updateLastReadMessage } from '../services/messagesService.js'
import { useTalkHashStore } from '../stores/talkHash.js'
import { generateOCSErrorResponse, generateOCSResponse } from '../test-helpers.js'

Expand All @@ -58,6 +59,10 @@ jest.mock('../services/conversationsService', () => ({
setConversationUnread: jest.fn(),
}))

jest.mock('../services/messagesService', () => ({
updateLastReadMessage: jest.fn(),
}))

jest.mock('@nextcloud/event-bus')

jest.mock('../services/BrowserStorage.js', () => ({
Expand Down Expand Up @@ -99,6 +104,7 @@ describe('conversationsStore', () => {
actorId: 'actor-id',
defaultPermissions: PARTICIPANT.PERMISSIONS.CUSTOM,
callPermissions: PARTICIPANT.PERMISSIONS.CUSTOM,
lastMessage: { ...previousLastMessage },
}

testStoreConfig = cloneDeep(storeConfig)
Expand Down Expand Up @@ -914,34 +920,48 @@ describe('conversationsStore', () => {
describe('read marker', () => {
beforeEach(() => {
store = new Vuex.Store(testStoreConfig)
store.commit('setUserId', 'current-user')
})

test('marks conversation as read by clearing unread counters', () => {
test('marks conversation as read by clearing unread counters', async () => {
// Arrange
testConversation.unreadMessages = 1024
testConversation.unreadMention = true

store.dispatch('addConversation', testConversation)

store.dispatch('markConversationRead', testToken)
const response = generateOCSResponse({
payload: {
...testConversation,
unreadMessages: 0,
unreadMention: false,
}
})
updateLastReadMessage.mockResolvedValue(response)

// Act
store.dispatch('clearLastReadMessage', { token: testToken })
await flushPromises()

// Assert
const changedConversation = store.getters.conversation(testToken)
expect(changedConversation.unreadMessages).toBe(0)
expect(changedConversation.unreadMention).toBe(false)
})

test('marks conversation as unread', async () => {
// Arrange
testConversation.unreadMessages = 0
store.dispatch('addConversation', testConversation)

const response = generateOCSResponse({ payload: { ...testConversation, unreadMessages: 1 } })
fetchConversation.mockResolvedValue(response)
store.dispatch('markConversationUnread', { token: testToken })
setConversationUnread.mockResolvedValue(response)

// Act
store.dispatch('markConversationUnread', { token: testToken })
await flushPromises()

// Assert
expect(setConversationUnread).toHaveBeenCalledWith(testConversation.token)
expect(fetchConversation).toHaveBeenCalledWith(testConversation.token)

const changedConversation = store.getters.conversation(testToken)
expect(changedConversation.unreadMessages).toBe(1)
})
Expand Down
24 changes: 16 additions & 8 deletions src/store/messagesStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import SHA256 from 'crypto-js/sha256.js'
import cloneDeep from 'lodash/cloneDeep.js'
import Vue from 'vue'

import { getCapabilities } from '@nextcloud/capabilities'
import { showError } from '@nextcloud/dialogs'

import {
Expand All @@ -49,6 +50,8 @@ import { useReactionsStore } from '../stores/reactions.js'
import { useSharedItemsStore } from '../stores/sharedItems.js'
import CancelableRequest from '../utils/cancelableRequest.js'

const markAsReadWithoutLast = getCapabilities()?.spreed?.features?.includes('chat-read-last')

/**
* Returns whether the given message contains a mention to self, directly
* or indirectly through a global mention.
Expand Down Expand Up @@ -817,17 +820,20 @@ const actions = {
*
* @param {object} context default store context;
* @param {object} data the wrapping object;
* @param {object} data.token the token of the conversation to be updated;
* @param {string} data.token the token of the conversation to be updated;
* @param {boolean} data.updateVisually whether to also clear the marker visually in the UI;
*/
async clearLastReadMessage(context, { token, updateVisually = false }) {
const conversation = context.getters.conversations[token]
if (!conversation || !conversation.lastMessage) {
const conversation = context.getters.conversation(token)
if (markAsReadWithoutLast) {
context.dispatch('updateLastReadMessage', { token, id: null, updateVisually })
return
}
if (!conversation?.lastMessage?.id) {
return
}
// set the id to the last message
context.dispatch('updateLastReadMessage', { token, id: conversation.lastMessage.id, updateVisually })
context.dispatch('markConversationRead', token)
},

/**
Expand All @@ -836,18 +842,19 @@ const actions = {
*
* @param {object} context default store context;
* @param {object} data the wrapping object;
* @param {object} data.token the token of the conversation to be updated;
* @param {number} data.id the id of the message on which to set the read marker;
* @param {string} data.token the token of the conversation to be updated;
* @param {number|null} data.id the id of the message on which to set the read marker;
* @param {boolean} data.updateVisually whether to also update the marker visually in the UI;
*/
async updateLastReadMessage(context, { token, id = 0, updateVisually = false }) {
const conversation = context.getters.conversations[token]
const conversation = context.getters.conversation(token)
if (!conversation || conversation.lastReadMessage === id) {
return
}

if (id === 0) {
console.warn('updateLastReadMessage: should not set read marker with id=0')
return
}

// optimistic early commit to avoid indicator flickering
Expand All @@ -858,7 +865,8 @@ const actions = {

if (context.getters.getUserId()) {
// only update on server side if there's an actual user, not guest
await updateLastReadMessage(token, id)
const response = await updateLastReadMessage(token, id)
context.dispatch('addConversation', response.data.ocs.data)
}
},

Expand Down

0 comments on commit 8b1f791

Please sign in to comment.