| | import { isSvgMimeType, svgBase64UrlToPngDataURL } from './svg-to-png';
|
| | import { isWebpMimeType, webpBase64UrlToPngDataURL } from './webp-to-png';
|
| | import { FileTypeCategory } from '$lib/enums';
|
| | import { modelsStore } from '$lib/stores/models.svelte';
|
| | import { settingsStore } from '$lib/stores/settings.svelte';
|
| | import { toast } from 'svelte-sonner';
|
| | import { getFileTypeCategory } from '$lib/utils';
|
| | import { convertPDFToText } from './pdf-processing';
|
| |
|
| | |
| | |
| | |
| | |
| |
|
| | function readFileAsDataURL(file: File): Promise<string> {
|
| | return new Promise((resolve, reject) => {
|
| | const reader = new FileReader();
|
| | reader.onload = () => resolve(reader.result as string);
|
| | reader.onerror = () => reject(reader.error);
|
| | reader.readAsDataURL(file);
|
| | });
|
| | }
|
| |
|
| | |
| | |
| | |
| | |
| |
|
| | function readFileAsUTF8(file: File): Promise<string> {
|
| | return new Promise((resolve, reject) => {
|
| | const reader = new FileReader();
|
| | reader.onload = () => resolve(reader.result as string);
|
| | reader.onerror = () => reject(reader.error);
|
| | reader.readAsText(file);
|
| | });
|
| | }
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | export async function processFilesToChatUploaded(
|
| | files: File[],
|
| | activeModelId?: string
|
| | ): Promise<ChatUploadedFile[]> {
|
| | const results: ChatUploadedFile[] = [];
|
| |
|
| | for (const file of files) {
|
| | const id = Date.now().toString() + Math.random().toString(36).substr(2, 9);
|
| | const base: ChatUploadedFile = {
|
| | id,
|
| | name: file.name,
|
| | size: file.size,
|
| | type: file.type,
|
| | file
|
| | };
|
| |
|
| | try {
|
| | if (getFileTypeCategory(file.type) === FileTypeCategory.IMAGE) {
|
| | let preview = await readFileAsDataURL(file);
|
| |
|
| |
|
| | if (isSvgMimeType(file.type)) {
|
| | try {
|
| | preview = await svgBase64UrlToPngDataURL(preview);
|
| | } catch (err) {
|
| | console.error('Failed to convert SVG to PNG:', err);
|
| | }
|
| | } else if (isWebpMimeType(file.type)) {
|
| | try {
|
| | preview = await webpBase64UrlToPngDataURL(preview);
|
| | } catch (err) {
|
| | console.error('Failed to convert WebP to PNG:', err);
|
| | }
|
| | }
|
| |
|
| | results.push({ ...base, preview });
|
| | } else if (getFileTypeCategory(file.type) === FileTypeCategory.PDF) {
|
| |
|
| | try {
|
| | const textContent = await convertPDFToText(file);
|
| | results.push({ ...base, textContent });
|
| | } catch (err) {
|
| | console.warn('Failed to extract text from PDF, adding without content:', err);
|
| | results.push(base);
|
| | }
|
| |
|
| |
|
| | const hasVisionSupport = activeModelId
|
| | ? modelsStore.modelSupportsVision(activeModelId)
|
| | : false;
|
| | const currentConfig = settingsStore.config;
|
| | if (hasVisionSupport && !currentConfig.pdfAsImage) {
|
| | toast.info(`You can enable parsing PDF as images with vision models.`, {
|
| | duration: 8000,
|
| | action: {
|
| | label: 'Enable PDF as Images',
|
| | onClick: () => {
|
| | settingsStore.updateConfig('pdfAsImage', true);
|
| | toast.success('PDF parsing as images enabled!', {
|
| | duration: 3000
|
| | });
|
| | }
|
| | }
|
| | });
|
| | }
|
| | } else if (getFileTypeCategory(file.type) === FileTypeCategory.AUDIO) {
|
| |
|
| | const preview = await readFileAsDataURL(file);
|
| | results.push({ ...base, preview });
|
| | } else {
|
| |
|
| | try {
|
| | const textContent = await readFileAsUTF8(file);
|
| | results.push({ ...base, textContent });
|
| | } catch (err) {
|
| | console.warn('Failed to read file as text, adding without content:', err);
|
| | results.push(base);
|
| | }
|
| | }
|
| | } catch (error) {
|
| | console.error('Error processing file', file.name, error);
|
| | results.push(base);
|
| | }
|
| | }
|
| |
|
| | return results;
|
| | }
|
| |
|