- CLAUDE.md: 프로젝트 규칙, 기술 스택, 코딩 규칙, 페이즈 로드맵 - .claude/settings.json: 권한, 강제 훅 (매 프롬프트 설계서 규칙 주입) - .claude/skills/: implement-phase, review-phase, scaffold, test-commit, debug - .claude/agents/: electron-architect, voice-pipeline-expert, ui-specialist - docs/design/00-09: 마스터 아키텍처, 서비스 명세(16개), IPC(113채널), DB스키마, UI컴포넌트, 검증리포트, 외부엔진연동, 갭분석, VoiceMode패턴, 디자인시스템, 히스토리팝업 - docs/phases/1-7+3.5: 전체 구현 페이즈 문서 - docs/re-findings/: Speakly RE 노하우 5개 문서
55 lines
1.8 KiB
Markdown
55 lines
1.8 KiB
Markdown
# UI 구현 핵심 패턴
|
|
|
|
## 1. 메인 앱 = React + MUI, 팝업 = Vanilla JS
|
|
- 메인 윈도우만 React 번들 (781KB)
|
|
- 팝업들은 개별 HTML + 순수 JS (빠른 로딩)
|
|
- 각 팝업: recording-tip, result-popup, info-tip, mic-tip, mode-tip, ask-window
|
|
|
|
## 2. MUI 테마 설정
|
|
```javascript
|
|
createTheme({
|
|
palette: {
|
|
mode: 'light' | 'dark',
|
|
primary: { main: 'rgb(31, 93, 242)' },
|
|
background: { default: '#F9F9F9'/'#121212', paper: '#FFFFFF'/'#1E1E1E' }
|
|
},
|
|
typography: { fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI"' },
|
|
shape: { borderRadius: 12 },
|
|
components: { MuiButton: { root: { textTransform: 'none', fontWeight: 500 } } }
|
|
})
|
|
```
|
|
|
|
## 3. RecordingTip 웨이브 바
|
|
- 9개 바, 코사인 분포: `cos(n * PI / 2)` 가중치
|
|
- 100ms 간격 setInterval
|
|
- 오디오 레벨 → targetAmplitude, smoothing: `v += (S - v) * 0.5`
|
|
- 최소 2px, 최대 28px + 랜덤 변동 ±35%
|
|
|
|
## 4. Thinking 프로그레스 바
|
|
- 시간 기반: `min(95, (1 - 1/(1 + 1.5*t)) * 100)%` — 95%에 점근 수렴
|
|
- requestAnimationFrame 루프
|
|
|
|
## 5. 2-Phase 윈도우 리사이즈 (깜빡임 방지)
|
|
```
|
|
prepare(state, params) → 숨겨진 span으로 폭 측정 → measured(width) IPC
|
|
→ 메인 프로세스에서 윈도우 리사이즈
|
|
→ show(state) → CSS 클래스 적용 → 보이기
|
|
```
|
|
|
|
## 6. 앱 구조 (React 컴포넌트 트리)
|
|
```
|
|
App
|
|
├── ThemeProvider (light/dark/auto, localStorage)
|
|
├── Drawer (240px, permanent)
|
|
│ ├── NavItems [Dashboard, Dictionary, CustomCommand]
|
|
│ └── BottomBar [Account, Settings]
|
|
└── Content Area
|
|
├── Dashboard (통계 + 최근 세션)
|
|
├── History (검색 + 재시도)
|
|
├── Dictionary
|
|
└── Settings (Modal)
|
|
```
|
|
|
|
## 7. 라우팅
|
|
- React Router 미사용, 순수 useState 기반
|
|
- `currentRoute` state → switch 문으로 렌더링
|