QodeAssist/chat/ChatWidget.cpp
2024-09-24 09:28:53 +02:00

148 lines
4.1 KiB
C++

/*
* Copyright (C) 2024 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ChatWidget.h"
#include "QodeAssistUtils.hpp"
#include <QCoreApplication>
#include <QDateTime>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QtCore/qtimer.h>
namespace QodeAssist::Chat {
ChatWidget::ChatWidget(QWidget *parent)
: QWidget(parent)
, m_showTimestamp(false)
, m_chatClient(new ChatClientInterface(this))
{
setupUi();
connect(m_sendButton, &QPushButton::clicked, this, &ChatWidget::sendMessage);
connect(m_messageInput, &QLineEdit::returnPressed, this, &ChatWidget::sendMessage);
connect(m_chatClient, &ChatClientInterface::messageReceived, this, &ChatWidget::receiveMessage);
connect(m_chatClient, &ChatClientInterface::errorOccurred, this, &ChatWidget::handleError);
logMessage("ChatWidget initialized");
}
void ChatWidget::setupUi()
{
m_chatDisplay = new QTextEdit(this);
m_chatDisplay->setReadOnly(true);
m_messageInput = new QLineEdit(this);
m_sendButton = new QPushButton("Send", this);
QHBoxLayout *inputLayout = new QHBoxLayout;
inputLayout->addWidget(m_messageInput);
inputLayout->addWidget(m_sendButton);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(m_chatDisplay);
mainLayout->addLayout(inputLayout);
setLayout(mainLayout);
}
void ChatWidget::sendMessage()
{
QString message = m_messageInput->text().trimmed();
if (!message.isEmpty()) {
logMessage("Sending message: " + message);
addMessage(message, true);
m_chatClient->sendMessage(message);
m_messageInput->clear();
addMessage("AI is typing...", false);
}
}
void ChatWidget::receiveMessage(const QString &message)
{
updateLastAIMessage(message);
}
void ChatWidget::receivePartialMessage(const QString &partialMessage)
{
logMessage("Received partial message: " + partialMessage);
m_currentAIResponse += partialMessage;
updateLastAIMessage(m_currentAIResponse);
}
void ChatWidget::onMessageCompleted()
{
updateLastAIMessage(m_currentAIResponse);
m_currentAIResponse.clear();
scrollToBottom();
}
void ChatWidget::handleError(const QString &error)
{
logMessage("Error occurred: " + error);
addMessage("Error: " + error, false);
}
void ChatWidget::addMessage(const QString &message, bool fromUser)
{
auto prefix = fromUser ? "You: " : "AI: ";
QString timestamp = m_showTimestamp ? QDateTime::currentDateTime().toString("[hh:mm:ss] ") : "";
QString fullMessage = timestamp + prefix + message;
m_chatDisplay->append(fullMessage);
scrollToBottom();
}
void ChatWidget::updateLastAIMessage(const QString &message)
{
QTextCursor cursor = m_chatDisplay->textCursor();
cursor.movePosition(QTextCursor::End);
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
QString timestamp = m_showTimestamp ? QDateTime::currentDateTime().toString("[hh:mm:ss] ") : "";
cursor.insertText(timestamp + "AI: " + message);
cursor.movePosition(QTextCursor::End);
m_chatDisplay->setTextCursor(cursor);
scrollToBottom();
m_chatDisplay->repaint();
}
void ChatWidget::clear()
{
m_chatDisplay->clear();
m_currentAIResponse.clear();
m_chatClient->clearMessages();
}
void ChatWidget::scrollToBottom()
{
QScrollBar *scrollBar = m_chatDisplay->verticalScrollBar();
scrollBar->setValue(scrollBar->maximum());
}
void ChatWidget::setShowTimestamp(bool show)
{
m_showTimestamp = show;
}
} // namespace QodeAssist::Chat