Skip to content

Commit

Permalink
Add shortkey to edit message
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 31, 2024
1 parent 0f775f6 commit c0d7bad
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 13 deletions.
18 changes: 6 additions & 12 deletions src/components/MessagesList/MessagesGroup/Message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -485,18 +485,12 @@ export default {
},
handleEdit() {
this.chatExtrasStore.setMessageIdToEdit(this.token, this.id)
if (this.isFileShareOnly) {
this.chatExtrasStore.setChatEditInput({ token: this.token, text: '' })
} else {
this.chatExtrasStore.setChatEditInput({
token: this.token,
text: this.message,
parameters: this.messageParameters
})
}
EventBus.$emit('editing-message')
EventBus.$emit('focus-chat-input')
this.chatExtrasStore.initiateEditingMessage({
token: this.token,
id: this.id,
message: this.message,
messageParameters: this.messageParameters,
})
},
async handleDelete() {
Expand Down
33 changes: 32 additions & 1 deletion src/components/NewMessage/NewMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
dir="auto"
@shortkey="focusInput"
@keydown.esc="handleInputEsc"
@keydown.ctrl.up="handleEditLastMessage"
@tribute-active-true.native="isTributePickerActive = true"
@tribute-active-false.native="isTributePickerActive = false"
@input="handleTyping"
Expand Down Expand Up @@ -230,6 +231,7 @@ import { parseSpecialSymbols } from '../../utils/textParse.js'
const disableKeyboardShortcuts = OCP.Accessibility.disableKeyboardShortcuts()
const supportTypingStatus = getCapabilities()?.spreed?.config?.chat?.['typing-privacy'] !== undefined
const canEditMessage = getCapabilities()?.spreed?.features?.includes('edit-messages')
export default {
name: 'NewMessage',
Expand Down Expand Up @@ -641,7 +643,6 @@ export default {
token: this.token,
})
this.text = ''
this.resetTypingIndicator()
this.userData = {}
// Scrolls the message list to the last added message
EventBus.$emit('smooth-scroll-chat-to-bottom')
Expand All @@ -651,6 +652,7 @@ export default {
this.broadcast
? await this.broadcastMessage(this.token, temporaryMessage.message)
: await this.postMessage(this.token, temporaryMessage, options)
this.resetTypingIndicator()
}
},
Expand Down Expand Up @@ -696,6 +698,7 @@ export default {
})
this.$store.dispatch('processMessage', { token: this.token, message: response.data.ocs.data })
this.chatExtrasStore.removeMessageIdToEdit(this.token)
this.resetTypingIndicator()
} catch {
this.$emit('failure')
showError(t('spreed', 'The message could not be edited'))
Expand Down Expand Up @@ -923,11 +926,39 @@ export default {
},
handleInputEsc() {
if (this.messageToEdit && !this.isTributePickerActive) {
this.handleAbortEdit()
this.focusInput()
return
}
// When the tribute picker (e.g. emoji picker or mentions) is open
// ESC should only close the picker but not blur
if (!this.isTributePickerActive) {
this.blurInput()
}
},
handleEditLastMessage() {
if (!canEditMessage || this.upload || this.broadcast || this.isRecordingAudio) {
return
}
const lastMessageByCurrentUser = this.$store.getters.messagesList(this.token).findLast(message => {
return message.actorId === this.$store.getters.getUserId()
&& message.actorType === this.$store.getters.getActorType()
&& !message.isTemporary && !message.systemMessage
})
if (!lastMessageByCurrentUser) {
return
}
this.chatExtrasStore.initiateEditingMessage({
token: this.token,
id: lastMessageByCurrentUser.id,
message: lastMessageByCurrentUser.message,
messageParameters: lastMessageByCurrentUser.messageParameters,
})
},
async checkAbsenceStatus() {
Expand Down
6 changes: 6 additions & 0 deletions src/components/SettingsDialog/SettingsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
{{ t('spreed', 'Unfocus the chat input to use shortcuts') }}
</dd>
</div>
<div>
<dt><kbd>Ctrl</kbd> + <kbd>↑</kbd></dt>
<dd class="shortcut-description">
{{ t('spreed', 'Edit your last message') }}
</dd>
</div>
<div>
<dt><kbd>F</kbd></dt>
<dd class="shortcut-description">
Expand Down
38 changes: 38 additions & 0 deletions src/stores/__tests__/chatExtras.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { setActivePinia, createPinia } from 'pinia'

import { EventBus } from '../../services/EventBus.js'
import { getUserAbsence } from '../../services/participantsService.js'
import { generateOCSErrorResponse, generateOCSResponse } from '../../test-helpers.js'
import { useChatExtrasStore } from '../chatExtras.js'
Expand Down Expand Up @@ -196,4 +197,41 @@ describe('chatExtrasStore', () => {
expect(chatExtrasStore.getChatInput('token-1')).toBe('Many whitespaces')
})
})

describe('initiateEditingMessage', () => {
it('should set the message ID to edit, set the chat edit input, and emit an event', () => {
// Arrange
const payload = {
token: 'token-1',
id: 'id-1',
message: 'Hello, world!',
messageParameters: {}
}
const emitSpy = jest.spyOn(EventBus, '$emit')

// Act
chatExtrasStore.initiateEditingMessage(payload)

// Assert
expect(chatExtrasStore.getMessageIdToEdit('token-1')).toBe('id-1')
expect(chatExtrasStore.getChatEditInput('token-1')).toEqual('Hello, world!')
expect(emitSpy).toHaveBeenCalledWith('editing-message')
})

it('should set the chat edit input text to empty if the message is a file share only', () => {
// Arrange
const payload = {
token: 'token-1',
id: 'id-1',
message: '{file}',
messageParameters: { file0: 'file-path' }
}

// Act
chatExtrasStore.initiateEditingMessage(payload)

// Assert
expect(chatExtrasStore.getChatEditInput('token-1')).toEqual('')
})
})
})
18 changes: 18 additions & 0 deletions src/stores/chatExtras.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import { defineStore } from 'pinia'
import Vue from 'vue'

import { EventBus } from '../services/EventBus.js'
import { getUserAbsence } from '../services/participantsService.js'
import { parseSpecialSymbols, parseMentions } from '../utils/textParse.js'

Expand Down Expand Up @@ -188,6 +189,23 @@ export const useChatExtrasStore = defineStore('chatExtras', {
Vue.delete(this.chatInput, token)
},

initiateEditingMessage({ token, id, message, messageParameters }) {
this.setMessageIdToEdit(token, id)
const isFileShareOnly = Object.keys(Object(messageParameters)).some(key => key.startsWith('file'))
&& message === '{file}'
if (isFileShareOnly) {
this.setChatEditInput({ token, text: '' })
} else {
this.setChatEditInput({
token,
text: message,
parameters: messageParameters
})
}
EventBus.$emit('editing-message')
EventBus.$emit('focus-chat-input')
},

/**
* Clears store for a deleted conversation
*
Expand Down

0 comments on commit c0d7bad

Please sign in to comment.