perf: support reading image from the clipboard

This commit is contained in:
molvqingtai 2024-10-31 11:38:13 +08:00
parent 2987c2d85d
commit 362d7db738
2 changed files with 13 additions and 2 deletions

View file

@ -1,4 +1,4 @@
import { forwardRef, type ChangeEvent, CompositionEvent, type KeyboardEvent } from 'react' import { forwardRef, type ChangeEvent, CompositionEvent, type KeyboardEvent, ClipboardEvent } from 'react'
import { cn } from '@/utils' import { cn } from '@/utils'
import { Textarea } from '@/components/ui/Textarea' import { Textarea } from '@/components/ui/Textarea'
@ -14,6 +14,7 @@ export interface MessageInputProps {
disabled?: boolean disabled?: boolean
loading?: boolean loading?: boolean
onInput?: (e: ChangeEvent<HTMLTextAreaElement>) => void onInput?: (e: ChangeEvent<HTMLTextAreaElement>) => void
onPaste?: (e: ClipboardEvent<HTMLTextAreaElement>) => void
onKeyDown?: (e: KeyboardEvent<HTMLTextAreaElement>) => void onKeyDown?: (e: KeyboardEvent<HTMLTextAreaElement>) => void
onCompositionStart?: (e: CompositionEvent<HTMLTextAreaElement>) => void onCompositionStart?: (e: CompositionEvent<HTMLTextAreaElement>) => void
onCompositionEnd?: (e: CompositionEvent<HTMLTextAreaElement>) => void onCompositionEnd?: (e: CompositionEvent<HTMLTextAreaElement>) => void
@ -31,6 +32,7 @@ const MessageInput = forwardRef<HTMLTextAreaElement, MessageInputProps>(
className, className,
maxLength = 500, maxLength = 500,
onInput, onInput,
onPaste,
onKeyDown, onKeyDown,
onCompositionStart, onCompositionStart,
onCompositionEnd, onCompositionEnd,
@ -45,6 +47,7 @@ const MessageInput = forwardRef<HTMLTextAreaElement, MessageInputProps>(
<ScrollArea className="box-border max-h-28 w-full rounded-lg border border-input bg-background ring-offset-background focus-within:ring-1 focus-within:ring-ring 2xl:max-h-40"> <ScrollArea className="box-border max-h-28 w-full rounded-lg border border-input bg-background ring-offset-background focus-within:ring-1 focus-within:ring-ring 2xl:max-h-40">
<Textarea <Textarea
ref={ref} ref={ref}
onPaste={onPaste}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
autoFocus={autoFocus} autoFocus={autoFocus}
maxLength={maxLength} maxLength={maxLength}

View file

@ -1,4 +1,4 @@
import { ChangeEvent, useMemo, useRef, useState, KeyboardEvent, type FC } from 'react' import { ChangeEvent, useMemo, useRef, useState, KeyboardEvent, type FC, ClipboardEvent } from 'react'
import { CornerDownLeftIcon } from 'lucide-react' import { CornerDownLeftIcon } from 'lucide-react'
import { useRemeshDomain, useRemeshQuery, useRemeshSend } from 'remesh-react' import { useRemeshDomain, useRemeshQuery, useRemeshSend } from 'remesh-react'
import MessageInput from '../../components/MessageInput' import MessageInput from '../../components/MessageInput'
@ -216,6 +216,13 @@ const Footer: FC = () => {
send(messageInputDomain.command.InputCommand(currentMessage)) send(messageInputDomain.command.InputCommand(currentMessage))
} }
const handlePaste = async (e: ClipboardEvent<HTMLTextAreaElement>) => {
const file = e.nativeEvent.clipboardData?.files[0]
if (['image/png', 'image/jpeg', 'image/webp'].includes(file?.type ?? '')) {
handleInjectImage(file!)
}
}
const handleInjectEmoji = (emoji: string) => { const handleInjectEmoji = (emoji: string) => {
const newMessage = `${message.slice(0, selectionEnd)}${emoji}${message.slice(selectionEnd)}` const newMessage = `${message.slice(0, selectionEnd)}${emoji}${message.slice(selectionEnd)}`
@ -335,6 +342,7 @@ const Footer: FC = () => {
value={message} value={message}
onInput={handleInput} onInput={handleInput}
loading={inputLoading} loading={inputLoading}
onPaste={handlePaste}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
maxLength={MESSAGE_MAX_LENGTH} maxLength={MESSAGE_MAX_LENGTH}
></MessageInput> ></MessageInput>