remove emoji reaction feature (KDE GUI)
This commit is contained in:
parent
d473fb4e4c
commit
5bdab3c616
|
|
@ -47,7 +47,6 @@ Item {
|
|||
if (chat) {
|
||||
paneModel.rawText = chat.text
|
||||
chatOffset = chat.offset
|
||||
paneModel.setReactions(dbus.getReactions(sessionId))
|
||||
}
|
||||
let cfg = dbus.getConfig(sessionId)
|
||||
if (cfg && cfg.cwd) paneCwd = cfg.cwd
|
||||
|
|
@ -67,14 +66,12 @@ Item {
|
|||
if (offset === paneRoot.chatOffset) {
|
||||
paneModel.rawText = paneModel.rawText + text
|
||||
paneRoot.chatOffset += text.length
|
||||
paneModel.setReactions(dbus.getReactions(paneRoot.sessionId))
|
||||
} else {
|
||||
// Offset mismatch - refetch
|
||||
let chat = dbus.getChat(paneRoot.sessionId, 0)
|
||||
if (chat) {
|
||||
paneModel.rawText = chat.text
|
||||
paneRoot.chatOffset = chat.offset
|
||||
paneModel.setReactions(dbus.getReactions(paneRoot.sessionId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -687,46 +684,21 @@ Item {
|
|||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||
}
|
||||
|
||||
// Reaction badge (pinned when reacted)
|
||||
Label {
|
||||
// Copy button
|
||||
ToolButton {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 4
|
||||
z: 10
|
||||
text: block ? (block.reaction || "") : ""
|
||||
font.pixelSize: 18
|
||||
visible: block ? block.reaction !== "" : false
|
||||
}
|
||||
|
||||
// Reaction buttons (hover only, hidden when already reacted)
|
||||
Row {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: block && block.reaction !== "" ? 36 : 4
|
||||
anchors.margins: 4
|
||||
z: 10
|
||||
spacing: 2
|
||||
opacity: (assistantHover.hovered && (block ? block.reaction : "") === "") ? 0.9 : 0
|
||||
text: "\uD83D\uDCCB"
|
||||
font.pixelSize: 14
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
opacity: assistantHover.hovered ? 0.9 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||
|
||||
Repeater {
|
||||
model: [
|
||||
{ emoji: "\uD83D\uDC4D", tip: "Good" },
|
||||
{ emoji: "\uD83D\uDC4E", tip: "Bad" },
|
||||
{ emoji: "\uD83D\uDE80", tip: "Excellent" },
|
||||
{ emoji: "\uD83D\uDCA9", tip: "Very bad" },
|
||||
{ emoji: "\uD83E\uDD14", tip: "Confused" }
|
||||
]
|
||||
ToolButton {
|
||||
text: modelData.emoji
|
||||
font.pixelSize: 14
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
onClicked: { dbus.reactTo(paneRoot.sessionId, block.responseId, modelData.emoji); paneModel.setReactions(dbus.getReactions(paneRoot.sessionId)) }
|
||||
ToolTip.text: modelData.tip
|
||||
ToolTip.visible: hovered
|
||||
}
|
||||
}
|
||||
onClicked: paneModel.copyToClipboard(block.content)
|
||||
ToolTip.text: "Copy"
|
||||
ToolTip.visible: hovered
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
|
|||
|
|
@ -74,8 +74,6 @@ QVariant ChatBlockModel::data(const QModelIndex &index, int role) const
|
|||
return block.content;
|
||||
case ResponseIdRole:
|
||||
return block.responseId;
|
||||
case ReactionRole:
|
||||
return block.reaction;
|
||||
case SubBlocksRole:
|
||||
if (block.cachedContent != block.content) {
|
||||
block.cachedSubBlocks = parseSubBlocks(block.content);
|
||||
|
|
@ -115,40 +113,9 @@ QHash<int, QByteArray> ChatBlockModel::roleNames() const
|
|||
{SubBlocksRole, "subBlocks"},
|
||||
{FormattedContentRole, "formattedContent"},
|
||||
{ResponseIdRole, "responseId"},
|
||||
{ReactionRole, "reaction"},
|
||||
};
|
||||
}
|
||||
|
||||
void ChatBlockModel::setReactions(const QVariantMap &reactions)
|
||||
{
|
||||
QHash<QString, QString> reactionMap;
|
||||
for (auto it = reactions.constBegin(); it != reactions.constEnd(); ++it)
|
||||
reactionMap[it.key()] = it.value().toString();
|
||||
|
||||
// Update m_allBlocks for future scroll/loadEarlier
|
||||
for (int i = 0; i < m_allBlocks.size(); ++i) {
|
||||
if (m_allBlocks[i].type == ChatBlock::Assistant && !m_allBlocks[i].responseId.isEmpty())
|
||||
m_allBlocks[i].reaction = reactionMap.value(m_allBlocks[i].responseId);
|
||||
}
|
||||
|
||||
// Update visible m_blocks with dataChanged signal
|
||||
for (int i = 0; i < m_blocks.size(); ++i) {
|
||||
if (m_blocks[i].type == ChatBlock::Assistant && !m_blocks[i].responseId.isEmpty()) {
|
||||
QString emoji = reactionMap.value(m_blocks[i].responseId);
|
||||
if (m_blocks[i].reaction != emoji) {
|
||||
m_blocks[i].reaction = emoji;
|
||||
emit dataChanged(index(i), index(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update filtered blocks too
|
||||
for (int i = 0; i < m_filteredBlocks.size(); ++i) {
|
||||
if (m_filteredBlocks[i].type == ChatBlock::Assistant && !m_filteredBlocks[i].responseId.isEmpty())
|
||||
m_filteredBlocks[i].reaction = reactionMap.value(m_filteredBlocks[i].responseId);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatBlockModel::setRawText(const QString &text)
|
||||
{
|
||||
if (text == m_rawText) return;
|
||||
|
|
@ -219,8 +186,7 @@ void ChatBlockModel::updateVisibleWindow()
|
|||
if (m_blocks[i].content != newBlocks[i].content ||
|
||||
m_blocks[i].type != newBlocks[i].type ||
|
||||
m_blocks[i].name != newBlocks[i].name ||
|
||||
m_blocks[i].responseId != newBlocks[i].responseId ||
|
||||
m_blocks[i].reaction != newBlocks[i].reaction) {
|
||||
m_blocks[i].responseId != newBlocks[i].responseId) {
|
||||
firstDiff = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ struct ChatBlock {
|
|||
Type type;
|
||||
QString name; // tool/call name, empty for others
|
||||
QString responseId; // stable assistant response ID
|
||||
QString reaction; // emoji reaction text (empty if not reacted)
|
||||
QString content; // raw text content
|
||||
mutable QVariantList cachedSubBlocks; // cached parseSubBlocks result
|
||||
mutable QString cachedContent; // content when subBlocks were cached
|
||||
|
|
@ -55,7 +54,6 @@ public:
|
|||
SubBlocksRole, // QVariantList of sub-block maps
|
||||
FormattedContentRole, // pre-formatted HTML for call/tool expanded view
|
||||
ResponseIdRole,
|
||||
ReactionRole,
|
||||
};
|
||||
|
||||
explicit ChatBlockModel(QObject *parent = nullptr);
|
||||
|
|
@ -79,7 +77,6 @@ public:
|
|||
Q_INVOKABLE bool executeInTerminal(const QString &code, const QString &language,
|
||||
const QString &workingDirectory = QString()) const;
|
||||
Q_INVOKABLE bool loadEarlier(); // returns true if more blocks were loaded
|
||||
Q_INVOKABLE void setReactions(const QVariantMap &reactions);
|
||||
Q_INVOKABLE QString diagramUrl(const QString &source, const QString &language) const;
|
||||
Q_INVOKABLE bool invalidateDiagram(const QString &source, const QString &language) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -398,21 +398,6 @@ QVariantMap OllieDBusClient::getChat(const QString &sessionId, int offset)
|
|||
return result;
|
||||
}
|
||||
|
||||
QVariantMap OllieDBusClient::getReactions(const QString &sessionId)
|
||||
{
|
||||
QDBusReply<QString> reply = m_iface->call("GetReactions", sessionId);
|
||||
QVariantMap result;
|
||||
if (reply.isValid()) {
|
||||
QJsonDocument doc = QJsonDocument::fromJson(reply.value().toUtf8());
|
||||
if (doc.isObject()) {
|
||||
QJsonObject obj = doc.object();
|
||||
for (auto it = obj.begin(); it != obj.end(); ++it)
|
||||
result[it.key()] = it.value().toString();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariantMap OllieDBusClient::getConfig(const QString &sessionId)
|
||||
{
|
||||
QDBusReply<QString> reply = m_iface->call("GetConfig", sessionId);
|
||||
|
|
@ -485,18 +470,6 @@ bool OllieDBusClient::submit(const QString &sessionId, const QString &prompt)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::react(const QString &sessionId, const QString &emoji)
|
||||
{
|
||||
m_iface->asyncCall("React", sessionId, emoji);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::reactTo(const QString &sessionId, const QString &responseId, const QString &emoji)
|
||||
{
|
||||
m_iface->asyncCall("ReactTo", sessionId, responseId, emoji);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OllieDBusClient::interrupt(const QString &sessionId)
|
||||
{
|
||||
m_iface->asyncCall("Interrupt", sessionId);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ public:
|
|||
|
||||
Q_INVOKABLE QStringList peerList(const QString &sessionId);
|
||||
Q_INVOKABLE QVariantMap getChat(const QString &sessionId, int offset);
|
||||
Q_INVOKABLE QVariantMap getReactions(const QString &sessionId);
|
||||
Q_INVOKABLE QVariantMap getConfig(const QString &sessionId);
|
||||
Q_INVOKABLE QString getState(const QString &sessionId);
|
||||
QString activeSessionId() const { return m_activeSessionId; }
|
||||
|
|
@ -55,8 +54,6 @@ public:
|
|||
Q_INVOKABLE bool renameSession(const QString &sessionId, const QString &newName);
|
||||
Q_INVOKABLE bool setConfig(const QString &sessionId, const QString &key, const QString &value);
|
||||
Q_INVOKABLE bool submit(const QString &sessionId, const QString &prompt);
|
||||
Q_INVOKABLE bool react(const QString &sessionId, const QString &emoji);
|
||||
Q_INVOKABLE bool reactTo(const QString &sessionId, const QString &responseId, const QString &emoji);
|
||||
Q_INVOKABLE bool interrupt(const QString &sessionId);
|
||||
Q_INVOKABLE QStringList listBackends();
|
||||
Q_INVOKABLE QStringList listModels(const QString &sessionId);
|
||||
|
|
|
|||
Reference in New Issue