mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-16 14:03:43 +08:00
feat: add UploadFile interface for handling file uploads
This commit is contained in:
@@ -71,16 +71,52 @@
|
||||
border-radius: 5px;
|
||||
margin-right: 10px;
|
||||
|
||||
.attach-file-name-full {
|
||||
max-width:calc(62vw);
|
||||
display:flex;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.attach-file-name-half {
|
||||
max-width:calc(45vw);
|
||||
display:flex;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.attach-file-name-less {
|
||||
max-width:calc(28vw);
|
||||
display:flex;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.attach-file-name-min {
|
||||
max-width:calc(12vw);
|
||||
display:flex;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.attach-file-icon {
|
||||
min-width: 16px;
|
||||
max-width: 16px;
|
||||
}
|
||||
|
||||
.attach-file-icon:hover {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.attach-image-mask {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: all ease 0.2s;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.attach-image-mask:hover {
|
||||
@@ -88,8 +124,8 @@
|
||||
}
|
||||
|
||||
.delete-image {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 16px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
float: left;
|
||||
|
||||
@@ -69,12 +69,15 @@ import {
|
||||
useMobileScreen,
|
||||
getMessageTextContent,
|
||||
getMessageImages,
|
||||
getMessageFiles,
|
||||
isVisionModel,
|
||||
isDalle3,
|
||||
showPlugins,
|
||||
safeLocalStorage,
|
||||
} from "../utils";
|
||||
|
||||
import type { UploadFile } from "../client/api";
|
||||
|
||||
import { uploadImage as uploadImageRemote } from "@/app/utils/chat";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
@@ -448,7 +451,7 @@ export function ChatActions(props: {
|
||||
uploadDocument: () => void;
|
||||
uploadImage: () => void;
|
||||
setAttachImages: (images: string[]) => void;
|
||||
setAttachFiles: (files: string[]) => void;
|
||||
setAttachFiles: (files: UploadFile[]) => void;
|
||||
setUploading: (uploading: boolean) => void;
|
||||
showPromptModal: () => void;
|
||||
scrollToBottom: () => void;
|
||||
@@ -957,7 +960,7 @@ function _Chat() {
|
||||
const isMobileScreen = useMobileScreen();
|
||||
const navigate = useNavigate();
|
||||
const [attachImages, setAttachImages] = useState<string[]>([]);
|
||||
const [attachFiles, setAttachFiles] = useState<string[]>([]);
|
||||
const [attachFiles, setAttachFiles] = useState<UploadFile[]>([]);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
|
||||
// prompt hints
|
||||
@@ -1475,11 +1478,11 @@ function _Chat() {
|
||||
);
|
||||
|
||||
async function uploadDocument() {
|
||||
const files: string[] = [];
|
||||
const files: UploadFile[] = [];
|
||||
files.push(...attachFiles);
|
||||
|
||||
files.push(
|
||||
...(await new Promise<string[]>((res, rej) => {
|
||||
...(await new Promise<UploadFile[]>((res, rej) => {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = "text/*";
|
||||
@@ -1487,12 +1490,12 @@ function _Chat() {
|
||||
fileInput.onchange = (event: any) => {
|
||||
setUploading(true);
|
||||
const files = event.target.files;
|
||||
const imagesData: string[] = [];
|
||||
const imagesData: UploadFile[] = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = event.target.files[i];
|
||||
uploadImageRemote(file)
|
||||
.then((dataUrl) => {
|
||||
imagesData.push(dataUrl);
|
||||
imagesData.push({ name: file.name, url: dataUrl });
|
||||
if (
|
||||
imagesData.length === 3 ||
|
||||
imagesData.length === files.length
|
||||
@@ -1937,6 +1940,13 @@ function _Chat() {
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{getMessageFiles(message).length > 0 && (
|
||||
<div>
|
||||
{getMessageFiles(message).map((file, index) => {
|
||||
return <div key={index}></div>;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles["chat-message-action-date"]}>
|
||||
@@ -2032,7 +2042,7 @@ function _Chat() {
|
||||
{attachFiles.length != 0 && (
|
||||
<div className={styles["attach-files"]}>
|
||||
{attachFiles.map((file, index) => {
|
||||
const extension: DefaultExtensionType = file
|
||||
const extension: DefaultExtensionType = file.url
|
||||
.split(".")
|
||||
.pop()
|
||||
?.toLowerCase() as DefaultExtensionType;
|
||||
@@ -2045,7 +2055,27 @@ function _Chat() {
|
||||
>
|
||||
<FileIcon {...style} />
|
||||
</div>
|
||||
<span>{extension}</span>
|
||||
{attachImages.length == 0 && (
|
||||
<div className={styles["attach-file-name-full"]}>
|
||||
{file.name}
|
||||
</div>
|
||||
)}
|
||||
{attachImages.length == 1 && (
|
||||
<div className={styles["attach-file-name-half"]}>
|
||||
{file.name}
|
||||
</div>
|
||||
)}
|
||||
{attachImages.length == 2 && (
|
||||
<div className={styles["attach-file-name-less"]}>
|
||||
{file.name}
|
||||
</div>
|
||||
)}
|
||||
{attachImages.length == 3 && (
|
||||
<div className={styles["attach-file-name-min"]}>
|
||||
{file.name}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles["attach-image-mask"]}>
|
||||
<DeleteImageButton
|
||||
deleteImage={() => {
|
||||
|
||||
Reference in New Issue
Block a user