diff --git a/src/renderer/src/pages/notes/HeaderNavbar.tsx b/src/renderer/src/pages/notes/HeaderNavbar.tsx index 45b015d15b..a0abc691ee 100644 --- a/src/renderer/src/pages/notes/HeaderNavbar.tsx +++ b/src/renderer/src/pages/notes/HeaderNavbar.tsx @@ -11,7 +11,8 @@ import { MoreHorizontal, PanelLeftClose, PanelRightClose, Star } from 'lucide-re import { useCallback, useEffect, useState } from 'react' import styled from 'styled-components' -import { handleExportPDF, MenuContext, menuItems } from './MenuConfig' +import { menuItems } from './MenuConfig' +import { ExportContext, handleExportPDF } from './utils/exportUtils' const logger = loggerService.withContext('HeaderNavbar') @@ -48,7 +49,7 @@ const HeaderNavbar = ({ notesTree, getCurrentNoteContent, onToggleStar, editorRe }, [getCurrentNoteContent]) const handleExportPDFAction = useCallback(async () => { - const menuContext: MenuContext = { + const menuContext: ExportContext = { editorRef, currentContent, fileName: activeNode?.name || t('notes.title') diff --git a/src/renderer/src/pages/notes/MenuConfig.tsx b/src/renderer/src/pages/notes/MenuConfig.tsx index bb564c09aa..cc41faba48 100644 --- a/src/renderer/src/pages/notes/MenuConfig.tsx +++ b/src/renderer/src/pages/notes/MenuConfig.tsx @@ -1,15 +1,8 @@ -import { loggerService } from '@logger' -import { RichEditorRef } from '@renderer/components/RichEditor/types' import { NotesSettings } from '@renderer/store/note' import { Copy, Download, MonitorSpeaker, Type } from 'lucide-react' -import { ReactNode, RefObject } from 'react' +import { ReactNode } from 'react' -const logger = loggerService.withContext('MenuConfig') -export interface MenuContext { - editorRef: RefObject - currentContent: string - fileName: string -} +import { ExportContext } from './utils/exportUtils' export interface MenuItem { key: string @@ -19,7 +12,7 @@ export interface MenuItem { action?: ( settings: NotesSettings, updateSettings: (newSettings: Partial) => void, - context?: MenuContext + context?: ExportContext ) => void children?: MenuItem[] isActive?: (settings: NotesSettings) => boolean @@ -28,27 +21,6 @@ export interface MenuItem { exportPdfAction?: boolean } -export const handleExportPDF = async (context: MenuContext) => { - if (!context.editorRef?.current || !context.currentContent?.trim()) { - return - } - - try { - // Use Tiptap's getHTML API to get HTML content - const htmlContent = context.editorRef.current.getHtml() - const filename = context.fileName ? `${context.fileName}.pdf` : 'note.pdf' - const result = await window.api.export.toPDF(htmlContent, filename) - - if (result.success) { - logger.info('PDF exported successfully to:', result.filePath) - } else { - logger.error('PDF export failed:', result.message) - } - } catch (error: any) { - logger.error('PDF export error:', error) - } -} - export const menuItems: MenuItem[] = [ { key: 'copy-content', diff --git a/src/renderer/src/pages/notes/NotesPage.tsx b/src/renderer/src/pages/notes/NotesPage.tsx index b3a3d564db..548ff2b51f 100644 --- a/src/renderer/src/pages/notes/NotesPage.tsx +++ b/src/renderer/src/pages/notes/NotesPage.tsx @@ -29,6 +29,7 @@ import styled from 'styled-components' import HeaderNavbar from './HeaderNavbar' import NotesEditor from './NotesEditor' import NotesSidebar from './NotesSidebar' +import { handleExportPDF } from './utils/exportUtils' const logger = loggerService.withContext('NotesPage') @@ -595,6 +596,50 @@ const NotesPage: FC = () => { } }, [currentContent, settings.defaultEditMode]) + // 处理PDF导出 - 复用MenuConfig中的导出逻辑 + const handleExportToPDF = useCallback( + async (nodeId: string) => { + try { + const node = findNodeById(notesTree, nodeId) + if (!node || node.type !== 'file') { + logger.warn('Cannot export PDF: Invalid node', { nodeId }) + return + } + + // 如果是当前活动的笔记,直接使用当前编辑器 + if (activeFilePath === node.externalPath && editorRef.current) { + const filename = node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name + await handleExportPDF({ + editorRef: editorRef as React.RefObject, + currentContent: getCurrentNoteContent(), + fileName: filename + }) + return + } + + // 如果不是当前笔记,先切换到该笔记再导出 + dispatch(setActiveFilePath(node.externalPath)) + invalidateFileContent(node.externalPath) + + // 等待内容加载后再导出 + setTimeout(async () => { + if (editorRef.current) { + const filename = node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name + await handleExportPDF({ + editorRef: editorRef as React.RefObject, + currentContent: editorRef.current.getMarkdown(), + fileName: filename + }) + } + }, 500) + } catch (error) { + logger.error('Failed to export PDF:', error as Error) + window.toast.error(`导出PDF失败: ${(error as Error).message}`) + } + }, + [findNodeById, notesTree, activeFilePath, editorRef, getCurrentNoteContent, dispatch, invalidateFileContent] + ) + return ( @@ -622,6 +667,7 @@ const NotesPage: FC = () => { onMoveNode={handleMoveNode} onSortNodes={handleSortNodes} onUploadFiles={handleUploadFiles} + onExportToPDF={handleExportToPDF} /> )} diff --git a/src/renderer/src/pages/notes/utils/exportUtils.ts b/src/renderer/src/pages/notes/utils/exportUtils.ts new file mode 100644 index 0000000000..3bdf3972fa --- /dev/null +++ b/src/renderer/src/pages/notes/utils/exportUtils.ts @@ -0,0 +1,32 @@ +import { loggerService } from '@logger' +import { RichEditorRef } from '@renderer/components/RichEditor/types' +import { RefObject } from 'react' + +const logger = loggerService.withContext('exportUtils') + +export interface ExportContext { + editorRef: RefObject + currentContent: string + fileName: string +} + +export const handleExportPDF = async (context: ExportContext) => { + if (!context.editorRef?.current || !context.currentContent?.trim()) { + return + } + + try { + // Use Tiptap's getHTML API to get HTML content + const htmlContent = context.editorRef.current.getHtml() + const filename = context.fileName ? `${context.fileName}.pdf` : 'note.pdf' + const result = await window.api.export.toPDF(htmlContent, filename) + + if (result.success) { + logger.info('PDF exported successfully to:', result.filePath) + } else { + logger.error('PDF export failed:', result.message) + } + } catch (error: any) { + logger.error('PDF export error:', error) + } +}