fix: MeetingModePage 렌더링 크래시 수정

d3roPalette.indicator → d3roPalette.tag, d3roTypo.reading → d3roTypo.body,
PhosphorText variant="reading" → "body", ScreenPanel sx prop 제거.
bootstrap.ts require() → dynamic import() 변환.
This commit is contained in:
Yun Chan 2026-04-08 08:51:24 +09:00
parent d0c4f9ee53
commit acab319589
2 changed files with 26 additions and 18 deletions

View file

@ -275,7 +275,7 @@ async function initMeetingSummaryWiring(): Promise<void> {
captionService.on('session-saved', (summary: { sessionId: string }) => { captionService.on('session-saved', (summary: { sessionId: string }) => {
// 회의 모드가 CaptionService를 사용 중이면 MeetingSummary 자동 생성 건너뛰기 // 회의 모드가 CaptionService를 사용 중이면 MeetingSummary 자동 생성 건너뛰기
const { getMeetingModeService } = require('./services/MeetingModeService') as { getMeetingModeService: () => { isMeetingModeActive: () => boolean } } import('./services/MeetingModeService').then(({ getMeetingModeService }) => {
if (getMeetingModeService().isMeetingModeActive()) { if (getMeetingModeService().isMeetingModeActive()) {
logger.info('Skipping auto meeting summary: meeting mode active') logger.info('Skipping auto meeting summary: meeting mode active')
return return
@ -283,6 +283,12 @@ async function initMeetingSummaryWiring(): Promise<void> {
summaryService.onCaptionSessionSaved(summary).catch((err) => { summaryService.onCaptionSessionSaved(summary).catch((err) => {
logger.warn('Auto meeting summary failed:', err) logger.warn('Auto meeting summary failed:', err)
}) })
}).catch(() => {
// MeetingModeService 로드 실패 시 기본 동작 수행
summaryService.onCaptionSessionSaved(summary).catch((err) => {
logger.warn('Auto meeting summary failed:', err)
})
})
}) })
} catch (err) { } catch (err) {
logger.warn('Meeting summary wiring failed:', err) logger.warn('Meeting summary wiring failed:', err)

View file

@ -304,7 +304,7 @@ export function MeetingModePage(): React.ReactElement {
{/* 상단 바 */} {/* 상단 바 */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<FiberManualRecordIcon sx={{ color: d3roPalette.indicator.red, fontSize: 16, animation: 'pulse 1s infinite' }} /> <FiberManualRecordIcon sx={{ color: d3roPalette.tag.red, fontSize: 16, animation: 'pulse 1s infinite' }} />
<PhosphorText variant="label" sx={{ fontFamily: d3roFontMono }}> <PhosphorText variant="label" sx={{ fontFamily: d3roFontMono }}>
{formatTime(elapsedMs)} {formatTime(elapsedMs)}
</PhosphorText> </PhosphorText>
@ -333,7 +333,8 @@ export function MeetingModePage(): React.ReactElement {
{/* 메인 패널: 전사 + 메모 */} {/* 메인 패널: 전사 + 메모 */}
<Box sx={{ flex: 1, display: 'flex', gap: 2, minHeight: 0 }}> <Box sx={{ flex: 1, display: 'flex', gap: 2, minHeight: 0 }}>
{/* 좌: 실시간 전사 */} {/* 좌: 실시간 전사 */}
<ScreenPanel sx={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}> <Box sx={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
<ScreenPanel>
<PhosphorText variant="dim" sx={{ mb: 1, fontSize: 11 }}> <PhosphorText variant="dim" sx={{ mb: 1, fontSize: 11 }}>
{t('meeting.transcript')} {t('meeting.transcript')}
</PhosphorText> </PhosphorText>
@ -343,7 +344,7 @@ export function MeetingModePage(): React.ReactElement {
flex: 1, flex: 1,
overflow: 'auto', overflow: 'auto',
fontFamily: d3roFontMono, fontFamily: d3roFontMono,
fontSize: d3roTypo.reading.fontSize, fontSize: d3roTypo.body.size,
color: d3roPalette.text.primary, color: d3roPalette.text.primary,
lineHeight: 1.8, lineHeight: 1.8,
}} }}
@ -363,6 +364,7 @@ export function MeetingModePage(): React.ReactElement {
))} ))}
</Box> </Box>
</ScreenPanel> </ScreenPanel>
</Box>
{/* 우: 메모 입력 */} {/* 우: 메모 입력 */}
<Box sx={{ width: 300, display: 'flex', flexDirection: 'column' }}> <Box sx={{ width: 300, display: 'flex', flexDirection: 'column' }}>
@ -383,7 +385,7 @@ export function MeetingModePage(): React.ReactElement {
<PhosphorText variant="dim" sx={{ fontSize: 10, fontFamily: d3roFontMono }}> <PhosphorText variant="dim" sx={{ fontSize: 10, fontFamily: d3roFontMono }}>
{formatTime(memo.timestampMs)} {formatTime(memo.timestampMs)}
</PhosphorText> </PhosphorText>
<PhosphorText variant="reading" sx={{ fontSize: 12 }}> <PhosphorText variant="body" sx={{ fontSize: 12 }}>
{memo.content} {memo.content}
</PhosphorText> </PhosphorText>
</Box> </Box>
@ -467,7 +469,7 @@ export function MeetingModePage(): React.ReactElement {
{/* 요약 */} {/* 요약 */}
<MetalCard sx={{ mb: 2 }}> <MetalCard sx={{ mb: 2 }}>
<PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.summary')}</PhosphorText> <PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.summary')}</PhosphorText>
<PhosphorText variant="reading" sx={{ whiteSpace: 'pre-wrap' }}> <PhosphorText variant="body" sx={{ whiteSpace: 'pre-wrap' }}>
{detail.minutes.summary} {detail.minutes.summary}
</PhosphorText> </PhosphorText>
</MetalCard> </MetalCard>
@ -477,7 +479,7 @@ export function MeetingModePage(): React.ReactElement {
<MetalCard sx={{ mb: 2 }}> <MetalCard sx={{ mb: 2 }}>
<PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.decisions')}</PhosphorText> <PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.decisions')}</PhosphorText>
{detail.minutes.decisions.map((d, i) => ( {detail.minutes.decisions.map((d, i) => (
<PhosphorText key={i} variant="reading" sx={{ mb: 0.5 }}> <PhosphorText key={i} variant="body" sx={{ mb: 0.5 }}>
{'• '}{d} {'• '}{d}
</PhosphorText> </PhosphorText>
))} ))}
@ -489,7 +491,7 @@ export function MeetingModePage(): React.ReactElement {
<MetalCard sx={{ mb: 2 }}> <MetalCard sx={{ mb: 2 }}>
<PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.actionItems')}</PhosphorText> <PhosphorText variant="label" sx={{ mb: 1 }}>{t('meeting.actionItems')}</PhosphorText>
{detail.minutes.actionItems.map((item, i) => ( {detail.minutes.actionItems.map((item, i) => (
<PhosphorText key={i} variant="reading" sx={{ mb: 0.5 }}> <PhosphorText key={i} variant="body" sx={{ mb: 0.5 }}>
{'☐ '}{item.assignee ? `${item.assignee}: ` : ''}{item.task} {'☐ '}{item.assignee ? `${item.assignee}: ` : ''}{item.task}
{item.deadline ? ` (${item.deadline})` : ''} {item.deadline ? ` (${item.deadline})` : ''}
</PhosphorText> </PhosphorText>
@ -506,7 +508,7 @@ export function MeetingModePage(): React.ReactElement {
<PhosphorText variant="dim" sx={{ fontFamily: d3roFontMono, minWidth: 50 }}> <PhosphorText variant="dim" sx={{ fontFamily: d3roFontMono, minWidth: 50 }}>
{tl.time} {tl.time}
</PhosphorText> </PhosphorText>
<PhosphorText variant="reading" sx={{ flex: 1 }}> <PhosphorText variant="body" sx={{ flex: 1 }}>
{tl.type === 'memo' ? '📝 ' : ''}{tl.content} {tl.type === 'memo' ? '📝 ' : ''}{tl.content}
</PhosphorText> </PhosphorText>
</Box> </Box>
@ -519,10 +521,10 @@ export function MeetingModePage(): React.ReactElement {
{/* 에러 메시지 */} {/* 에러 메시지 */}
{detail.status === 'error' && detail.errorMessage && ( {detail.status === 'error' && detail.errorMessage && (
<MetalCard sx={{ mb: 2 }}> <MetalCard sx={{ mb: 2 }}>
<PhosphorText variant="label" sx={{ color: d3roPalette.indicator.red, mb: 1 }}> <PhosphorText variant="label" sx={{ color: d3roPalette.tag.red, mb: 1 }}>
{t('meeting.error')} {t('meeting.error')}
</PhosphorText> </PhosphorText>
<PhosphorText variant="reading">{detail.errorMessage}</PhosphorText> <PhosphorText variant="body">{detail.errorMessage}</PhosphorText>
</MetalCard> </MetalCard>
)} )}
@ -535,7 +537,7 @@ export function MeetingModePage(): React.ReactElement {
<PhosphorText variant="dim" sx={{ fontFamily: d3roFontMono, minWidth: 50 }}> <PhosphorText variant="dim" sx={{ fontFamily: d3roFontMono, minWidth: 50 }}>
{formatTime(m.timestampMs)} {formatTime(m.timestampMs)}
</PhosphorText> </PhosphorText>
<PhosphorText variant="reading">{m.content}</PhosphorText> <PhosphorText variant="body">{m.content}</PhosphorText>
</Box> </Box>
))} ))}
</MetalCard> </MetalCard>