Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
Paste clipboard img (mckaywrigley#1119)
Browse files Browse the repository at this point in the history
* Support for paste imgs from clipboard

* add image copy/paste

---------

Co-authored-by: Murillo Camargo <[email protected]>
  • Loading branch information
2 people authored and bpalagi committed Jan 12, 2024
1 parent 6a6cd0e commit 8a4ffbd
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 13 deletions.
9 changes: 4 additions & 5 deletions components/chat/chat-files-display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ export const ChatFilesDisplay: FC<ChatFilesDisplayProps> = ({}) => {
const [selectedImage, setSelectedImage] = useState<MessageImage | null>(null)
const [showPreview, setShowPreview] = useState(false)

const combinedImages = [
const messageImages = [
...newMessageImages.filter(
image =>
!chatImages.some(chatImage => chatImage.messageId === image.messageId)
),
...chatImages
)
]

const combinedChatFiles = [
Expand All @@ -55,7 +54,7 @@ export const ChatFilesDisplay: FC<ChatFilesDisplayProps> = ({}) => {
...chatFiles
]

const combinedMessageFiles = [...combinedImages, ...combinedChatFiles]
const combinedMessageFiles = [...messageImages, ...combinedChatFiles]

const getLinkAndView = async (file: ChatFile) => {
const fileRecord = files.find(f => f.id === file.id)
Expand Down Expand Up @@ -108,7 +107,7 @@ export const ChatFilesDisplay: FC<ChatFilesDisplayProps> = ({}) => {

<div className="overflow-auto">
<div className="flex flex-wrap gap-6 truncate pt-2">
{combinedImages.map((image, index) => (
{messageImages.map((image, index) => (
<div
key={index}
className="relative flex h-[64px] cursor-pointer items-center space-x-4 rounded-xl hover:opacity-50"
Expand Down
17 changes: 14 additions & 3 deletions components/chat/chat-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ export const handleCreateMessages = async (
isRegeneration: boolean,
retrievedFileItems: Tables<"file_items">[],
setChatMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>,
setChatFileItems: React.Dispatch<React.SetStateAction<Tables<"file_items">[]>>
setChatFileItems: React.Dispatch<
React.SetStateAction<Tables<"file_items">[]>
>,
setChatImages: React.Dispatch<React.SetStateAction<MessageImage[]>>
) => {
const finalUserMessage: TablesInsert<"messages"> = {
chat_id: currentChat.id,
Expand Down Expand Up @@ -432,7 +435,15 @@ export const handleCreateMessages = async (
Boolean
) as string[]

updateMessage(createdMessages[0].id, {
setChatImages(prevImages => [
...prevImages,
...newMessageImages.map(obj => ({
...obj,
messageId: createdMessages[0].id
}))
])

const updatedMessage = await updateMessage(createdMessages[0].id, {
...createdMessages[0],
image_paths: paths
})
Expand All @@ -450,7 +461,7 @@ export const handleCreateMessages = async (
finalChatMessages = [
...chatMessages,
{
message: createdMessages[0],
message: updatedMessage,
fileItems: []
},
{
Expand Down
3 changes: 2 additions & 1 deletion components/chat/chat-hooks/use-chat-handler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ export const useChatHandler = () => {
isRegeneration,
retrievedFileItems,
setChatMessages,
setChatFileItems
setChatFileItems,
setChatImages
)

setIsGenerating(false)
Expand Down
27 changes: 25 additions & 2 deletions components/chat/chat-input.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ChatbotUIContext } from "@/context/context"
import useHotkey from "@/lib/hooks/use-hotkey"
import { LLM_LIST } from "@/lib/models/llm/llm-list"
import { cn } from "@/lib/utils"
import {
IconCirclePlus,
IconPlayerStopFilled,
IconSend
} from "@tabler/icons-react"
import { FC, useContext, useEffect, useRef } from "react"
import { FC, useContext, useEffect, useRef, useState } from "react"
import { Input } from "../ui/input"
import { TextareaAutosize } from "../ui/textarea-autosize"
import { ChatCommandInput } from "./chat-command-input"
Expand Down Expand Up @@ -34,7 +35,10 @@ export const ChatInput: FC<ChatInputProps> = ({}) => {
isPromptPickerOpen,
setIsPromptPickerOpen,
isAtPickerOpen,
setFocusFile
setFocusFile,
newMessageImages,
setNewMessageImages,
chatSettings
} = useContext(ChatbotUIContext)

const {
Expand All @@ -44,6 +48,8 @@ export const ChatInput: FC<ChatInputProps> = ({}) => {
handleFocusChatInput
} = useChatHandler()

const [isTextareaFocused, setTextareaFocused] = useState(false)

const { handleInputChange } = usePromptAndCommand()

const { filesToAccept, handleSelectDeviceFile } = useSelectFileHandler()
Expand Down Expand Up @@ -74,6 +80,22 @@ export const ChatInput: FC<ChatInputProps> = ({}) => {
}
}

const handlePaste = (event: React.ClipboardEvent) => {
const imagesAllowed = LLM_LIST.find(
llm => llm.modelId === chatSettings?.model
)?.imageInput
if (!imagesAllowed) return

const items = event.clipboardData.items
for (const item of items) {
if (item.type.indexOf("image") === 0) {
const file = item.getAsFile()
if (!file) return
handleSelectDeviceFile(file)
}
}
}

return (
<>
<ChatFilesDisplay />
Expand Down Expand Up @@ -112,6 +134,7 @@ export const ChatInput: FC<ChatInputProps> = ({}) => {
minRows={1}
maxRows={20}
onKeyDown={handleKeyDown}
onPaste={handlePaste}
/>

<div className="absolute bottom-[14px] right-3 cursor-pointer hover:opacity-50">
Expand Down
4 changes: 3 additions & 1 deletion components/messages/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ export const Message: FC<MessageProps> = ({

<div className="mt-3 flex flex-wrap gap-2">
{message.image_paths.map((path, index) => {
const item = chatImages.find(image => image.path === path)
const item = chatImages.find(
image => image.messageId === message.id
)

return (
<Image
Expand Down
5 changes: 4 additions & 1 deletion components/ui/textarea-autosize.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface TextareaAutosizeProps {
minRows?: number
maxRows?: number
onKeyDown?: (event: React.KeyboardEvent) => void
onPaste?: (event: React.ClipboardEvent) => void
}

export const TextareaAutosize: FC<TextareaAutosizeProps> = ({
Expand All @@ -24,7 +25,8 @@ export const TextareaAutosize: FC<TextareaAutosizeProps> = ({
placeholder = "",
minRows = 1,
maxRows = 6,
onKeyDown = () => {}
onKeyDown = () => {},
onPaste = () => {}
}) => {
return (
<ReactTextareaAutosize
Expand All @@ -39,6 +41,7 @@ export const TextareaAutosize: FC<TextareaAutosizeProps> = ({
value={value}
onChange={event => onValueChange(event.target.value)}
onKeyDown={onKeyDown}
onPaste={onPaste}
/>
)
}

0 comments on commit 8a4ffbd

Please sign in to comment.