diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.spec.js b/src/components/LeftSidebar/ConversationsList/Conversation.spec.js index 4ba6b58c529..ce09fa78a88 100644 --- a/src/components/LeftSidebar/ConversationsList/Conversation.spec.js +++ b/src/components/LeftSidebar/ConversationsList/Conversation.spec.js @@ -137,7 +137,7 @@ describe('Conversation.vue', () => { }) test('displays nothing when there is no last chat message', () => { - item.lastMessage = {} + delete item.lastMessage testConversationLabel(item, 'No messages') }) diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.vue b/src/components/LeftSidebar/ConversationsList/Conversation.vue index 67b1a95a5d0..2c5ecb2f3d9 100644 --- a/src/components/LeftSidebar/ConversationsList/Conversation.vue +++ b/src/components/LeftSidebar/ConversationsList/Conversation.vue @@ -284,7 +284,6 @@ export default { type: 0, displayName: '', isFavorite: false, - lastMessage: {}, notificationLevel: PARTICIPANT.NOTIFY.DEFAULT, notificationCalls: PARTICIPANT.NOTIFY_CALLS.ON, canDeleteConversation: false, diff --git a/src/components/LeftSidebar/ConversationsList/ConversationSearchResult.vue b/src/components/LeftSidebar/ConversationsList/ConversationSearchResult.vue index 788c6c70286..41aee3fd9d3 100644 --- a/src/components/LeftSidebar/ConversationsList/ConversationSearchResult.vue +++ b/src/components/LeftSidebar/ConversationsList/ConversationSearchResult.vue @@ -54,7 +54,6 @@ export default { displayName: '', isFavorite: false, notificationLevel: 0, - lastMessage: {}, } }, }, diff --git a/src/components/LeftSidebar/LeftSidebar.spec.js b/src/components/LeftSidebar/LeftSidebar.spec.js index 4f28d1b59ca..4c5dfacf264 100644 --- a/src/components/LeftSidebar/LeftSidebar.spec.js +++ b/src/components/LeftSidebar/LeftSidebar.spec.js @@ -225,7 +225,6 @@ describe('LeftSidebar.vue', () => { isFavorite: false, name: 'one', displayName: 'the searched one by display name', - lastMessage: {}, }, { id: 200, token: 't200', @@ -233,7 +232,6 @@ describe('LeftSidebar.vue', () => { isFavorite: false, name: 'searched by name', displayName: 'another one', - lastMessage: {}, }, { id: 300, token: 't300', @@ -241,20 +239,17 @@ describe('LeftSidebar.vue', () => { isFavorite: true, name: 'excluded', displayName: 'excluded from results', - lastMessage: {}, }] listedResults = [{ id: 1000, name: 'listed one searched', displayName: 'listed one searched', - lastMessage: {}, token: 'listed-token-1', }, { id: 1001, name: 'listed two searched', displayName: 'listed two searched', - lastMessage: {}, token: 'listed-token-2', }] usersResults = [{ diff --git a/src/composables/useConversationInfo.js b/src/composables/useConversationInfo.js index 8e6404e8363..f94280ce429 100644 --- a/src/composables/useConversationInfo.js +++ b/src/composables/useConversationInfo.js @@ -43,7 +43,7 @@ export function useConversationInfo({ }) const hasLastMessage = computed(() => { - return !!Object.keys(Object(item.value?.lastMessage)).length + return !!item.value?.lastMessage && !!Object.keys(Object(item.value?.lastMessage)).length }) /** diff --git a/src/store/conversationsStore.js b/src/store/conversationsStore.js index 2a16c8465d5..fa83bb010a4 100644 --- a/src/store/conversationsStore.js +++ b/src/store/conversationsStore.js @@ -317,6 +317,13 @@ const actions = { updateConversationIfHasChanged(context, conversation) { const oldConversation = context.state.conversations[conversation.token] + // Update conversation if the number of attributes differ + // (e.g. lastMessage was added or removed, because we don't keep lastMessage as an empty object) + if (Object.keys(oldConversation).length !== Object.keys(conversation).length) { + context.commit('updateConversation', conversation) + return true + } + // Update 1-1 conversation, if its status was changed if (conversation.type === CONVERSATION.TYPE.ONE_TO_ONE && (oldConversation.status !== conversation.status @@ -336,7 +343,7 @@ const actions = { return true } - // Check if any property were changed (no properties except status-related supposed to be added or deleted) + // Check if any property were changed (no properties except status-related and lastMessage supposed to be added or deleted) for (const key of Object.keys(conversation)) { // "lastMessage" is the only property with non-primitive (object) value and cannot be compared by === // If "lastMessage" was actually changed, it is already checked by "lastActivity" @@ -760,8 +767,8 @@ const actions = { } const conversation = Object.assign({}, getters.conversations[token]) - if (conversation.lastMessage.id === parseInt(messageId, 10) - || conversation.lastMessage.timestamp >= Date.parse(notification.datetime) / 1000) { + if (conversation.lastMessage?.id === parseInt(messageId, 10) + || conversation.lastMessage?.timestamp >= Date.parse(notification.datetime) / 1000) { // Already updated from other source, skipping return } diff --git a/src/store/messagesStore.js b/src/store/messagesStore.js index 9eb625a6276..b4b34c8c344 100644 --- a/src/store/messagesStore.js +++ b/src/store/messagesStore.js @@ -151,7 +151,7 @@ const getters = { return false } - return getters.getLastKnownMessageId(token) < conversation.lastMessage.id + return getters.getLastKnownMessageId(token) < conversation.lastMessage?.id }, isMessagesListPopulated: (state) => (token) => { @@ -552,7 +552,7 @@ const actions = { if (message.systemMessage === 'message_edited' || message.systemMessage === 'message_deleted') { // update conversation lastMessage, if it was edited or deleted - if (message.parent.id === context.getters.conversation(token).lastMessage.id) { + if (message.parent.id === context.getters.conversation(token).lastMessage?.id) { context.dispatch('updateConversationLastMessage', { token, lastMessage: message.parent }) } // Check existing messages for having a deleted / edited message as parent, and update them @@ -1118,7 +1118,7 @@ const actions = { // Overwrite the conversation.hasCall property so people can join // after seeing the message in the chat. - if (conversation && conversation.lastMessage && message.id > conversation.lastMessage.id) { + if (conversation?.lastMessage && message.id > conversation.lastMessage.id) { if (['call_started', 'call_ended', 'call_ended_everyone', 'call_missed'].includes(message.systemMessage)) { context.dispatch('overwriteHasCallByChat', { token, @@ -1150,7 +1150,7 @@ const actions = { id: parseInt(response.headers['x-chat-last-given'], 10), }) - if (conversation && conversation.lastMessage && lastMessage.id > conversation.lastMessage.id) { + if (conversation?.lastMessage && lastMessage.id > conversation.lastMessage.id) { context.dispatch('updateConversationLastMessage', { token, lastMessage, @@ -1237,7 +1237,7 @@ const actions = { // update lastMessage and lastReadMessage // do it conditionally because there could have been more messages appearing concurrently - if (conversation && conversation.lastMessage && message.id > conversation.lastMessage.id) { + if (conversation?.lastMessage && message.id > conversation.lastMessage.id) { context.dispatch('updateConversationLastMessage', { token, lastMessage: message, diff --git a/src/utils/getMessageIcon.ts b/src/utils/getMessageIcon.ts index dcee379afb0..80112093388 100644 --- a/src/utils/getMessageIcon.ts +++ b/src/utils/getMessageIcon.ts @@ -22,10 +22,10 @@ const iconSvgTemplate = (path: string) => { } export const getMessageIcon = (lastMessage: Conversation['lastMessage']): string => { - if (Array.isArray(lastMessage)) { + if (!lastMessage || Array.isArray(lastMessage)) { return '' } - const file = lastMessage?.messageParameters?.file + const file = lastMessage.messageParameters?.file if (file) { if (file.mimetype?.startsWith('video')) { return iconSvgTemplate(mdiMovie) // Media - Videos