- 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 빌드
95 lines
3.1 KiB
JavaScript
95 lines
3.1 KiB
JavaScript
// 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
|
|
})
|
|
})()
|