Phase 3 구현: 텍스트 삽입 + RecordingTip/ResultPopup + Settings
- TextInsertService: clipboard save→set→Ctrl+V→restore (@nut-tree-fork/nut-js) - RecordingTip 팝업: 9개 웨이브바 cos분포, thinking 점근수렴, 2-phase 리사이즈 - ResultPopup 팝업: 복사 버튼, auto-close, 마우스 호버 유지, 다크모드 - WindowManager: 팝업 프리로딩, 커서 위치 표시, 멀티모니터 보정 - Settings 모달: General/Audio/STT/LLM 탭 - VoiceModeService: 전사 완료 시 자동 텍스트 삽입 + 팝업 연동 - electron-vite: 팝업 HTML 멀티 엔트리 + popup preload 빌드
This commit is contained in:
parent
1d152d01a1
commit
517210af2f
16 changed files with 1366 additions and 10 deletions
95
src/renderer/popups/result-popup/script.js
Normal file
95
src/renderer/popups/result-popup/script.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// ResultPopup 팝업 스크립트
|
||||
// 설계서 03: 2-phase 리사이즈, auto-close, 마우스 호버 시 유지
|
||||
|
||||
;(function () {
|
||||
'use strict'
|
||||
|
||||
var container = document.getElementById('container')
|
||||
var resultText = document.getElementById('result-text')
|
||||
var copyBtn = document.getElementById('copy-btn')
|
||||
var copyIcon = document.getElementById('copy-icon')
|
||||
var checkIcon = document.getElementById('check-icon')
|
||||
|
||||
var autoCloseTimer = null
|
||||
var remainingTime = 0
|
||||
var lastTick = 0
|
||||
|
||||
// ── Auto-close 제어 ─────────────────────────────────
|
||||
function startAutoCloseTimer(ms) {
|
||||
remainingTime = ms
|
||||
lastTick = Date.now()
|
||||
clearInterval(autoCloseTimer)
|
||||
autoCloseTimer = setInterval(function () {
|
||||
remainingTime -= (Date.now() - lastTick)
|
||||
lastTick = Date.now()
|
||||
if (remainingTime <= 0) {
|
||||
clearInterval(autoCloseTimer)
|
||||
autoCloseTimer = null
|
||||
window.popupAPI.send('window:hideResultPopup')
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
function pauseAutoClose() {
|
||||
clearInterval(autoCloseTimer)
|
||||
autoCloseTimer = null
|
||||
}
|
||||
|
||||
function resumeAutoClose() {
|
||||
startAutoCloseTimer(remainingTime > 0 ? remainingTime : 2000)
|
||||
}
|
||||
|
||||
// ── 복사 버튼 ───────────────────────────────────────
|
||||
copyBtn.addEventListener('click', function () {
|
||||
// navigator.clipboard는 팝업에서 작동 안 할 수 있으므로 IPC 사용
|
||||
window.popupAPI.send('clipboard:copy', resultText.textContent)
|
||||
|
||||
copyBtn.classList.add('copied')
|
||||
copyIcon.classList.add('hidden')
|
||||
checkIcon.classList.remove('hidden')
|
||||
|
||||
setTimeout(function () {
|
||||
copyBtn.classList.remove('copied')
|
||||
copyIcon.classList.remove('hidden')
|
||||
checkIcon.classList.add('hidden')
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
// ── 마우스 호버 시 auto-close 일시정지 ──────────────
|
||||
container.addEventListener('mouseenter', pauseAutoClose)
|
||||
container.addEventListener('mouseleave', resumeAutoClose)
|
||||
|
||||
// ── IPC 리스너 ───────────────────────────────────────
|
||||
|
||||
// Phase 1: prepare — 결과 텍스트 세팅 + 크기 측정
|
||||
window.popupAPI.on('result:prepare', function (data) {
|
||||
resultText.textContent = data.text || ''
|
||||
container.classList.remove('visible')
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
requestAnimationFrame(function () {
|
||||
var rect = container.getBoundingClientRect()
|
||||
window.popupAPI.send('result:measured', {
|
||||
width: Math.ceil(rect.width) + 4,
|
||||
height: Math.ceil(rect.height) + 4
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Phase 2: show — 리사이즈 완료 후 표시
|
||||
window.popupAPI.on('result:show', function (data) {
|
||||
container.classList.add('visible')
|
||||
var autoHideMs = (data && data.autoHideMs) || 5000
|
||||
if (autoHideMs > 0) {
|
||||
startAutoCloseTimer(autoHideMs)
|
||||
}
|
||||
})
|
||||
|
||||
// hide
|
||||
window.popupAPI.on('result:hide', function () {
|
||||
container.classList.remove('visible')
|
||||
clearInterval(autoCloseTimer)
|
||||
autoCloseTimer = null
|
||||
})
|
||||
})()
|
||||
Loading…
Add table
Add a link
Reference in a new issue