mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
fix(web): improve chat input UX — IME composing, send button, file upload
- Prevent Enter from sending message during IME composing (keyCode 229) - Remove separator line between textarea and toolbar - Change send/stop buttons to compact circular icon-only style - Fix send icon color to white for dark mode visibility - Add missing hidden file input element so the attach button works
This commit is contained in:
@@ -118,6 +118,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
ref="fileInput"
|
||||||
|
type="file"
|
||||||
|
multiple
|
||||||
|
class="hidden"
|
||||||
|
@change="handleFileInputChange"
|
||||||
|
>
|
||||||
<section>
|
<section>
|
||||||
<InputGroup class="bg-transparent overflow-hidden">
|
<InputGroup class="bg-transparent overflow-hidden">
|
||||||
<InputGroupTextarea
|
<InputGroupTextarea
|
||||||
@@ -129,7 +136,6 @@
|
|||||||
@keydown.enter.exact="handleKeydown"
|
@keydown.enter.exact="handleKeydown"
|
||||||
@paste="handlePaste"
|
@paste="handlePaste"
|
||||||
/>
|
/>
|
||||||
<Separator />
|
|
||||||
<InputGroupAddon
|
<InputGroupAddon
|
||||||
align="block-end"
|
align="block-end"
|
||||||
class="bg-[#FAFAFA] dark:bg-background items-center py-1.5"
|
class="bg-[#FAFAFA] dark:bg-background items-center py-1.5"
|
||||||
@@ -161,23 +167,22 @@
|
|||||||
<Button
|
<Button
|
||||||
v-if="!streaming"
|
v-if="!streaming"
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="icon"
|
||||||
:disabled="(!inputText.trim() && !pendingFiles.length) || !currentBotId || activeChatReadOnly"
|
:disabled="(!inputText.trim() && !pendingFiles.length) || !currentBotId || activeChatReadOnly"
|
||||||
aria-label="Send message"
|
aria-label="Send message"
|
||||||
class="ml-auto bg-[#8B56E3]"
|
class="ml-auto size-7 rounded-full bg-[#8B56E3] text-white"
|
||||||
@click="handleSend"
|
@click="handleSend"
|
||||||
>
|
>
|
||||||
<Send
|
<Send
|
||||||
class="size-2"
|
class="size-3"
|
||||||
/>
|
/>
|
||||||
{{ $t('chat.send') }}
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="icon"
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
class="ml-auto"
|
class="ml-auto size-7 rounded-full"
|
||||||
aria-label="Stop generating response"
|
aria-label="Stop generating response"
|
||||||
@click="chatStore.abort()"
|
@click="chatStore.abort()"
|
||||||
>
|
>
|
||||||
@@ -220,7 +225,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, nextTick, onMounted, provide, useTemplateRef, watchEffect} from 'vue'
|
import { ref, computed, nextTick, onMounted, provide, useTemplateRef, watchEffect} from 'vue'
|
||||||
import { LoaderCircle, Image as ImageIcon, File as FileIcon, X, Paperclip, FolderOpen, Send } from 'lucide-vue-next'
|
import { LoaderCircle, Image as ImageIcon, File as FileIcon, X, Paperclip, FolderOpen, Send } from 'lucide-vue-next'
|
||||||
import { ScrollArea, Button, InputGroup, InputGroupAddon, InputGroupTextarea, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription,Separator } from '@memohai/ui'
|
import { ScrollArea, Button, InputGroup, InputGroupAddon, InputGroupTextarea, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '@memohai/ui'
|
||||||
import { useChatStore } from '@/store/chat-list'
|
import { useChatStore } from '@/store/chat-list'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import MessageItem from './message-item.vue'
|
import MessageItem from './message-item.vue'
|
||||||
@@ -340,12 +345,22 @@ watchEffect(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function handleKeydown(e: KeyboardEvent) {
|
function handleKeydown(e: KeyboardEvent) {
|
||||||
if (e.isComposing) return
|
if (e.isComposing || e.keyCode === 229) return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
handleSend()
|
handleSend()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleFileInputChange(e: Event) {
|
||||||
|
const input = e.target as HTMLInputElement
|
||||||
|
if (input.files) {
|
||||||
|
for (const file of Array.from(input.files)) {
|
||||||
|
pendingFiles.value.push(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
function handlePaste(e: ClipboardEvent) {
|
function handlePaste(e: ClipboardEvent) {
|
||||||
const items = e.clipboardData?.items
|
const items = e.clipboardData?.items
|
||||||
if (!items) return
|
if (!items) return
|
||||||
|
|||||||
Reference in New Issue
Block a user