added message draft persistence and send button
This commit is contained in:
@@ -1,10 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<textarea ref="textareaRef" v-model="content" @input="resize" @keydown="handleKeydown" rows="1"
|
<div class="container-div">
|
||||||
:placeholder="$t('chat-input-placeholder')"></textarea>
|
<textarea ref="textareaRef" v-model="content" @input="handleInput" @keydown="handleKeydown" rows="1"
|
||||||
|
:placeholder="$t('chat-input-placeholder')"></textarea>
|
||||||
|
|
||||||
|
<button class="send-btn" @click="submit" :disabled="!content.trim()">
|
||||||
|
<i class="fas fa-paper-plane"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick } from 'vue'
|
import { ref, nextTick, onMounted } from 'vue'
|
||||||
|
import { saveMessageDraft, getMessageDraft } from '../store'
|
||||||
|
|
||||||
const content = ref('')
|
const content = ref('')
|
||||||
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
||||||
@@ -17,10 +24,24 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const saved = await getMessageDraft()
|
||||||
|
if (saved) {
|
||||||
|
content.value = saved
|
||||||
|
resize()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleInput() {
|
||||||
|
resize()
|
||||||
|
saveMessageDraft(content.value)
|
||||||
|
}
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
if (!content.value.trim()) return
|
if (!content.value.trim()) return
|
||||||
emit('send', content.value)
|
emit('send', content.value)
|
||||||
content.value = ''
|
content.value = ''
|
||||||
|
saveMessageDraft('')
|
||||||
resize()
|
resize()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +64,9 @@ function handleKeydown(e: KeyboardEvent) {
|
|||||||
textarea.selectionStart = textarea.selectionEnd = start + 1
|
textarea.selectionStart = textarea.selectionEnd = start + 1
|
||||||
})
|
})
|
||||||
resize()
|
resize()
|
||||||
|
|
||||||
|
saveMessageDraft(content.value)
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
} else if (!e.shiftKey && !e.altKey && e.key === 'Enter') {
|
} else if (!e.shiftKey && !e.altKey && e.key === 'Enter') {
|
||||||
submit()
|
submit()
|
||||||
@@ -52,6 +76,13 @@ function handleKeydown(e: KeyboardEvent) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.container-div {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
resize: none;
|
resize: none;
|
||||||
@@ -64,5 +95,26 @@ textarea {
|
|||||||
border: none;
|
border: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn {
|
||||||
|
margin-right: 0.8rem;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--text);
|
||||||
|
padding: 0;
|
||||||
|
transition: color 0.2s;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn:hover:not(:disabled) {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
13
src/store.ts
13
src/store.ts
@@ -223,3 +223,16 @@ export async function getCompactLayoutPreference(): Promise<boolean> {
|
|||||||
const s = await getStore();
|
const s = await getStore();
|
||||||
return (await s.get<boolean>('compact_layout')) ?? false;
|
return (await s.get<boolean>('compact_layout')) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==== Message draft ====
|
||||||
|
|
||||||
|
export async function saveMessageDraft(text: string) {
|
||||||
|
const s = await getStore()
|
||||||
|
await s.set('message_draft', text)
|
||||||
|
await s.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getMessageDraft(): Promise<string> {
|
||||||
|
const s = await getStore()
|
||||||
|
return (await s.get<string>('message_draft')) ?? ''
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user