SearchTrademark/rest-modal.js

302 lines
11 KiB
JavaScript

class RestModal {
constructor() {
this.restTime = 5; // 기본 5분
this.currentTime = this.restTime * 60; // 초 단위
this.timer = null;
this.config = null;
this.currentSaying = null;
this.autoZzim = false;
// 기본 추천 활동 목록 (백엔드 연결 실패 시 사용)
this.defaultActivities = [
"🚶‍♀️ 가벼운 산책을 해보세요",
"💧 물 한 잔을 마시며 수분을 보충하세요",
"🧘‍♀️ 심호흡을 하며 명상을 해보세요",
"🤸‍♀️ 간단한 스트레칭으로 몸을 풀어보세요",
"👀 눈 운동을 하며 눈의 피로를 풀어보세요",
"🚽 화장실을 다녀오세요",
"🌱 창밖을 보며 자연을 감상해보세요",
"📱 잠시 휴대폰을 내려놓고 마음을 비워보세요",
"☕ 따뜻한 차 한 잔을 마셔보세요",
"🎵 좋아하는 음악을 들으며 휴식하세요",
"📚 짧은 글이나 명언을 읽어보세요",
"🤝 동료나 가족과 간단한 대화를 나누세요",
"🧴 손 마사지나 목 마사지를 해보세요",
"🏃‍♀️ 제자리에서 가볍게 몸을 움직여보세요",
"🍎 건강한 간식을 드세요"
];
this.activities = []; // 백엔드에서 가져온 활동 목록
}
async init() {
try {
await this.loadSettings();
await this.loadConfig();
this.setupEventListeners();
await this.loadRestActivities();
this.showRandomActivity();
await this.loadRandomSaying();
this.startTimer();
// 자동 품앗이 체크 및 실행
this.checkAutoZzim();
} catch (error) {
console.error('[RestModal] 초기화 실패:', error);
}
}
async checkAutoZzim() {
if (this.autoZzim) {
console.log('[RestModal] 휴식 중 자동 품앗이 시작 (Fast Mode: 10ms)');
// 백그라운드에 메시지 전송 (100ms 딜레이로 고속 실행)
try {
chrome.runtime.sendMessage({
action: 'autoMutualZzim',
delay: 100
});
} catch (e) {
console.error('[RestModal] 자동 품앗이 요청 실패:', e);
}
}
}
async loadSettings() {
try {
const result = await chrome.storage.local.get('time_alarm_settings');
const settings = result.time_alarm_settings || {};
this.restTime = settings.restTime || 5;
this.autoZzim = settings.autoZzim || false;
this.currentTime = this.restTime * 60;
console.log('[RestModal] 설정 로드:', { restTime: this.restTime, autoZzim: this.autoZzim });
} catch (error) {
console.error('[RestModal] 설정 로드 실패:', error);
}
}
async loadConfig() {
try {
const result = await chrome.storage.local.get('settings_config');
this.config = result.settings_config || {};
console.log('[RestModal] 설정 정보 로드:', this.config);
} catch (error) {
console.error('[RestModal] 설정 정보 로드 실패:', error);
}
}
setupEventListeners() {
// 닫기 버튼
document.getElementById('closeBtn').addEventListener('click', () => {
this.closeModal();
});
// 건너뛰기 버튼
document.getElementById('skipBtn').addEventListener('click', () => {
this.closeModal();
});
// ESC 키로 닫기
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.closeModal();
}
});
}
async loadRestActivities() {
try {
if (!this.config.ACCESS_TOKEN) {
throw new Error('Access token not found');
}
console.log('[RestModal] 추천활동 API 호출 (background.js 경유)');
// background.js를 통해 API 호출
const response = await chrome.runtime.sendMessage({
action: 'getRestActivities',
token: this.config.ACCESS_TOKEN
});
if (!response || !response.success) {
throw new Error(response?.error || 'API 호출 실패');
}
const events = response.activities;
if (events && events.length > 0) {
// message 필드에서 JSON 파싱하여 활동 목록 생성
this.activities = [];
events.forEach(event => {
try {
// message 필드가 JSON 형식인 경우 파싱
const messageData = JSON.parse(event.message);
// 활동 텍스트 추출 (다양한 형식 지원)
if (messageData.activity) {
this.activities.push(messageData.activity);
} else if (messageData.text) {
this.activities.push(messageData.text);
} else if (typeof messageData === 'string') {
this.activities.push(messageData);
}
} catch (parseError) {
// JSON 파싱 실패 시 문자열 그대로 사용
if (typeof event.message === 'string' && event.message.trim()) {
this.activities.push(event.message);
}
}
});
console.log('[RestModal] 백엔드에서 추천활동 로드 완료:', this.activities.length + '개');
} else {
throw new Error('추천활동 데이터가 없습니다');
}
} catch (error) {
console.error('[RestModal] 추천활동 로드 실패:', error);
// 기본 활동 목록 사용
this.activities = [...this.defaultActivities];
console.log('[RestModal] 기본 추천활동 사용:', this.activities.length + '개');
}
}
showRandomActivity() {
if (this.activities.length === 0) {
this.activities = [...this.defaultActivities];
}
const randomActivity = this.activities[Math.floor(Math.random() * this.activities.length)];
document.getElementById('activitySuggestion').innerHTML = randomActivity;
}
async loadRandomSaying() {
try {
if (!this.config.ACCESS_TOKEN) {
throw new Error('Access token not found');
}
console.log('[RestModal] 어록 API 호출 (background.js 경유)');
// background.js를 통해 API 호출
const response = await chrome.runtime.sendMessage({
action: 'getRandomSaying',
token: this.config.ACCESS_TOKEN
});
if (!response || !response.success) {
throw new Error(response?.error || 'API 호출 실패');
}
const sayings = response.sayings;
if (sayings && sayings.length > 0) {
// 랜덤하게 하나 선택
const randomSaying = sayings[Math.floor(Math.random() * sayings.length)];
this.currentSaying = randomSaying;
// 어록 표시
const sayingContent = document.getElementById('sayingContent');
const sayingAuthor = document.getElementById('sayingAuthor');
sayingContent.innerHTML = `"${randomSaying.saying}"`;
// 카테고리와 대상 정보 표시
const category = randomSaying.sayings_cat?.saying_cat || '';
const target = randomSaying.sayings_target?.target || '';
const dateStr = new Date(randomSaying.created_at).toLocaleDateString('ko-KR');
sayingAuthor.innerHTML = `${category} ${target ? `${target}` : ''}${dateStr}`;
console.log('[RestModal] 어록 로드 완료:', randomSaying);
} else {
throw new Error('어록이 없습니다');
}
} catch (error) {
console.error('[RestModal] 어록 로드 실패:', error);
// 기본 메시지 표시
document.getElementById('sayingContent').innerHTML = '"열심히 일한 당신, 잠시 휴식을 취하며 에너지를 충전하세요!"';
document.getElementById('sayingAuthor').innerHTML = '타냐 • 휴식 메시지';
}
}
startTimer() {
this.updateTimerDisplay();
this.updateProgressBar();
this.timer = setInterval(() => {
this.currentTime--;
this.updateTimerDisplay();
this.updateProgressBar();
if (this.currentTime <= 0) {
this.onTimerComplete();
}
}, 1000);
}
updateTimerDisplay() {
const minutes = Math.floor(this.currentTime / 60);
const seconds = this.currentTime % 60;
const display = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
document.getElementById('timerDisplay').textContent = display;
}
updateProgressBar() {
const totalTime = this.restTime * 60;
const elapsed = totalTime - this.currentTime;
const percentage = (elapsed / totalTime) * 100;
document.getElementById('progressFill').style.width = `${percentage}%`;
}
async onTimerComplete() {
clearInterval(this.timer);
// 완료 메시지 표시
this.showCompletionMessage();
// 3초 후 자동 닫기
setTimeout(() => {
this.closeModal();
}, 3000);
}
showCompletionMessage() {
const modalContainer = document.querySelector('.modal-container');
modalContainer.innerHTML = `
<div class="rest-icon">🚀</div>
<h1 class="rest-title">휴식 완료!</h1>
<p class="rest-subtitle">이제 다시 열심히 월매출 1억을 향해 달려가세요!</p>
<div style="font-size: 1.2rem; color: #667eea; margin-top: 20px;">
💪 화이팅! 성공은 바로 앞에 있습니다!
</div>
<div class="actions" style="margin-top: 30px;">
<button class="btn btn-primary" onclick="window.close()">확인</button>
</div>
`;
}
closeModal() {
if (this.timer) {
clearInterval(this.timer);
}
// 창 닫기
window.close();
}
}
// 페이지 로드 시 휴식 모달 초기화
document.addEventListener('DOMContentLoaded', () => {
const restModal = new RestModal();
restModal.init();
});