From e6ef10e96e9a2576db6a8373b665fea42ebe769d Mon Sep 17 00:00:00 2001 From: dakai Date: Sun, 6 Oct 2024 15:30:24 +0800 Subject: [PATCH] refactor(client): update file handling in file upload functions --- app/client/api.ts | 4 ++-- app/components/chat.module.scss | 27 +++++++++++---------------- app/components/chat.tsx | 31 +++++++++++++++++-------------- app/store/chat.ts | 1 + app/utils.ts | 17 +++++++++++------ 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/app/client/api.ts b/app/client/api.ts index c74c883db..f38c20330 100644 --- a/app/client/api.ts +++ b/app/client/api.ts @@ -37,14 +37,14 @@ export interface MultimodalContent { file_url?: { url: string; name: string; - tokenCount?: string; + tokenCount?: number; }; } export interface UploadFile { name: string; url: string; - tokenCount?: string; + tokenCount?: number; } export interface RequestMessage { diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss index 672c7bffd..9399ece2a 100644 --- a/app/components/chat.module.scss +++ b/app/components/chat.module.scss @@ -71,37 +71,32 @@ border-radius: 5px; margin-right: 10px; - .attach-file-name-full { - max-width:calc(62vw); - display:flex; + %attach-file-name-common { + display:flex; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + } + .attach-file-name-full { + @extend %attach-file-name-common; + max-width:calc(62vw); + } .attach-file-name-half { + @extend %attach-file-name-common; max-width:calc(45vw); - display:flex; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; } .attach-file-name-less { + @extend %attach-file-name-common; max-width:calc(28vw); - display:flex; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; } .attach-file-name-min { + @extend %attach-file-name-common; max-width:calc(12vw); - display:flex; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } + } .attach-file-icon { min-width: 16px; max-width: 16px; diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 9975e33df..b128f1e7a 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -80,6 +80,7 @@ import { import type { UploadFile } from "../client/api"; import { uploadImage as uploadImageRemote } from "@/app/utils/chat"; +import { uploadImage as uploadFileRemote } from "@/app/utils/chat"; import dynamic from "next/dynamic"; @@ -1193,7 +1194,9 @@ function _Chat() { setIsLoading(true); const textContent = getMessageTextContent(userMessage); const images = getMessageImages(userMessage); - chatStore.onUserInput(textContent, images).then(() => setIsLoading(false)); + chatStore + .onUserInput(textContent, images, attachFiles) + .then(() => setIsLoading(false)); inputRef.current?.focus(); }; @@ -1488,20 +1491,20 @@ function _Chat() { fileInput.multiple = true; fileInput.onchange = (event: any) => { setUploading(true); - const files = event.target.files; + const inputFiles = event.target.files; const imagesData: UploadFile[] = []; (async () => { - for (let i = 0; i < files.length; i++) { - const file = files[i]; + for (let i = 0; i < inputFiles.length; i++) { + const file = inputFiles[i]; try { - const dataUrl = await uploadImageRemote(file); + const dataUrl = await uploadFileRemote(file); const fileData: UploadFile = { name: file.name, url: dataUrl }; - const tokenCount = await countTokens(fileData); + const tokenCount: number = await countTokens(fileData); fileData.tokenCount = tokenCount; imagesData.push(fileData); if ( imagesData.length === 3 || - imagesData.length === files.length + imagesData.length === inputFiles.length ) { setUploading(false); res(imagesData); @@ -1945,7 +1948,7 @@ function _Chat() { {getMessageFiles(message).length > 0 && (
{getMessageFiles(message).map((file, index) => { - const extension: DefaultExtensionType = file.url + const extension: DefaultExtensionType = file.name .split(".") .pop() ?.toLowerCase() as DefaultExtensionType; @@ -1970,7 +1973,7 @@ function _Chat() { styles["chat-message-item-file-name"] } > - {file.name} {file.tokenCount} + {file.name} {file.tokenCount}K
); @@ -2072,7 +2075,7 @@ function _Chat() { {attachFiles.length != 0 && (
{attachFiles.map((file, index) => { - const extension: DefaultExtensionType = file.url + const extension: DefaultExtensionType = file.name .split(".") .pop() ?.toLowerCase() as DefaultExtensionType; @@ -2087,22 +2090,22 @@ function _Chat() {
{attachImages.length == 0 && (
- {file.name} {file.tokenCount} + {file.name} {file.tokenCount}K
)} {attachImages.length == 1 && (
- {file.name} {file.tokenCount} + {file.name} {file.tokenCount}K
)} {attachImages.length == 2 && (
- {file.name} {file.tokenCount} + {file.name} {file.tokenCount}K
)} {attachImages.length == 3 && (
- {file.name} {file.tokenCount} + {file.name} {file.tokenCount}K
)} diff --git a/app/store/chat.ts b/app/store/chat.ts index 64ed375c2..2fbd56c5e 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -351,6 +351,7 @@ export const useChatStore = createPersistStore( if (attachFiles && attachFiles.length > 0) { let fileContent = userContent + " Here are the files: \n"; for (let i = 0; i < attachFiles.length; i++) { + fileContent += attachFiles[i].name + "\n"; fileContent += await readFileContent(attachFiles[i]); } mContent = [ diff --git a/app/utils.ts b/app/utils.ts index 76bc9e014..2d0343a36 100644 --- a/app/utils.ts +++ b/app/utils.ts @@ -18,6 +18,10 @@ export function trimTopic(topic: string) { } export const readFileContent = async (file: UploadFile): Promise => { + const host_url = new URL(window.location.href); + if (!file.url.includes(host_url.host)) { + throw new Error(`The URL ${file.url} is not allowed to access.`); + } try { const response = await fetch(file.url); if (!response.ok) { @@ -25,9 +29,10 @@ export const readFileContent = async (file: UploadFile): Promise => { `Failed to fetch content from ${file.url}: ${response.statusText}`, ); } - const content = await response.text(); - const result = file.name + "\n" + content; - return result; + //const content = await response.text(); + //const result = file.name + "\n" + content; + //return result; + return await response.text(); } catch (error) { console.error("Error reading file content:", error); return ""; @@ -60,7 +65,7 @@ export const countTokens = async (file: UploadFile) => { totalTokens += 0.98; } } - let totalTokenCount = (totalTokens / 1000).toFixed(2).toString() + "K"; + const totalTokenCount: number = +(totalTokens / 1000).toFixed(2); return totalTokenCount; }; @@ -303,8 +308,8 @@ export function getMessageFiles(message: RequestMessage): UploadFile[] { } const files: UploadFile[] = []; for (const c of message.content) { - if (c.type === "file_url") { - files.push(c.file_url ? c.file_url : { name: "", url: "" }); + if (c.type === "file_url" && c.file_url) { + files.push(c.file_url); } } return files;