205 lines
5.5 KiB
TypeScript
205 lines
5.5 KiB
TypeScript
import { ChatbotUIContext } from "@/context/context"
|
|
import { createDocXFile, createFile } from "@/db/files"
|
|
import { LLM_LIST } from "@/lib/models/llm/llm-list"
|
|
import mammoth from "mammoth"
|
|
import { useContext, useEffect, useState } from "react"
|
|
import { toast } from "sonner"
|
|
|
|
export const ACCEPTED_FILE_TYPES = [
|
|
"text/csv",
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
"application/json",
|
|
"text/markdown",
|
|
"application/pdf",
|
|
"text/plain"
|
|
].join(",")
|
|
|
|
export const useSelectFileHandler = () => {
|
|
const {
|
|
selectedWorkspace,
|
|
profile,
|
|
chatSettings,
|
|
setNewMessageImages,
|
|
setNewMessageFiles,
|
|
setShowFilesDisplay,
|
|
setFiles,
|
|
setUseRetrieval
|
|
} = useContext(ChatbotUIContext)
|
|
|
|
const [filesToAccept, setFilesToAccept] = useState(ACCEPTED_FILE_TYPES)
|
|
|
|
useEffect(() => {
|
|
handleFilesToAccept()
|
|
}, [chatSettings?.model])
|
|
|
|
const handleFilesToAccept = () => {
|
|
const model = chatSettings?.model
|
|
const FULL_MODEL = LLM_LIST.find(llm => llm.modelId === model)
|
|
|
|
if (!FULL_MODEL) return
|
|
|
|
setFilesToAccept(
|
|
FULL_MODEL.imageInput
|
|
? `${ACCEPTED_FILE_TYPES},image/*`
|
|
: ACCEPTED_FILE_TYPES
|
|
)
|
|
}
|
|
|
|
const handleSelectDeviceFile = async (file: File) => {
|
|
if (!profile || !selectedWorkspace || !chatSettings) return
|
|
|
|
setShowFilesDisplay(true)
|
|
setUseRetrieval(true)
|
|
|
|
if (file) {
|
|
let simplifiedFileType = file.type.split("/")[1]
|
|
|
|
let reader = new FileReader()
|
|
|
|
if (file.type.includes("image")) {
|
|
reader.readAsDataURL(file)
|
|
} else if (ACCEPTED_FILE_TYPES.split(",").includes(file.type)) {
|
|
if (simplifiedFileType.includes("vnd.adobe.pdf")) {
|
|
simplifiedFileType = "pdf"
|
|
} else if (
|
|
simplifiedFileType.includes(
|
|
"vnd.openxmlformats-officedocument.wordprocessingml.document" ||
|
|
"docx"
|
|
)
|
|
) {
|
|
simplifiedFileType = "docx"
|
|
}
|
|
|
|
setNewMessageFiles(prev => [
|
|
...prev,
|
|
{
|
|
id: "loading",
|
|
name: file.name,
|
|
type: simplifiedFileType,
|
|
file: file
|
|
}
|
|
])
|
|
|
|
// Handle docx files
|
|
if (
|
|
file.type.includes(
|
|
"vnd.openxmlformats-officedocument.wordprocessingml.document" ||
|
|
"docx"
|
|
)
|
|
) {
|
|
const arrayBuffer = await file.arrayBuffer()
|
|
const result = await mammoth.extractRawText({
|
|
arrayBuffer
|
|
})
|
|
|
|
const createdFile = await createDocXFile(
|
|
result.value,
|
|
file,
|
|
{
|
|
user_id: profile.user_id,
|
|
description: "",
|
|
file_path: "",
|
|
name: file.name,
|
|
size: file.size,
|
|
tokens: 0,
|
|
type: simplifiedFileType
|
|
},
|
|
selectedWorkspace.id,
|
|
chatSettings.embeddingsProvider
|
|
)
|
|
|
|
setFiles(prev => [...prev, createdFile])
|
|
|
|
setNewMessageFiles(prev =>
|
|
prev.map(item =>
|
|
item.id === "loading"
|
|
? {
|
|
id: createdFile.id,
|
|
name: createdFile.name,
|
|
type: createdFile.type,
|
|
file: file
|
|
}
|
|
: item
|
|
)
|
|
)
|
|
|
|
reader.onloadend = null
|
|
|
|
return
|
|
} else {
|
|
// Use readAsArrayBuffer for PDFs and readAsText for other types
|
|
file.type.includes("pdf")
|
|
? reader.readAsArrayBuffer(file)
|
|
: reader.readAsText(file)
|
|
}
|
|
} else {
|
|
throw new Error("Unsupported file type")
|
|
}
|
|
|
|
reader.onloadend = async function () {
|
|
try {
|
|
if (file.type.includes("image")) {
|
|
// Create a temp url for the image file
|
|
const imageUrl = URL.createObjectURL(file)
|
|
|
|
// This is a temporary image for display purposes in the chat input
|
|
setNewMessageImages(prev => [
|
|
...prev,
|
|
{
|
|
messageId: "temp",
|
|
path: "",
|
|
base64: reader.result, // base64 image
|
|
url: imageUrl,
|
|
file
|
|
}
|
|
])
|
|
} else {
|
|
const createdFile = await createFile(
|
|
file,
|
|
{
|
|
user_id: profile.user_id,
|
|
description: "",
|
|
file_path: "",
|
|
name: file.name,
|
|
size: file.size,
|
|
tokens: 0,
|
|
type: simplifiedFileType
|
|
},
|
|
selectedWorkspace.id,
|
|
chatSettings.embeddingsProvider
|
|
)
|
|
|
|
setFiles(prev => [...prev, createdFile])
|
|
|
|
setNewMessageFiles(prev =>
|
|
prev.map(item =>
|
|
item.id === "loading"
|
|
? {
|
|
id: createdFile.id,
|
|
name: createdFile.name,
|
|
type: createdFile.type,
|
|
file: file
|
|
}
|
|
: item
|
|
)
|
|
)
|
|
}
|
|
} catch (error: any) {
|
|
toast.error("Failed to upload. " + error?.message, {
|
|
duration: 10000
|
|
})
|
|
setNewMessageImages(prev =>
|
|
prev.filter(img => img.messageId !== "temp")
|
|
)
|
|
setNewMessageFiles(prev => prev.filter(file => file.id !== "loading"))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
handleSelectDeviceFile,
|
|
filesToAccept
|
|
}
|
|
}
|