From c4bb9aec12c94143e13784c92011c249950f439e Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 9 Dec 2025 11:03:32 -0800 Subject: [PATCH] Refactor chat message formatting and enhance subtitle settings --- app/custom/VideoConferenceClientImpl.tsx | 5 +++-- app/rooms/[roomName]/PageClientImpl.tsx | 12 +++--------- lib/SubtitlesOverlay.tsx | 24 +++++++++++++++++++++++- lib/SubtitlesSettings.tsx | 18 ++++++++++++------ lib/chat-utils.ts | 18 ++++++++++++++++++ 5 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 lib/chat-utils.ts diff --git a/app/custom/VideoConferenceClientImpl.tsx b/app/custom/VideoConferenceClientImpl.tsx index cd7f77a..3689cc6 100644 --- a/app/custom/VideoConferenceClientImpl.tsx +++ b/app/custom/VideoConferenceClientImpl.tsx @@ -1,6 +1,7 @@ 'use client'; -import { formatChatMessageLinks, RoomContext, VideoConference } from '@livekit/components-react'; +import { RoomContext, VideoConference } from '@livekit/components-react'; +import { formatChatMessage } from '@/lib/chat-utils'; import { ExternalE2EEKeyProvider, LogLevel, @@ -86,7 +87,7 @@ export function VideoConferenceClientImpl(props: { diff --git a/lib/SubtitlesOverlay.tsx b/lib/SubtitlesOverlay.tsx index de15eac..a74a710 100644 --- a/lib/SubtitlesOverlay.tsx +++ b/lib/SubtitlesOverlay.tsx @@ -24,6 +24,7 @@ interface SubtitleContextType { updateSettings: (settings: SubtitleSettings) => void; hasAgent: boolean; summaryEmail: string | null; + setSummaryEmail: (email: string | null) => void; } const SubtitleContext = React.createContext(null); @@ -109,8 +110,29 @@ export function SubtitleProvider({ children }: { children: React.ReactNode }) { } }, []); + const updateSummaryEmail = React.useCallback((email: string | null) => { + setSummaryEmail(email); + try { + if (email) { + localStorage.setItem('summary-email', email); + } else { + localStorage.removeItem('summary-email'); + } + } catch (e) { + console.error('Failed to save summary email:', e); + } + }, []); + return ( - + {children} ); diff --git a/lib/SubtitlesSettings.tsx b/lib/SubtitlesSettings.tsx index ce6c3e3..3eca635 100644 --- a/lib/SubtitlesSettings.tsx +++ b/lib/SubtitlesSettings.tsx @@ -102,7 +102,8 @@ function EmailPopup({ export function SubtitlesSettings() { const room = useRoomContext(); - const { settings, updateSettings, hasAgent, summaryEmail } = useSubtitleSettings(); + const { settings, updateSettings, hasAgent, summaryEmail, setSummaryEmail } = + useSubtitleSettings(); const [showPopup, setShowPopup] = React.useState(false); const [isSpawning, setIsSpawning] = React.useState(false); const [spawnError, setSpawnError] = React.useState(null); @@ -125,14 +126,17 @@ export function SubtitlesSettings() { setSpawnError(null); try { + const payload = { + roomName: room.name, + email: email || undefined, + e2eePassphrase: getPassphrase(), + }; + console.log('[SubtitlesSettings] Spawning agent with:', payload); + const response = await fetch('/api/agent/spawn', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - roomName: room.name, - email: email || undefined, - e2eePassphrase: getPassphrase(), - }), + body: JSON.stringify(payload), }); if (!response.ok) { @@ -160,6 +164,7 @@ export function SubtitlesSettings() { const handleSkip = async () => { if (await spawnAgent()) { + setSummaryEmail(null); updateSettings({ ...settings, enabled: true }); setShowPopup(false); } @@ -167,6 +172,7 @@ export function SubtitlesSettings() { const handleSubscribe = async (email: string) => { if (await spawnAgent(email)) { + setSummaryEmail(email); updateSettings({ ...settings, enabled: true }); setShowPopup(false); } diff --git a/lib/chat-utils.ts b/lib/chat-utils.ts new file mode 100644 index 0000000..d90d7cf --- /dev/null +++ b/lib/chat-utils.ts @@ -0,0 +1,18 @@ +'use client'; + +import React from 'react'; +import { formatChatMessageLinks } from '@livekit/components-react'; + +/** + * Chat message formatter with newline support. + * Wraps LiveKit's formatChatMessageLinks and adds
for line breaks. + */ +export function formatChatMessage(message: string): React.ReactNode { + return message + .split('\n') + .flatMap((line, i) => + i === 0 + ? [formatChatMessageLinks(line)] + : [React.createElement('br', { key: `br-${i}` }), formatChatMessageLinks(line)], + ); +}