/*
* Управляет пользовательским интерфейсом чата, включая ввод сообщений,
* отображение истории и подсказки команд для взаимодействия с пользователем.
*/
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 = '';
}
}