-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebengineviewcustom.cpp
More file actions
143 lines (112 loc) · 4.77 KB
/
Copy pathwebengineviewcustom.cpp
File metadata and controls
143 lines (112 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QWebChannel>
#include <QFile>
#include <QGraphicsBlurEffect>
#include <QVBoxLayout>
#include <QRegularExpression>
#include "webengineviewcustom.h"
#include "chatbotwithapi.h"
#include "chatbotwithmodel.h"
// Constructor implementation
WebEngineViewCustom::WebEngineViewCustom(QWidget *parent)
: QWebEngineView(parent), channel(new QWebChannel(this)) {
}
void WebEngineViewCustom::isAssistantReady(bool ready){
if(ready){
initChatBot();
setEnabled(true);
}
else{
setEnabled(false);
}
}
// Initialize the chat screen with HTML content
void WebEngineViewCustom::initChatScreen() {
QFile file(":/resources/html/chatscreen.html"); // Use the resource path
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning("Couldn't open HTML file.");
return;
}
QTextStream in(&file);
QString htmlContent = in.readAll();
file.close();
this->setHtml(htmlContent); // Load the HTML content from the file
}
void WebEngineViewCustom::initChatBot() {
// Initialize the chatbot based on the configuration
if (vizData->chatbotData.isWithAPI) {
chatbot = new ChatbotWithAPI(vizData, this);
} else {
chatbot = new ChatbotWithModel(vizData, this);
}
// Set up the WebChannel
channel = new QWebChannel(this);
// Connect chatbot signals to UI slots
connect(chatbot, &ChatbotInterface::chatbotSendUserMessage,
this, &WebEngineViewCustom::appendUserMessage);
connect(chatbot, &ChatbotInterface::chatbotResponseReceived,
this, &WebEngineViewCustom::appendAssistantMessage);
// Register the chatbot object with the channel
channel->registerObject("chatbot", chatbot);
// Initialize the chat screen (loads the HTML)
initChatScreen();
// Assign the channel to the page
this->page()->setWebChannel(channel);
// Connect to the loadFinished signal to run JavaScript after the page loads
connect(this, &QWebEngineView::loadFinished, this, &WebEngineViewCustom::onLoadFinished);
}
// Slot to handle the loadFinished signal
void WebEngineViewCustom::onLoadFinished(bool ok) {
if (ok) {
// Execute the JavaScript function after successful load
this->page()->runJavaScript("hideDefaultMessage();", [this](const QVariant &v) {
Q_UNUSED(v);
});
// chatbot->sendFile(vizData->prefData->getConfigFilePath());
// chatbot->sendMessage("These are available data of the simulation ("+QString(vizData->statsData.keys().join(","))+"), you always have to remember this");
appendAssistantMessage("Hi, I'm your assistant, you can ask me anything...");
} else {
qWarning() << "Failed to load chat screen HTML.";
}
// Optional: Disconnect the signal if you only want to handle it once
disconnect(this, &QWebEngineView::loadFinished, this, &WebEngineViewCustom::onLoadFinished);
}
void WebEngineViewCustom::setVizData(VizData *vizData) {
this->vizData = vizData;
}
void WebEngineViewCustom::appendUserMessage(const QString &message) {
// Append a user message (right-aligned with a blue bubble)
appendMessage(message, "user-message");
}
void WebEngineViewCustom::appendAssistantMessage(const QString &message) {
// Append an assistant message (left-aligned with a gray bubble)
appendMessage(message, "assistant-message");
this->page()->runJavaScript("onMessageReceived();");
}
void WebEngineViewCustom::appendMessage(const QString &message, const QString &senderClass) {
QString sanitizedMessage = message;
// Replace special characters for safe JavaScript string embedding
sanitizedMessage.replace("\\", "\\\\"); // Escape backslashes
sanitizedMessage.replace("'", "\\'"); // Escape single quotes
sanitizedMessage.replace("\"", "\\\""); // Escape double quotes
sanitizedMessage.replace("\n", "\\n"); // Escape newlines
// JavaScript script with marked.js and DOMPurify integration
QString script = QString(R"(
var container = document.getElementById('message-container');
var messageElement = document.createElement('div');
messageElement.className = '%1'; // Apply the correct CSS class for styling
// Use marked.js to convert Markdown to HTML and DOMPurify to sanitize it
var rawMessage = '%2';
var htmlMessage = DOMPurify.sanitize(marked(rawMessage));
messageElement.innerHTML = htmlMessage;
container.appendChild(messageElement);
window.scrollTo(0, document.body.scrollHeight);
)").arg(senderClass).arg(sanitizedMessage);
// Run the JavaScript to append the message in the HTML
this->page()->runJavaScript(script);
}