Wire desktop context-menu editing and update visible messages in place
This commit is contained in:
1 parent
2a9b5748e9
commit
1afb1010cc
2 files changed
+50
-4
No files matched your search
@@ -460,8 +460,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
QFont font = option.font; font.setPointSize(qMax(1, font.pointSize() - 1));
|
||||
QFont timeFont = option.font; timeFont.setPointSize(qMax(1, timeFont.pointSize() - 2));
|
||||
const int height = qMax(24, QFontMetrics(font).height() + 6), left = layout.bubbleRect.left() + kPadH;
|
||||
layout.reactionTimeText = index.data(MsgEditedRole).toBool() ? QCoreApplication::translate("ChatGui", "edited ") : QString();
|
||||
layout.reactionTimeText += index.data(MsgTimeRole).toString();
|
||||
layout.reactionTimeText = index.data(MsgTimeRole).toString();
|
||||
const int innerWidth = layout.bubbleRect.width() - 2 * kPadH;
|
||||
const int timeWidth = qMin(QFontMetrics(timeFont).horizontalAdvance(layout.reactionTimeText) + 2, qMax(0, innerWidth - height - 6));
|
||||
const int reactionsRight = layout.bubbleRect.right() - kPadH - timeWidth - 6;
|
||||
@@ -1683,8 +1682,7 @@ void MessageDelegate::drawStatusBar(QPainter* p, const Layout& layout, const QMo
|
||||
p->save();
|
||||
QFont font = option.font; font.setPointSize(qMax(1, font.pointSize() - 2)); p->setFont(font);
|
||||
p->setPen(QColor(128, 128, 128));
|
||||
QString text = index.data(MsgEditedRole).toBool() ? QCoreApplication::translate("ChatGui", "edited ") : QString();
|
||||
text += index.data(MsgTimeRole).toString();
|
||||
QString text = index.data(MsgTimeRole).toString();
|
||||
p->drawText(layout.statusRect, Qt::AlignRight | Qt::AlignVCenter, text);
|
||||
p->restore();
|
||||
}
|
||||
|
||||
@@ -683,6 +683,21 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
m_inputBar->focusProxy()->installEventFilter(m_view);
|
||||
window()->installEventFilter(m_view);
|
||||
|
||||
connect(m_inputBar, &InputBar::saveEdit, this,
|
||||
[this](const QString& channel, const QByteArray& id, quint64 version, const QString& text, quint64 request) {
|
||||
const auto bytes = text.toUtf8();
|
||||
if (!gui_bridge_get_inst() || !gui_bridge_is_uasync_ready() || channel != m_currentChannelId ||
|
||||
isDmChannel(channel) || id.size() != 32) {
|
||||
GUI_ERROR("edit: unavailable target=%s", qPrintable(channel)); m_inputBar->submissionResult(request, false); return;
|
||||
}
|
||||
auto* req = (struct chat_msg_submit*)u_calloc(1, sizeof(struct chat_msg_submit) + bytes.size());
|
||||
if (!req) { GUI_ERROR("edit: allocation failed"); m_inputBar->submissionResult(request, false); return; }
|
||||
req->inst = gui_bridge_get_inst(); req->request_id = request; req->expected_ver = version;
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s", channel.toUtf8().constData());
|
||||
memcpy(req->message_id, id.constData(), 32); req->data = (uint8_t*)(req + 1); req->data_len = bytes.size();
|
||||
memcpy(req->data, bytes.constData(), bytes.size());
|
||||
gui_bridge_post_uasync_fn(chat_core_submit_trampoline, req);
|
||||
});
|
||||
connect(m_inputBar, &InputBar::sendMessage, this, [this](const QString &text, const QByteArray& reply, quint64 request) {
|
||||
if (!gui_bridge_get_inst() || !gui_bridge_is_uasync_ready()) {
|
||||
GUI_ERROR("send: core unavailable"); m_inputBar->submissionResult(request, false); return;
|
||||
@@ -1356,6 +1371,30 @@ void MessageList::onMessageSubmitted(const uint8_t* data, int len) {
|
||||
m_inputBar->submissionResult(request, data[8] != 0);
|
||||
}
|
||||
|
||||
/* Меняем существующий item даже в окне старой цитаты, сохраняя позицию прокрутки. */
|
||||
void MessageList::onMessageUpdated(const uint8_t* data, int len) {
|
||||
if (!data || len < 34 || len != 1 + data[0] + 32) { GUI_ERROR("edit: invalid event bytes=%d", len); return; }
|
||||
const QString channel = QString::fromUtf8((const char*)data + 1, data[0]);
|
||||
if (channel != m_currentChannelId || !m_db) return;
|
||||
const QByteArray id((const char*)data + 1 + data[0], 32);
|
||||
const auto message = m_db->getMessageByKey(channel, id);
|
||||
if (message.messageId.isEmpty()) { GUI_WARN("edit: updated message disappeared ch=%s", qPrintable(channel)); return; }
|
||||
auto* sb = m_view->verticalScrollBar(); const bool atBottom = sb->value() == sb->maximum();
|
||||
const QPersistentModelIndex top(m_view->indexAt(QPoint(1, 1))); const int offset = m_view->visualRect(top).top();
|
||||
for (int row = 0; row < m_model->rowCount(); ++row) {
|
||||
auto* item = m_model->item(row);
|
||||
if (item->data(MsgMessageKeyRole).toString() != QString::fromLatin1(id.toHex())) continue;
|
||||
if (item->data(MsgVersionRole).toULongLong() >= message.version) break;
|
||||
item->setData(QString::fromUtf8(message.data), MsgTextRole);
|
||||
setupFeedback(item, message, channel); updateReply(item, message.replyTo); break;
|
||||
}
|
||||
refreshReplies(); m_view->doItemsLayout();
|
||||
if (atBottom) m_view->scrollToBottom();
|
||||
else if (top.isValid()) { m_view->scrollTo(top, QAbstractItemView::PositionAtTop); sb->setValue(sb->value() - offset); }
|
||||
GUI_DEBUG("edit: row refreshed ch=%s id=%s ver=%llu", qPrintable(channel), id.toHex().constData(),
|
||||
(unsigned long long)message.version);
|
||||
}
|
||||
|
||||
void MessageList::onMessageContextMenu(const QPoint& pos) {
|
||||
QModelIndex idx = m_view->indexAt(pos);
|
||||
if (!idx.isValid()) return;
|
||||
@@ -1374,6 +1413,15 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
|
||||
QString messageId = idx.data(MsgMessageKeyRole).toString();
|
||||
if (!isDm && messageId.size() == 64) {
|
||||
const QString channel = idx.data(MsgChannelIdRole).toString();
|
||||
if (idx.data(MsgIsOutgoingRole).toBool() && (ct == "text" || ct == "text/plain")) {
|
||||
connect(menu.addAction(QCoreApplication::translate("ChatGui", "Edit message")), &QAction::triggered, this,
|
||||
[this, channel, messageId] {
|
||||
if (channel != m_currentChannelId || !m_db) return;
|
||||
const auto message = m_db->getMessageByKey(channel, QByteArray::fromHex(messageId.toLatin1()));
|
||||
if (message.isOutgoing && message.messageId.size() == 32)
|
||||
m_inputBar->editMessage(message.messageId, message.version, QString::fromUtf8(message.data));
|
||||
});
|
||||
}
|
||||
connect(menu.addAction(QCoreApplication::translate("ChatGui", "Reply")), &QAction::triggered, this, [this, channel, messageId]() {
|
||||
if (channel != m_currentChannelId || !m_db) return;
|
||||
const auto original = m_db->getMessageByKey(channel, QByteArray::fromHex(messageId.toLatin1()));
|
||||
|
||||
Reference in new issue
Block a user