Skip to content

Commit

Permalink
feat(chat): edit last message on keyup (#4986)
Browse files Browse the repository at this point in the history
  • Loading branch information
molimauro committed Sep 23, 2022
1 parent 1bbc9c5 commit f1f8f6e
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 10 deletions.
1 change: 1 addition & 0 deletions components/views/chat/chatbar/Chatbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
:class="{'has-command' : hasCommand}"
:focus="ui.chatbarFocus"
@keydown="handleInputKeydown"
@keyup="handleInputKeyup"
@paste="handlePaste"
/>
<ChatbarControls
Expand Down
68 changes: 63 additions & 5 deletions components/views/chat/chatbar/Chatbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ import { mapState } from 'vuex'
import { throttle, debounce } from 'lodash'
import { TerminalIcon } from 'satellite-lucide-icons'
import { parseCommand, commands } from '~/libraries/ui/Commands'
import {
KeybindingEnum,
MessagingTypesEnum,
PropCommonEnum,
} from '~/libraries/Enums/enums'
import { KeybindingEnum, MessagingTypesEnum } from '~/libraries/Enums/enums'
import { Config } from '~/config'
import { RootState } from '~/types/store/store'
import iridium from '~/libraries/Iridium/IridiumManager'
import { ChatbarUploadRef } from '~/components/views/chat/chatbar/upload/Upload.vue'
import {
Conversation,
ConversationMessage,
ConversationMessagePayload,
MessageAttachment,
} from '~/libraries/Iridium/chat/types'
Expand All @@ -33,6 +30,23 @@ function typingFunction(conversationId: string) {
}
}
function isVisible(ele: HTMLElement, container: HTMLElement, partial = false) {
const cTop = container.scrollTop
const cBottom = cTop + container.clientHeight
const eTop = ele.offsetTop
const eBottom = eTop + ele.clientHeight
const scrolledBefore = eTop >= cTop
const scrolledAfter = eBottom <= cBottom
const isTotal = scrolledBefore && scrolledAfter
const isPartial =
partial &&
((eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom))
return { isElVisible: isTotal || isPartial, scrolledAfter, scrolledBefore }
}
const Chatbar = Vue.extend({
components: {
TerminalIcon,
Expand Down Expand Up @@ -153,6 +167,16 @@ const Chatbar = Vue.extend({
? (this.$t('ui.talk') as string)
: ''
},
userLastTextMessage(): ConversationMessage | undefined {
if (!this.conversationId) return
return Object.values(
iridium.chat.state.conversations[this.conversationId].message,
)
.filter((m) => m.from === iridium.id && m.type === 'text')
.sort((a, b) => a.at - b.at)
.at(-1)
},
},
mounted() {
const message = this.chat.draftMessages[this.conversationId] ?? ''
Expand Down Expand Up @@ -207,6 +231,17 @@ const Chatbar = Vue.extend({
}
this.smartTypingStart()
},
handleInputKeyup(event: KeyboardEvent) {
switch (event.key) {
case KeybindingEnum.ARROW_UP:
if (!event.shiftKey) {
this.editMessage()
}
break
default:
break
}
},
async uploadAttachments(): Promise<MessageAttachment[]> {
if (!this.files.length) {
return []
Expand Down Expand Up @@ -322,6 +357,29 @@ const Chatbar = Vue.extend({
}
;(this.$refs.editable as EditableRef).handleTextFromOutside(text)
},
editMessage() {
if (!this.userLastTextMessage) return
const { id, payload, from } = this.userLastTextMessage
this.$store.commit('ui/setEditMessage', {
id,
payload,
from,
})
this.$nextTick(() => {
const el = document.querySelector(
`[data-message-id="${id}"]`,
) as HTMLElement
const container = document.getElementById('conversation-container')
if (!el || !container) return
const { isElVisible, scrolledAfter } = isVisible(el, container)
if (!isElVisible) {
el.scrollIntoView(scrolledAfter)
}
})
},
},
})
export type ChatbarRef = InstanceType<typeof Chatbar>
Expand Down
3 changes: 2 additions & 1 deletion components/views/chat/conversation/Conversation.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div class="conversation" ref="container">
<!-- dont change the 'conversation-container' id -->
<div id="conversation-container" class="conversation" ref="container">
<div class="messages" ref="messages">
<UiBanner>
<template #icon><key-icon size="1x" /></template>
Expand Down
1 change: 1 addition & 0 deletions components/views/chat/conversation/Conversation.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.conversation {
position: relative; // Dont remove
display: flex;
flex-direction: column;
flex: 1;
Expand Down
6 changes: 5 additions & 1 deletion components/views/chat/message/Message.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<div class="chat-message-container" :class="{ 'show-header': showHeader }">
<div
class="chat-message-container"
:class="{ 'show-header': showHeader }"
:data-message-id="message.id"
>
<MessageNotice v-if="isNotice" :message="message" />
<div
v-else
Expand Down
2 changes: 1 addition & 1 deletion components/views/chat/message/Message.less
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

.chat-message-container {
&.show-header {
margin-top: @normal-spacing;
padding-top: @normal-spacing;
}
}

Expand Down
11 changes: 9 additions & 2 deletions components/views/chat/message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -188,27 +188,34 @@ export default Vue.extend({
from,
})
},
saveMessage(message: string) {
async saveMessage(message: string) {
this.$store.commit('ui/setEditMessage', {
id: '',
payload: '',
from: '',
})
if (message !== this.message.body) {
iridium.chat.editMessage({
await iridium.chat.editMessage({
conversationId: this.message.conversationId,
messageId: this.message.id,
body: message,
})
}
if (this.$device.isDesktop) {
this.$store.dispatch('ui/setChatbarFocus')
}
},
cancelMessage() {
this.$store.commit('ui/setEditMessage', {
id: '',
payload: '',
from: '',
})
if (this.$device.isDesktop) {
this.$store.dispatch('ui/setChatbarFocus')
}
},
},
})
Expand Down

0 comments on commit f1f8f6e

Please sign in to comment.