Skip to content

Commit

Permalink
Split input states and split groups at edited messages
Browse files Browse the repository at this point in the history
Signed-off-by: DorraJaouad <dorra.jaoued7@gmail.com>
  • Loading branch information
DorraJaouad committed Jan 12, 2024
1 parent 15cab80 commit 9389f8c
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 58 deletions.
7 changes: 2 additions & 5 deletions src/components/MessagesList/MessagesGroup/Message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -790,11 +790,8 @@ export default {
},
handleEdit() {
this.chatExtrasStore.setMessageIdToEdit({
token: this.token,
message: this.message,
id: this.id
})
this.chatExtrasStore.setMessageIdToEdit(this.token, this.id)
this.chatExtrasStore.setChatEditInput({ token: this.token, text: this.message })
EventBus.$emit('focus-chat-input')
},
Expand Down
9 changes: 4 additions & 5 deletions src/components/MessagesList/MessagesGroup/MessagesGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
<ul class="messages">
<li class="messages__author" aria-level="4">
{{ actorDisplayName }}
<div v-if="lastEditActorDisplayName"
:aria-label="getLastEditor"
:aria-level="4">
<div v-if="lastEditActorDisplayName">
{{ getLastEditor }}
</div>
</li>
Expand Down Expand Up @@ -143,9 +141,10 @@ export default {
},
getLastEditor() {
if (this.lastEditActorDisplayName === this.actorDisplayName) {
if (this.lastEditActorId === this.actorId && this.lastEditActorType === this.actorType) {
return t('spreed', '(edited)')
} else if (this.lastEditActorDisplayName === this.$store.getters.getDisplayName()) {
} else if (this.lastEditActorId === this.$store.getters.getActorId()
&& this.lastEditActorType === this.$store.getters.getActorType()) {
return t('spreed', '(edited by you)')
} else {
return t('spreed', '(edited by {user1})', { user1: this.lastEditActorDisplayName })
Expand Down
57 changes: 57 additions & 0 deletions src/components/MessagesList/MessagesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ export default {
EventBus.$on('scroll-chat-to-bottom-if-sticky', this.scrollToBottomIfSticky)
EventBus.$on('focus-message', this.focusMessage)
EventBus.$on('route-change', this.onRouteChange)
EventBus.$on('message-edited', this.handleMessageEdited)
subscribe('networkOffline', this.handleNetworkOffline)
subscribe('networkOnline', this.handleNetworkOnline)
window.addEventListener('focus', this.onWindowFocus)
Expand All @@ -305,6 +306,7 @@ export default {
EventBus.$on('scroll-chat-to-bottom-if-sticky', this.scrollToBottomIfSticky)
EventBus.$off('focus-message', this.focusMessage)
EventBus.$off('route-change', this.onRouteChange)
EventBus.$off('message-edited', this.handleMessageEdited)
this.$store.dispatch('cancelLookForNewMessages', { requestId: this.chatIdentifier })
this.destroying = true
Expand Down Expand Up @@ -399,6 +401,10 @@ export default {
return false // No previous message
}
if (!!message1.lastEditTimestamp || !!message2.lastEditTimestamp) {
return false // Edited messages are not grouped
}
if (message1.actorType === ATTENDEE.ACTOR_TYPE.BOTS // Don't group messages of commands and bots
&& message1.actorId !== ATTENDEE.CHANGELOG_BOT_ID) { // Apart from the changelog bot
return false
Expand Down Expand Up @@ -630,6 +636,57 @@ export default {
}
},
handleMessageEdited(id) {
// regroup messagesGroupedByAuthor when a message is edited
// find the group that contains the id and split it into 3 groups
// 1. the messages before the edited message
// 2. the edited message
// 3. the messages after the edited message
const groups = this.messagesGroupedByAuthor
const groupIndex = groups.findIndex(group => group.messages.some(message => message.id === id))
if (groupIndex === -1) {
return
}
// split the group into 3 groups
const group = groups[groupIndex]
const messageIndex = group.messages.findIndex(message => message.id === id)
const beforeMessages = group.messages.slice(0, messageIndex)
const afterMessages = group.messages.slice(messageIndex + 1)
const editedMessage = group.messages[messageIndex]
// remove the old group and add the 3 new groups at the same index
groups.splice(groupIndex, 1,
...(beforeMessages.length
? [{
id: beforeMessages[0].id,
messages: beforeMessages,
dateSeparator: group.dateSeparator,
previousMessageId: group.previousMessageId,
nextMessageId: editedMessage.id,
isSystemMessagesGroup: group.isSystemMessagesGroup,
}]
: []),
{
id: editedMessage.id,
messages: [editedMessage],
dateSeparator: group.dateSeparator,
previousMessageId: beforeMessages.length ? beforeMessages.at(-1).id : group.previousMessageId,
nextMessageId: afterMessages.length ? afterMessages[0].id : group.nextMessageId,
isSystemMessagesGroup: group.isSystemMessagesGroup,
},
...(afterMessages.length
? [{
id: afterMessages[0].id,
messages: afterMessages,
dateSeparator: group.dateSeparator,
previousMessageId: editedMessage.id,
nextMessageId: group.nextMessageId,
isSystemMessagesGroup: group.isSystemMessagesGroup,
}]
: []),
)
},
/**
* Fetches the messages of a conversation given the conversation token. Triggers
* a long-polling request for new messages.
Expand Down
33 changes: 19 additions & 14 deletions src/components/NewMessage/NewMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@ export default {
return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent)
},
chatInput() {
return this.chatExtrasStore.getChatInput(this.token)
chatEditInput() {
return this.chatExtrasStore.getChatEditInput(this.token)
},
},
Expand All @@ -446,34 +446,36 @@ export default {
},
text(newValue) {
this.chatExtrasStore.setChatInput({ token: this.token, text: newValue })
if (this.messageToEdit) {
this.chatExtrasStore.setChatEditInput({ token: this.token, text: newValue })
} else {
this.chatExtrasStore.setChatInput({ token: this.token, text: newValue })
}
},
messageToEdit(newValue) {
if (newValue) {
this.text = this.chatExtrasStore.getChatInput(this.token)
this.text = this.chatExtrasStore.getChatEditInput(this.token)
this.chatExtrasStore.removeParentIdToReply(this.token)
} else {
this.text = this.chatExtrasStore.getChatInput(this.token)
}
},
parentMessage(newValue) {
if (newValue) {
this.chatExtrasStore.removeMessageIdToEdit(this.token)
this.chatExtrasStore.removeChatInput(this.token)
}
},
chatInput(newValue) {
if (this.text !== newValue) {
this.text = newValue
this.chatExtrasStore.removeChatEditInput(this.token)
}
},
token: {
immediate: true,
handler(token) {
if (token) {
this.text = this.chatExtrasStore.getChatInput(token)
this.text = this.messageToEdit
? this.chatExtrasStore.getChatEditInput(token)
: this.chatExtrasStore.getChatInput(token)
} else {
this.text = ''
}
Expand Down Expand Up @@ -645,15 +647,17 @@ export default {
},
async handleEdit() {
if (this.messageToEdit.messageParameters.length !== 0) {
const isSimpleMessage = this.messageToEdit.messageParameters?.length === 0
|| this.messageToEdit.messageParameters?.some(parameter => parameter.startsWith('mention'))
if (!isSimpleMessage) {
// Captions editing is not supported yet
return
}
// Submitting an empty message will abort the edit
if (this.text.trim() === '') {
this.chatExtrasStore.removeMessageIdToEdit(this.token)
return
}
try {
Expand All @@ -662,6 +666,7 @@ export default {
messageId: this.messageToEdit.id,
updatedMessage: this.text.trim()
})
EventBus.$emit('message-edited', this.messageToEdit.id)
this.chatExtrasStore.removeMessageIdToEdit(this.token)
} catch {
this.$emit('failure')
Expand Down
2 changes: 1 addition & 1 deletion src/components/Quote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export default {
handleAbort() {
if (this.editMessage) {
this.chatExtrasStore.removeMessageIdToEdit(this.token)
this.chatExtrasStore.removeChatInput(this.token)
this.chatExtrasStore.removeChatEditInput(this.token)
} else {
this.chatExtrasStore.removeParentIdToReply(this.token)
}
Expand Down
35 changes: 6 additions & 29 deletions src/store/messagesStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,6 @@ const mutations = {
Vue.set(state.firstKnown, token, newFirstKnown)
}
},

updateMessage(state, { token, messageId, updatedMessageText, editDetails }) {
const message = state.messages[token][messageId]
if (!message) {
return
}
const updatedMessage = { ...message, message: updatedMessageText, ...editDetails }
Vue.set(state.messages[token], messageId, updatedMessage)
},
}

const actions = {
Expand All @@ -524,11 +515,16 @@ const actions = {
&& (message.systemMessage === 'message_deleted'
|| message.systemMessage === 'reaction'
|| message.systemMessage === 'reaction_deleted'
|| message.systemMessage === 'reaction_revoked')) {
|| message.systemMessage === 'reaction_revoked'
|| message.systemMessage === 'message_edited')) {
// If parent message is presented in store already, we update it
const parentInStore = context.getters.message(message.token, message.parent.id)
if (Object.keys(parentInStore).length !== 0) {
context.commit('addMessage', message.parent)
if (message.systemMessage === 'message_edited') {
// End of process for edited messages
return
}
}

const reactionsStore = useReactionsStore()
Expand Down Expand Up @@ -558,21 +554,6 @@ const actions = {
context.commit('addMessage', message.parent)
return
}

// Update message in store
const messageUpdated = message.parent
const editDetails = {
lastEditActorDisplayName: messageUpdated.lastEditActorDisplayName,
lastEditActorId: messageUpdated.lastEditActorId,
lastEditActorType: messageUpdated.lastEditActorType,
lastEditTimestamp: messageUpdated.lastEditTimestamp,
}
context.commit('updateMessage', {
token: messageUpdated.token,
messageId: messageUpdated.id,
updatedMessageText: messageUpdated.message,
editDetails,
})
return
}

Expand Down Expand Up @@ -1379,10 +1360,6 @@ const actions = {
async easeMessageList(context, { token }) {
context.commit('easeMessageList', { token })
},

updateMessage(context, { token, messageId, updatedMessageText, editDetails }) {
context.commit('updateMessage', { token, messageId, updatedMessageText, editDetails })
},
}

export default { state, mutations, getters, actions }
51 changes: 47 additions & 4 deletions src/stores/chatExtras.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const useChatExtrasStore = defineStore('chatExtras', {
parentToReply: {},
chatInput: {},
messageIdToEdit: {},
chatEditInput: {},
}),

getters: {
Expand All @@ -62,9 +63,13 @@ export const useChatExtrasStore = defineStore('chatExtras', {
return state.chatInput[token] ?? ''
},

getChatEditInput: (state) => (token) => {
return state.chatEditInput[token] ?? ''
},

getMessageIdToEdit: (state) => (token) => {
return state.messageIdToEdit[token]
}
},
},

actions: {
Expand Down Expand Up @@ -142,18 +147,56 @@ export const useChatExtrasStore = defineStore('chatExtras', {
Vue.set(this.chatInput, token, parsedText)
},

setMessageIdToEdit({ token, message, id }) {
this.setChatInput({ token, text: message })
/**
* Add a message text that is being edited to the store for a given conversation token
*
* @param {object} payload action payload
* @param {string} payload.token The conversation token
* @param {string} payload.text The string to store
*/
setChatEditInput({ token, text }) {
// FIXME upstream: https://github.com/nextcloud-libraries/nextcloud-vue/issues/4492
const temp = document.createElement('textarea')
temp.innerHTML = text.replace(/&/gmi, '&amp;')
const parsedText = temp.value.replace(/&amp;/gmi, '&').replace(/&lt;/gmi, '<')
.replace(/&gt;/gmi, '>').replace(/&sect;/gmi, '§')

Vue.set(this.chatEditInput, token, parsedText)
},

/**
* Add a message id that is being edited to the store
*
* @param {string} token The conversation token
* @param {number} id The id of message
*/
setMessageIdToEdit(token, id) {
Vue.set(this.messageIdToEdit, token, id)
},

/**
* Remove a message id that is being edited to the store
*
* @param {string} token The conversation token
*/
removeMessageIdToEdit(token) {
this.removeChatInput(token)
this.removeChatEditInput(token)
if (this.messageIdToEdit[token]) {
Vue.delete(this.messageIdToEdit, token)
}
},

/**
* Remove the edited message text from the store for a given conversation token
*
* @param {string} token The conversation token
*/
removeChatEditInput(token) {
if (this.chatEditInput[token]) {
Vue.delete(this.chatEditInput, token)
}
},

/**
* Remove a current input value from the store for a given conversation token
*
Expand Down

0 comments on commit 9389f8c

Please sign in to comment.