From b04f47ae815e5e7c67b0ac83bd830e4d9285f3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=B1=ED=83=9C=EA=B2=BD?= Date: Sun, 15 Mar 2026 18:34:48 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=8B=A4=EC=8B=9C=EA=B0=84=20=EC=9A=94?= =?UTF-8?q?=EC=95=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/recording/RightPanel.tsx | 4 +++- src/components/recording/SummaryTab.tsx | 31 +++++++++++++++++++------ src/hooks/useSocket.ts | 11 ++++++++- src/pages/RecordingPage.tsx | 6 ++++- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/components/recording/RightPanel.tsx b/src/components/recording/RightPanel.tsx index d4f060f..ec63880 100644 --- a/src/components/recording/RightPanel.tsx +++ b/src/components/recording/RightPanel.tsx @@ -7,11 +7,13 @@ type Tab = 'summary' | 'memo'; interface RightPanelProps { memos: MemoEntry[]; + summaries: string[]; defaultTab?: Tab; } export default function RightPanel({ memos, + summaries, defaultTab = 'summary', }: RightPanelProps) { const [activeTab, setActiveTab] = useState(defaultTab); @@ -52,7 +54,7 @@ export default function RightPanel({ {/* 탭 콘텐츠 */}
- {activeTab === 'summary' ? : } + {activeTab === 'summary' ? : }
); diff --git a/src/components/recording/SummaryTab.tsx b/src/components/recording/SummaryTab.tsx index 81e2267..af55fe9 100644 --- a/src/components/recording/SummaryTab.tsx +++ b/src/components/recording/SummaryTab.tsx @@ -1,11 +1,28 @@ -export default function SummaryTab() { +interface SummaryTabProps { + summaries: string[]; +} + +export default function SummaryTab({ summaries }: SummaryTabProps) { + if (summaries.length === 0) { + return ( +
+

+ 중요한 내용만 +
+ 실시간으로 정리해드릴게요! 📝 +

+
+ ); + } + return ( -
-

- 중요한 내용만 -
- 실시간으로 정리해드릴게요! 📝 -

+
+ {summaries.map((summary, index) => ( +
+

{index + 1}분

+

{summary}

+
+ ))}
); } diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 77fb939..26c1192 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -12,15 +12,18 @@ interface UseSocketReturn { export function useSocket( onSubtitleFinal: (text: string) => void, + onSummary: (text: string) => void, ): UseSocketReturn { const socketRef = useRef(null); const [isConnected, setIsConnected] = useState(false); const onSubtitleFinalRef = useRef(onSubtitleFinal); + const onSummaryRef = useRef(onSummary); useEffect(() => { onSubtitleFinalRef.current = onSubtitleFinal; - }, [onSubtitleFinal]); + onSummaryRef.current = onSummary; + }, [onSubtitleFinal, onSummary]); const connect = useCallback(() => { if (socketRef.current?.connected) return; @@ -47,6 +50,12 @@ export function useSocket( onSubtitleFinalRef.current(text); }); + socket.on('stt:summary', (...args: unknown[]) => { + const text = args[0] as string; + console.log('[Socket] summary:', text); + onSummaryRef.current(text); + }); + socketRef.current = socket; }, []); diff --git a/src/pages/RecordingPage.tsx b/src/pages/RecordingPage.tsx index 774075c..f941635 100644 --- a/src/pages/RecordingPage.tsx +++ b/src/pages/RecordingPage.tsx @@ -32,6 +32,7 @@ function formatElapsed(ms: number): string { export default function RecordingPage() { const [entries, setEntries] = useState([]); + const [summaries, setSummaries] = useState([]); const [isRecording, setIsRecording] = useState(false); const [isPaused, setIsPaused] = useState(false); @@ -60,6 +61,9 @@ export default function RecordingPage() { }, ]); }, + (text) => { + setSummaries((prev) => [...prev, text]); + }, ); const handleStart = useCallback(async () => { @@ -127,7 +131,7 @@ export default function RecordingPage() {
- +