Timothy Jaeryang Baek 3 месяцев назад
Родитель
Сommit
67aa1b028d

+ 6 - 111
src/lib/components/notes/NoteEditor.svelte

@@ -38,11 +38,12 @@
 		WEBUI_NAME
 	} from '$lib/stores';
 
-	import NotePanel from '$lib/components/notes/NotePanel.svelte';
+	import { downloadPdf } from './utils';
 
 	import Controls from './NoteEditor/Controls.svelte';
 	import Chat from './NoteEditor/Chat.svelte';
 
+	import NotePanel from '$lib/components/notes/NotePanel.svelte';
 	import AccessControlModal from '$lib/components/workspace/common/AccessControlModal.svelte';
 
 	async function loadLocale(locales) {
@@ -566,117 +567,11 @@ ${content}
 			const blob = new Blob([note.data.content.md], { type: 'text/markdown' });
 			saveAs(blob, `${note.title}.md`);
 		} else if (type === 'pdf') {
-			await downloadPdf(note);
-		}
-	};
-
-	const downloadPdf = async (note) => {
-		try {
-			const [{ default: jsPDF }, { default: html2canvas }] = await Promise.all([
-				import('jspdf'),
-				import('html2canvas-pro')
-			]);
-
-			// Define a fixed virtual screen size
-			const virtualWidth = 1024; // Fixed width (adjust as needed)
-			const virtualHeight = 1400; // Fixed height (adjust as needed)
-
-			// STEP 1. Get a DOM node to render
-			const html = note.data?.content?.html ?? '';
-			const isDarkMode = document.documentElement.classList.contains('dark');
-
-			let node;
-			if (html instanceof HTMLElement) {
-				node = html;
-			} else {
-				const virtualWidth = 800; // px, fixed width for cloned element
-
-				// Clone and style
-				node = document.createElement('div');
-
-				// title node
-				const titleNode = document.createElement('div');
-				titleNode.textContent = note.title;
-				titleNode.style.fontSize = '24px';
-				titleNode.style.fontWeight = 'medium';
-				titleNode.style.paddingBottom = '20px';
-				titleNode.style.color = isDarkMode ? 'white' : 'black';
-				node.appendChild(titleNode);
-
-				const contentNode = document.createElement('div');
-
-				contentNode.innerHTML = html;
-
-				node.appendChild(contentNode);
-
-				node.classList.add('text-black');
-				node.classList.add('dark:text-white');
-				node.style.width = `${virtualWidth}px`;
-				node.style.position = 'absolute';
-				node.style.left = '-9999px';
-				node.style.height = 'auto';
-				node.style.padding = '40px 40px';
-
-				console.log(node);
-				document.body.appendChild(node);
-			}
-
-			// Render to canvas with predefined width
-			const canvas = await html2canvas(node, {
-				useCORS: true,
-				backgroundColor: isDarkMode ? '#000' : '#fff',
-				scale: 2, // Keep at 1x to avoid unexpected enlargements
-				width: virtualWidth, // Set fixed virtual screen width
-				windowWidth: virtualWidth, // Ensure consistent rendering
-				windowHeight: virtualHeight
-			});
-
-			// Remove hidden node if needed
-			if (!(html instanceof HTMLElement)) {
-				document.body.removeChild(node);
-			}
-
-			const imgData = canvas.toDataURL('image/jpeg', 0.7);
-
-			// A4 page settings
-			const pdf = new jsPDF('p', 'mm', 'a4');
-			const imgWidth = 210; // A4 width in mm
-			const pageWidthMM = 210; // A4 width in mm
-			const pageHeight = 297; // A4 height in mm
-			const pageHeightMM = 297; // A4 height in mm
-
-			if (isDarkMode) {
-				pdf.setFillColor(0, 0, 0);
-				pdf.rect(0, 0, pageWidthMM, pageHeightMM, 'F'); // black bg
-			}
-
-			// Maintain aspect ratio
-			const imgHeight = (canvas.height * imgWidth) / canvas.width;
-			let heightLeft = imgHeight;
-			let position = 0;
-
-			pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
-			heightLeft -= pageHeight;
-
-			// Handle additional pages
-			while (heightLeft > 0) {
-				position -= pageHeight;
-				pdf.addPage();
-
-				if (isDarkMode) {
-					pdf.setFillColor(0, 0, 0);
-					pdf.rect(0, 0, pageWidthMM, pageHeightMM, 'F'); // black bg
-				}
-
-				pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
-				heightLeft -= pageHeight;
+			try {
+				await downloadPdf(note);
+			} catch (error) {
+				toast.error(`${error}`);
 			}
-
-			pdf.save(`${note.title}.pdf`);
-		} catch (error) {
-			console.error('Error generating PDF', error);
-
-			toast.error(`${error}`);
 		}
 	};
 

+ 10 - 72
src/lib/components/notes/Notes.svelte

@@ -36,6 +36,8 @@
 	import { createNewNote, deleteNoteById, getNotes } from '$lib/apis/notes';
 	import { capitalizeFirstLetter, copyToClipboard, getTimeRange } from '$lib/utils';
 
+	import { downloadPdf } from './utils';
+
 	import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
 	import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
 	import Search from '../icons/Search.svelte';
@@ -124,82 +126,18 @@
 	};
 
 	const downloadHandler = async (type) => {
-		console.log('downloadHandler', type);
-		console.log('selectedNote', selectedNote);
-		if (type === 'md') {
+		if (type === 'txt') {
+			const blob = new Blob([selectedNote.data.content.md], { type: 'text/plain' });
+			saveAs(blob, `${selectedNote.title}.txt`);
+		} else if (type === 'md') {
 			const blob = new Blob([selectedNote.data.content.md], { type: 'text/markdown' });
 			saveAs(blob, `${selectedNote.title}.md`);
 		} else if (type === 'pdf') {
-			await downloadPdf(selectedNote);
-		}
-	};
-
-	const downloadPdf = async (note) => {
-		try {
-			const [{ default: jsPDF }, { default: html2canvas }] = await Promise.all([
-				import('jspdf'),
-				import('html2canvas-pro')
-			]);
-
-			// Define a fixed virtual screen size
-			const virtualWidth = 1024; // Fixed width (adjust as needed)
-			const virtualHeight = 1400; // Fixed height (adjust as needed)
-
-			// STEP 1. Get a DOM node to render
-			const html = note.data?.content?.html ?? '';
-			let node;
-			if (html instanceof HTMLElement) {
-				node = html;
-			} else {
-				// If it's HTML string, render to a temporary hidden element
-				node = document.createElement('div');
-				node.innerHTML = html;
-				document.body.appendChild(node);
-			}
-
-			// Render to canvas with predefined width
-			const canvas = await html2canvas(node, {
-				useCORS: true,
-				scale: 2, // Keep at 1x to avoid unexpected enlargements
-				width: virtualWidth, // Set fixed virtual screen width
-				windowWidth: virtualWidth, // Ensure consistent rendering
-				windowHeight: virtualHeight
-			});
-
-			// Remove hidden node if needed
-			if (!(html instanceof HTMLElement)) {
-				document.body.removeChild(node);
-			}
-
-			const imgData = canvas.toDataURL('image/jpeg', 0.7);
-
-			// A4 page settings
-			const pdf = new jsPDF('p', 'mm', 'a4');
-			const imgWidth = 210; // A4 width in mm
-			const pageHeight = 297; // A4 height in mm
-
-			// Maintain aspect ratio
-			const imgHeight = (canvas.height * imgWidth) / canvas.width;
-			let heightLeft = imgHeight;
-			let position = 0;
-
-			pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
-			heightLeft -= pageHeight;
-
-			// Handle additional pages
-			while (heightLeft > 0) {
-				position -= pageHeight;
-				pdf.addPage();
-
-				pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
-				heightLeft -= pageHeight;
+			try {
+				await downloadPdf(selectedNote);
+			} catch (error) {
+				toast.error(`${error}`);
 			}
-
-			pdf.save(`${note.title}.pdf`);
-		} catch (error) {
-			console.error('Error generating PDF', error);
-
-			toast.error(`${error}`);
 		}
 	};
 

+ 103 - 0
src/lib/components/notes/utils.ts

@@ -0,0 +1,103 @@
+export const downloadPdf = async (note) => {
+	const [{ default: jsPDF }, { default: html2canvas }] = await Promise.all([
+		import('jspdf'),
+		import('html2canvas-pro')
+	]);
+
+	// Define a fixed virtual screen size
+	const virtualWidth = 1024; // Fixed width (adjust as needed)
+	const virtualHeight = 1400; // Fixed height (adjust as needed)
+
+	// STEP 1. Get a DOM node to render
+	const html = note.data?.content?.html ?? '';
+	const isDarkMode = document.documentElement.classList.contains('dark');
+
+	let node;
+	if (html instanceof HTMLElement) {
+		node = html;
+	} else {
+		const virtualWidth = 800; // px, fixed width for cloned element
+
+		// Clone and style
+		node = document.createElement('div');
+
+		// title node
+		const titleNode = document.createElement('div');
+		titleNode.textContent = note.title;
+		titleNode.style.fontSize = '24px';
+		titleNode.style.fontWeight = 'medium';
+		titleNode.style.paddingBottom = '20px';
+		titleNode.style.color = isDarkMode ? 'white' : 'black';
+		node.appendChild(titleNode);
+
+		const contentNode = document.createElement('div');
+
+		contentNode.innerHTML = html;
+
+		node.appendChild(contentNode);
+
+		node.classList.add('text-black');
+		node.classList.add('dark:text-white');
+		node.style.width = `${virtualWidth}px`;
+		node.style.position = 'absolute';
+		node.style.left = '-9999px';
+		node.style.height = 'auto';
+		node.style.padding = '40px 40px';
+
+		console.log(node);
+		document.body.appendChild(node);
+	}
+
+	// Render to canvas with predefined width
+	const canvas = await html2canvas(node, {
+		useCORS: true,
+		backgroundColor: isDarkMode ? '#000' : '#fff',
+		scale: 2, // Keep at 1x to avoid unexpected enlargements
+		width: virtualWidth, // Set fixed virtual screen width
+		windowWidth: virtualWidth, // Ensure consistent rendering
+		windowHeight: virtualHeight
+	});
+
+	// Remove hidden node if needed
+	if (!(html instanceof HTMLElement)) {
+		document.body.removeChild(node);
+	}
+
+	const imgData = canvas.toDataURL('image/jpeg', 0.7);
+
+	// A4 page settings
+	const pdf = new jsPDF('p', 'mm', 'a4');
+	const imgWidth = 210; // A4 width in mm
+	const pageWidthMM = 210; // A4 width in mm
+	const pageHeight = 297; // A4 height in mm
+	const pageHeightMM = 297; // A4 height in mm
+
+	if (isDarkMode) {
+		pdf.setFillColor(0, 0, 0);
+		pdf.rect(0, 0, pageWidthMM, pageHeightMM, 'F'); // black bg
+	}
+
+	// Maintain aspect ratio
+	const imgHeight = (canvas.height * imgWidth) / canvas.width;
+	let heightLeft = imgHeight;
+	let position = 0;
+
+	pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
+	heightLeft -= pageHeight;
+
+	// Handle additional pages
+	while (heightLeft > 0) {
+		position -= pageHeight;
+		pdf.addPage();
+
+		if (isDarkMode) {
+			pdf.setFillColor(0, 0, 0);
+			pdf.rect(0, 0, pageWidthMM, pageHeightMM, 'F'); // black bg
+		}
+
+		pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
+		heightLeft -= pageHeight;
+	}
+
+	pdf.save(`${note.title}.pdf`);
+};