返回 oh-my-ppt
useSessionPageActions.ts
根目录 / src / renderer / src / components / session-detail / hooks / useSessionPageActions.ts
1 import { useCallback } from 'react'
2 import { ipc } from '@renderer/lib/ipc'
3 import {
4 useGenerateStore,
5 useSessionDetailUiStore,
6 useSessionStore,
7 useToastStore
8 } from '@renderer/store'
9 import { useT } from '@renderer/i18n'
10 import type { SessionPreviewPage } from '../shared/types'
11 import { useSessionExportActions } from './useSessionExportActions'
12
13 export function useSessionPageActions(sessionId: string): {
14 isExportingPptx: boolean
15 exportPagePptx: (page: SessionPreviewPage, options?: { imageOnly?: boolean }) => void
16 exportOutlinesMarkdown: () => void
17 renamePage: (page: SessionPreviewPage) => void
18 deletePage: (page: SessionPreviewPage) => void
19 duplicatePage: (page: SessionPreviewPage) => void
20 } {
21 const t = useT()
22 const isExportingPptx = useSessionDetailUiStore((state) => state.isExportingPptx)
23 const openPageTitleEdit = useSessionDetailUiStore((state) => state.openPageTitleEdit)
24 const setDeleteConfirmPageId = useSessionDetailUiStore((state) => state.setDeleteConfirmPageId)
25 const loadSession = useSessionStore((state) => state.loadSession)
26 const toastError = useToastStore((state) => state.error)
27 const exportActions = useSessionExportActions(sessionId)
28
29 const exportPagePptx = useCallback(
30 (page: SessionPreviewPage, options?: { imageOnly?: boolean }) => {
31 void exportActions.exportPptx({ pageId: page.id, ...options })
32 },
33 [exportActions]
34 )
35
36 const exportOutlinesMarkdown = useCallback(() => {
37 void exportActions.exportOutlinesMarkdown()
38 }, [exportActions])
39
40 const renamePage = useCallback(
41 (page: SessionPreviewPage) => {
42 openPageTitleEdit(page.id, page.title || '')
43 },
44 [openPageTitleEdit]
45 )
46
47 const deletePage = useCallback(
48 (page: SessionPreviewPage) => {
49 setDeleteConfirmPageId(page.id)
50 },
51 [setDeleteConfirmPageId]
52 )
53
54 const duplicatePage = useCallback(
55 (page: SessionPreviewPage) => {
56 if (!sessionId || !page.id) return
57 const ui = useSessionDetailUiStore.getState()
58 if (ui.isAddingPage || ui.isManagingPages) return
59 ui.setIsAddingPage(true)
60 let targetSelection: string | null | undefined
61 void (async () => {
62 try {
63 const result = await ipc.duplicateSessionPage({
64 sessionId,
65 sourcePageId: page.id
66 })
67 useGenerateStore.getState().setPages(result.generatedPages)
68 await loadSession(sessionId)
69 useGenerateStore.getState().setPages(useSessionStore.getState().currentGeneratedPages)
70 targetSelection = result.selectedPageId || null
71 useSessionDetailUiStore.getState().bumpPreviewKey()
72 void ipc
73 .clearSpeechScript(sessionId)
74 .catch((err) => console.warn('[speech] clearSpeechScript failed', err))
75 } catch (err) {
76 const message =
77 err instanceof Error ? err.message : t('pageManagement.duplicatePageFailed')
78 toastError(message)
79 } finally {
80 useSessionDetailUiStore.getState().finishAddPage(targetSelection)
81 }
82 })()
83 },
84 [sessionId, loadSession, t, toastError]
85 )
86
87 return {
88 isExportingPptx,
89 exportPagePptx,
90 exportOutlinesMarkdown,
91 renamePage,
92 deletePage,
93 duplicatePage
94 }
95 }
96
96 lines TYPESCRIPT