refactor: restructure PDF export functionality and update context handling

This commit is contained in:
suyao 2025-09-12 07:25:53 +08:00
parent 009e0d0877
commit 60e69ad49c
No known key found for this signature in database
4 changed files with 84 additions and 33 deletions

View File

@ -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')

View File

@ -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<RichEditorRef>
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<NotesSettings>) => 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',

View File

@ -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<RichEditorRef>,
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<RichEditorRef>,
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 (
<Container id="notes-page">
<Navbar>
@ -622,6 +667,7 @@ const NotesPage: FC = () => {
onMoveNode={handleMoveNode}
onSortNodes={handleSortNodes}
onUploadFiles={handleUploadFiles}
onExportToPDF={handleExportToPDF}
/>
</motion.div>
)}

View File

@ -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<RichEditorRef>
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)
}
}