返回 oh-my-ppt
useSpeechScriptDrawerController.ts
根目录 / src / renderer / src / components / session-detail / speech / useSpeechScriptDrawerController.ts
1 import { useMemo } from 'react'
2 import { ipc } from '@renderer/lib/ipc'
3 import { useGenerateStore, useSessionDetailUiStore, useToastStore } from '@renderer/store'
4 import { useT } from '@renderer/i18n'
5 import { useModelAction } from '@renderer/hooks/useModelAction'
6 import type { SpeechConfig } from '@shared/speech'
7 import { normalizePagesForSelection } from '../shared/pageUtils'
8
9 export function useSpeechScriptDrawerController(sessionId: string) {
10 const t = useT()
11 const modelAction = useModelAction()
12 const currentPages = useGenerateStore((state) => state.currentPages)
13 const selectedPageId = useSessionDetailUiStore((state) => state.selectedPageId)
14 const open = useSessionDetailUiStore((state) => state.speechScriptDialogOpen)
15 const isGenerating = useSessionDetailUiStore((state) => state.isGeneratingSpeechScript)
16 const speechProgress = useSessionDetailUiStore((state) => state.speechProgress)
17 const speechConfig = useSessionDetailUiStore((state) => state.speechConfig)
18 const setSpeechConfig = useSessionDetailUiStore((state) => state.setSpeechConfig)
19 const setOpen = useSessionDetailUiStore((state) => state.setSpeechScriptDialogOpen)
20 const toastError = useToastStore((state) => state.error)
21
22 const pages = useMemo(() => normalizePagesForSelection(currentPages), [currentPages])
23 const selectedPage = useMemo(
24 () => pages.find((page) => page.id === selectedPageId) ?? pages[0] ?? null,
25 [pages, selectedPageId]
26 )
27
28 const handleGenerate = async (config: SpeechConfig): Promise<void> => {
29 const detailState = useSessionDetailUiStore.getState()
30 if (!sessionId || detailState.isGeneratingSpeechScript) return
31 detailState.setIsGeneratingSpeechScript(true)
32 detailState.setSpeechProgress(null)
33 try {
34 const modelConfigId = await modelAction.ensureModelActive(config.modelConfigId)
35 if (!modelConfigId) return
36 const result = await ipc.generateSpeechScript(sessionId, {
37 ...config,
38 modelConfigId,
39 currentPageId: config.scope === 'single' ? selectedPage?.id : undefined
40 })
41 if (!result.success) {
42 toastError(t('sessionDetail.speechScriptError'))
43 }
44 } catch (error) {
45 toastError(error instanceof Error ? error.message : t('sessionDetail.speechScriptError'))
46 } finally {
47 const state = useSessionDetailUiStore.getState()
48 state.setIsGeneratingSpeechScript(false)
49 state.setSpeechProgress(null)
50 }
51 }
52
53 return {
54 open,
55 isGenerating,
56 speechProgress,
57 speechConfig,
58 modelAction,
59 currentPageNumber: selectedPage?.pageNumber,
60 currentPageTitle: selectedPage?.title || undefined,
61 setSpeechConfig,
62 generate: (config: SpeechConfig) => void handleGenerate(config),
63 close: () => {
64 setOpen(false)
65 useSessionDetailUiStore.getState().setWorkspaceTab('preview')
66 }
67 }
68 }
69
69 lines TYPESCRIPT