135 lines
3.7 KiB
JavaScript
135 lines
3.7 KiB
JavaScript
/**
|
|
* Chat Panel — 채팅 표시/입력 UI 관리
|
|
*/
|
|
|
|
class ChatPanel {
|
|
constructor() {
|
|
this.containerEl = document.getElementById('chatContainer');
|
|
this.emptyEl = document.getElementById('emptyState');
|
|
this.messagesEl = document.getElementById('chatMessages');
|
|
this.inputEl = document.getElementById('chatInput');
|
|
this.sendBtn = document.getElementById('sendBtn');
|
|
this.sessionNameEl = document.getElementById('chatSessionName');
|
|
this.sessionStatusEl = document.getElementById('chatSessionStatus');
|
|
|
|
this.onSendMessage = null; // callback(text)
|
|
this.activeSession = null;
|
|
|
|
this._setupInput();
|
|
}
|
|
|
|
/**
|
|
* 입력 이벤트 바인딩
|
|
*/
|
|
_setupInput() {
|
|
// 자동 높이 조절
|
|
this.inputEl.addEventListener('input', () => {
|
|
this.inputEl.style.height = 'auto';
|
|
this.inputEl.style.height = Math.min(this.inputEl.scrollHeight, 120) + 'px';
|
|
});
|
|
|
|
// Enter로 전송 (Shift+Enter는 줄바꿈)
|
|
this.inputEl.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
e.preventDefault();
|
|
this._sendMessage();
|
|
}
|
|
});
|
|
|
|
this.sendBtn.addEventListener('click', () => {
|
|
this._sendMessage();
|
|
});
|
|
}
|
|
|
|
_sendMessage() {
|
|
const text = this.inputEl.value.trim();
|
|
if (!text) return;
|
|
|
|
if (this.onSendMessage) {
|
|
this.onSendMessage(text);
|
|
}
|
|
|
|
// 입력창 초기화
|
|
this.inputEl.value = '';
|
|
this.inputEl.style.height = 'auto';
|
|
}
|
|
|
|
/**
|
|
* 세션 선택 시 UI 표시
|
|
*/
|
|
showSession(session) {
|
|
this.activeSession = session;
|
|
this.emptyEl.style.display = 'none';
|
|
this.containerEl.style.display = 'flex';
|
|
|
|
this.sessionNameEl.textContent = session.name;
|
|
this.sessionStatusEl.textContent = session.status === 'connected' ? '● 연결됨' : session.status;
|
|
|
|
this.messagesEl.innerHTML = `
|
|
<div class="chat-welcome">
|
|
<p>채팅 데이터를 불러오는 중...</p>
|
|
</div>
|
|
`;
|
|
|
|
this.inputEl.focus();
|
|
}
|
|
|
|
/**
|
|
* 빈 상태 표시
|
|
*/
|
|
showEmpty() {
|
|
this.activeSession = null;
|
|
this.emptyEl.style.display = 'flex';
|
|
this.containerEl.style.display = 'none';
|
|
}
|
|
|
|
/**
|
|
* 채팅 내용 업데이트 (Antigravity DOM HTML)
|
|
*/
|
|
updateChat(html) {
|
|
if (!html || html.includes('chat container not found')) {
|
|
this.messagesEl.innerHTML = `
|
|
<div class="chat-welcome">
|
|
<p>⚠️ 채팅 컨테이너를 찾을 수 없습니다.<br>
|
|
Antigravity에서 채팅을 시작해주세요.</p>
|
|
</div>
|
|
`;
|
|
return;
|
|
}
|
|
|
|
// HTML 삽입 (Antigravity에서 가져온 DOM)
|
|
const wasAtBottom = this._isScrolledToBottom();
|
|
|
|
this.messagesEl.innerHTML = `<div class="ag-content">${html}</div>`;
|
|
|
|
// 스크롤 유지
|
|
if (wasAtBottom) {
|
|
this._scrollToBottom();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 세션 상태 업데이트
|
|
*/
|
|
updateSessionStatus(status) {
|
|
if (!this.activeSession) return;
|
|
|
|
const statusText = {
|
|
connected: '● 연결됨',
|
|
disconnected: '○ 연결 끊김',
|
|
error: '⚠ 오류',
|
|
};
|
|
|
|
this.sessionStatusEl.textContent = statusText[status] || status;
|
|
}
|
|
|
|
_isScrolledToBottom() {
|
|
const el = this.messagesEl;
|
|
return el.scrollTop + el.clientHeight >= el.scrollHeight - 50;
|
|
}
|
|
|
|
_scrollToBottom() {
|
|
this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
}
|
|
}
|