feat: chat_file table

This commit is contained in:
Timothy Jaeryang Baek
2025-12-21 23:17:53 +04:00
parent a3458f492c
commit f1bf4f20c5
14 changed files with 382 additions and 101 deletions
+37 -51
View File
@@ -191,17 +191,11 @@
for (const type of item.types) {
if (type.startsWith('image/')) {
const blob = await item.getType(type);
const reader = new FileReader();
reader.onload = (event) => {
files = [
...files,
{
type: 'image',
url: event.target.result as string
}
];
};
reader.readAsDataURL(blob);
const file = new File([blob], `clipboard-image.${type.split('/')[1]}`, {
type: type
});
inputFilesHandler([file]);
}
}
}
@@ -527,8 +521,9 @@
// Convert the canvas to a Base64 image URL
const imageUrl = canvas.toDataURL('image/png');
// Add the captured image to the files array to render it
files = [...files, { type: 'image', url: imageUrl }];
const blob = await (await fetch(imageUrl)).blob();
const file = new File([blob], `screen-capture-${Date.now()}.png`, { type: 'image/png' });
inputFilesHandler([file]);
// Clean memory: Clear video srcObject
video.srcObject = null;
} catch (error) {
@@ -537,7 +532,7 @@
}
};
const uploadFileHandler = async (file, fullContext: boolean = false) => {
const uploadFileHandler = async (file, process = true, itemData = {}) => {
if ($_user?.role !== 'admin' && !($_user?.permissions?.chat?.file_upload ?? true)) {
toast.error($i18n.t('You do not have permission to upload files.'));
return null;
@@ -560,7 +555,7 @@
size: file.size,
error: '',
itemId: tempItemId,
...(fullContext ? { context: 'full' } : {})
...itemData
};
if (fileItem.size == 0) {
@@ -584,7 +579,7 @@
}
// During the file upload, file content is automatically extracted.
const uploadedFile = await uploadFile(localStorage.token, file, metadata);
const uploadedFile = await uploadFile(localStorage.token, file, metadata, process);
if (uploadedFile) {
console.log('File upload completed:', {
@@ -603,7 +598,8 @@
fileItem.id = uploadedFile.id;
fileItem.collection_name =
uploadedFile?.meta?.collection_name || uploadedFile?.collection_name;
fileItem.url = `${WEBUI_API_BASE_URL}/files/${uploadedFile.id}`;
fileItem.content_type = uploadedFile.meta?.content_type || uploadedFile.content_type;
fileItem.url = `${uploadedFile.id}`;
files = files;
} else {
@@ -726,19 +722,21 @@
};
let reader = new FileReader();
reader.onload = async (event) => {
let imageUrl = event.target.result;
imageUrl = await compressImageHandler(imageUrl, $settings, $config);
// Compress the image if settings or config require it
if ($settings?.imageCompression && $settings?.imageCompressionInChannels) {
imageUrl = await compressImageHandler(imageUrl, $settings, $config);
}
files = [
...files,
{
type: 'image',
url: `${imageUrl}`
}
];
const blob = await (await fetch(imageUrl)).blob();
const compressedFile = new File([blob], file.name, { type: file.type });
uploadFileHandler(compressedFile, false);
};
reader.readAsDataURL(file['type'] === 'image/heic' ? await convertHeicToJpeg(file) : file);
} else {
uploadFileHandler(file);
@@ -1146,11 +1144,15 @@
dir={$settings?.chatDirection ?? 'auto'}
>
{#each files as file, fileIdx}
{#if file.type === 'image'}
{#if file.type === 'image' || (file?.content_type ?? '').startsWith('image/')}
{@const fileUrl =
file.url.startsWith('data') || file.url.startsWith('http')
? file.url
: `${WEBUI_API_BASE_URL}/files/${file.url}${file?.content_type ? '/content' : ''}`}
<div class=" relative group">
<div class="relative flex items-center">
<Image
src={file.url}
src={fileUrl}
alt=""
imageClassName=" size-10 rounded-xl object-cover"
/>
@@ -1392,29 +1394,7 @@
if (clipboardData && clipboardData.items) {
for (const item of clipboardData.items) {
if (item.type.indexOf('image') !== -1) {
const blob = item.getAsFile();
const reader = new FileReader();
reader.onload = function (e) {
files = [
...files,
{
type: 'image',
url: `${e.target.result}`
}
];
};
reader.readAsDataURL(blob);
} else if (item?.kind === 'file') {
const file = item.getAsFile();
if (file) {
const _files = [file];
await inputFilesHandler(_files);
e.preventDefault();
}
} else if (item.type === 'text/plain') {
if (item.type === 'text/plain') {
if (($settings?.largeTextAsFile ?? false) && !shiftKey) {
const text = clipboardData.getData('text/plain');
@@ -1429,9 +1409,15 @@
}
);
await uploadFileHandler(file, true);
await uploadFileHandler(file, true, { context: 'full' });
}
}
} else {
const file = item.getAsFile();
if (file) {
await inputFilesHandler([file]);
e.preventDefault();
}
}
}
}