feat(panel/chat): 显隐切换、暂存清空隐藏、菜单避让、待办联动、DTK 关于
- 传送门 desktop 入口,--show 再点一次回 daemon;右键菜单加隐藏 - 暂存区清空后整个面板隐藏 - 右键菜单弹到面板左侧,避免被自己遮挡 - 启动悬停 80ms - 添加待办后立即打开待办窗口;待办独立图标 - 分词胶囊按浅/深色取色,修复透明不可见 - 关于改用 DAboutDialog - 聊天消息下方常驻 复制/编辑/重试;助手消息可编辑、可从任意一条重试
This commit is contained in:
+9
-19
@@ -182,15 +182,16 @@ public:
|
||||
connect(fork, &QToolButton::clicked, this,
|
||||
[this]() { Q_EMIT forkRequested(m_index); });
|
||||
actions->addWidget(fork);
|
||||
if (m_isLast) {
|
||||
auto *retry = actionButton(tr("重试"), m_actions);
|
||||
connect(retry, &QToolButton::clicked, this,
|
||||
[this]() { Q_EMIT retryRequested(); });
|
||||
actions->addWidget(retry);
|
||||
}
|
||||
auto *edit = actionButton(tr("编辑"), m_actions);
|
||||
connect(edit, &QToolButton::clicked, this,
|
||||
[this]() { Q_EMIT editRequested(m_index); });
|
||||
actions->addWidget(edit);
|
||||
auto *retry = actionButton(tr("重试"), m_actions);
|
||||
connect(retry, &QToolButton::clicked, this,
|
||||
[this]() { Q_EMIT retryRequested(m_index); });
|
||||
actions->addWidget(retry);
|
||||
}
|
||||
actions->addStretch();
|
||||
m_actions->hide();
|
||||
column->addWidget(m_actions);
|
||||
|
||||
if (m_isUser) {
|
||||
@@ -220,21 +221,10 @@ signals:
|
||||
void copyRequested(int index);
|
||||
void editRequested(int index);
|
||||
void forkRequested(int index);
|
||||
void retryRequested();
|
||||
void retryRequested(int index);
|
||||
void linkActivated(const QUrl &url);
|
||||
|
||||
protected:
|
||||
void enterEvent(QEnterEvent *event) override
|
||||
{
|
||||
m_actions->show();
|
||||
QWidget::enterEvent(event);
|
||||
}
|
||||
|
||||
void leaveEvent(QEvent *event) override
|
||||
{
|
||||
m_actions->hide();
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
ChatMessage m_message;
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ signals:
|
||||
void copyRequested(int index);
|
||||
void editRequested(int index);
|
||||
void forkRequested(int index);
|
||||
void retryRequested();
|
||||
void retryRequested(int index);
|
||||
void linkActivated(const QUrl &url);
|
||||
|
||||
protected:
|
||||
|
||||
+27
-13
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "chatview.h"
|
||||
|
||||
#include "../ui/aboutdialog.h"
|
||||
#include "markdown.h"
|
||||
#include "mcpclient.h"
|
||||
|
||||
@@ -555,7 +557,9 @@ void ChatWindow::setupUi()
|
||||
});
|
||||
connect(m_messages, &ChatMessageList::editRequested, this, &ChatWindow::editMessage);
|
||||
connect(m_messages, &ChatMessageList::forkRequested, this, &ChatWindow::forkFrom);
|
||||
connect(m_messages, &ChatMessageList::retryRequested, this, &ChatWindow::retryLast);
|
||||
connect(m_messages, &ChatMessageList::retryRequested, this, [this](int index) {
|
||||
retryFrom(index);
|
||||
});
|
||||
|
||||
auto *menu = new QMenu(menuButton);
|
||||
menu->addAction(tr("压缩上下文"), this, [this]() { beginCompression(false); });
|
||||
@@ -925,9 +929,6 @@ void ChatWindow::editMessage(int index)
|
||||
if (index < 0 || index >= conversation.messages.size()) {
|
||||
return;
|
||||
}
|
||||
if (conversation.messages.at(index).role != QStringLiteral("user")) {
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog dialog(this);
|
||||
dialog.setWindowTitle(tr("编辑消息"));
|
||||
@@ -959,6 +960,27 @@ void ChatWindow::editMessage(int index)
|
||||
requestCompletion();
|
||||
}
|
||||
|
||||
void ChatWindow::retryFrom(int index)
|
||||
{
|
||||
if (m_client->busy() || m_compressing || m_current < 0) {
|
||||
return;
|
||||
}
|
||||
ChatConversation &conversation = m_conversations[m_current];
|
||||
if (index < 0 || index >= conversation.messages.size()) {
|
||||
return;
|
||||
}
|
||||
if (conversation.messages.at(index).role != QStringLiteral("assistant")) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* drop everything from the assistant answer on, then regenerate it */
|
||||
conversation.messages.resize(index);
|
||||
conversation.updatedAt = QDateTime::currentMSecsSinceEpoch();
|
||||
save();
|
||||
renderConversation();
|
||||
requestCompletion();
|
||||
}
|
||||
|
||||
void ChatWindow::retryLast()
|
||||
{
|
||||
if (m_client->busy() || m_compressing || m_current < 0) {
|
||||
@@ -1028,15 +1050,7 @@ void ChatWindow::handleAnchor(const QUrl &url)
|
||||
|
||||
void ChatWindow::showAbout()
|
||||
{
|
||||
QMessageBox::about(
|
||||
this, tr("关于小埃同学"),
|
||||
tr("<h3>GXDE 小埃同学</h3>"
|
||||
"<p>版本 %1</p>"
|
||||
"<p>GXDE 桌面的 AI 助手:传送门、内容工厂、待办与对话。</p>"
|
||||
"<p>许可证:GPL-3.0-or-later<br/>"
|
||||
"仓库:<a href='https://gitee.com/GXDE-OS/gxde-ai-see'>"
|
||||
"gitee.com/GXDE-OS/gxde-ai-see</a></p>")
|
||||
.arg(QCoreApplication::applicationVersion()));
|
||||
showAboutDialog(this, tr("GXDE 桌面的 AI 助手:传送门、内容工厂、待办与对话。"));
|
||||
}
|
||||
|
||||
void ChatWindow::appendError(const QString &message)
|
||||
|
||||
@@ -68,6 +68,7 @@ private:
|
||||
void sendPayload();
|
||||
void editMessage(int index);
|
||||
void retryLast();
|
||||
void retryFrom(int index);
|
||||
void forkFrom(int index);
|
||||
void beginCompression(bool thenSend);
|
||||
void handleAnchor(const QUrl &url);
|
||||
|
||||
Reference in New Issue
Block a user