/* * Управляет пользовательским интерфейсом чата, включая ввод сообщений, * отображение истории и подсказки команд для взаимодействия с пользователем. */ import { ChatHistoryItem } from './models/ChatHistoryItem'; export class ChatPanel { container: HTMLElement; props: { chatHistory: ChatHistoryItem[]; onSendMessage: (message: string) => void; }; chatHistory: ChatHistoryItem[]; messageInput: HTMLInputElement; sendButton: HTMLButtonElement; suggestionsContainer: HTMLDivElement; constructor( container: HTMLElement, props: { chatHistory: ChatHistoryItem[]; onSendMessage: (message: string) => void; } ) { this.container = container; this.props = props; this.chatHistory = props.chatHistory || []; this.init(); } init(): void { this.container.innerHTML = `
`; this.messageInput = this.container.querySelector('#message-input') as HTMLInputElement; this.sendButton = this.container.querySelector('#send-button') as HTMLButtonElement; this.suggestionsContainer = this.container.querySelector('#suggestions') as HTMLDivElement; this.setupEventListeners(); this.renderHistory(); } setupEventListeners(): void { this.sendButton.addEventListener('click', () => this.handleSend()); this.messageInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { if (this.suggestionsContainer.style.display === 'block') { const firstSuggestion = this.suggestionsContainer.querySelector('.suggestion-item'); if (firstSuggestion) { this.messageInput.value = firstSuggestion.textContent || ''; this.hideSuggestions(); e.preventDefault(); return; } } this.handleSend(); e.preventDefault(); } }); this.messageInput.addEventListener('input', (e) => { this.handleInput((e.target as HTMLInputElement).value); }); } handleInput(value: string): void { const commands = ['/help', '/imagine', '/analyze', '/subtitles_meet', '/subtitles_teams', '/summarize', '/chat']; if (value.startsWith('/')) { const filteredCommands = commands.filter((cmd) => cmd.startsWith(value.toLowerCase())); this.showSuggestions(filteredCommands); } else { this.hideSuggestions(); } } showSuggestions(suggestions: string[]): void { if (suggestions.length === 0) { this.hideSuggestions(); return; } this.suggestionsContainer.innerHTML = suggestions.map((suggestion) => `
${suggestion}
`).join(''); this.suggestionsContainer.style.display = 'block'; // Добавляем обработчики кликов на предложения this.suggestionsContainer.querySelectorAll('.suggestion-item').forEach((item) => { item.addEventListener('click', () => { this.messageInput.value = item.textContent || ''; this.hideSuggestions(); this.messageInput.focus(); }); }); } hideSuggestions(): void { this.suggestionsContainer.style.display = 'none'; } handleSend(): void { const message = this.messageInput.value.trim(); if (message && this.props.onSendMessage) { this.props.onSendMessage(message); this.messageInput.value = ''; this.hideSuggestions(); } } renderHistory(): void { const historyContainer = this.container.querySelector('#chat-history') as HTMLElement; historyContainer.innerHTML = this.chatHistory .map( (msg) => `
${this.processMessageContent(msg.content)}
` ) .join(''); // Прокручиваем к концу historyContainer.scrollTop = historyContainer.scrollHeight; } processMessageContent(content: string): string { // Простейшая обработка Markdown для изображений return content.replace(/]*?)>/g, '').replace(/\n/g, '
'); } updateHistory(newHistory: ChatHistoryItem[]): void { this.chatHistory = newHistory; this.renderHistory(); } destroy(): void { this.container.innerHTML = ''; } }