Use the rich text char format to store mentions rather than a separate structure in ChatBarCache.
This removes mentions from ChatBarCache and instead sets mentions as an anchor using the QTextCursor. Saving and restoring the chatbar text content is then done using QTextDocumentFragments which retain the rich text formatting.
This commit is contained in:
@@ -400,7 +400,6 @@ void ModelTest::testCompletionModel()
|
||||
auto model = new CompletionModel(this);
|
||||
auto tester = new QAbstractItemModelTester(model, model);
|
||||
tester->setUseFetchMore(true);
|
||||
model->setRoom(room);
|
||||
model->setAutoCompletionType(CompletionModel::Room);
|
||||
auto roomListModel = new RoomListModel(this);
|
||||
roomListModel->setConnection(connection);
|
||||
|
||||
@@ -30,8 +30,6 @@ QQC2.Control {
|
||||
}
|
||||
|
||||
readonly property LibNeoChat.CompletionModel completionModel: LibNeoChat.CompletionModel {
|
||||
room: root.room
|
||||
type: root.chatBarType
|
||||
textItem: root.model.focusedTextItem
|
||||
roomListModel: RoomManager.roomListModel
|
||||
userListModel: RoomManager.userListModel
|
||||
|
||||
@@ -9,6 +9,7 @@ target_sources(LibNeoChat PRIVATE
|
||||
neochatroommember.cpp
|
||||
accountmanager.cpp
|
||||
chatbarcache.cpp
|
||||
blockcache.cpp
|
||||
chatbarsyntaxhighlighter.cpp
|
||||
chatkeyhelper.cpp
|
||||
chatmarkdownhelper.cpp
|
||||
|
||||
25
src/libneochat/blockcache.cpp
Normal file
25
src/libneochat/blockcache.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: 2026 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "blockcache.h"
|
||||
|
||||
#include "chattextitemhelper.h"
|
||||
|
||||
using namespace Block;
|
||||
|
||||
void Cache::fill(QList<MessageComponent> components)
|
||||
{
|
||||
std::ranges::for_each(components, [this](const MessageComponent &component) {
|
||||
if (!MessageComponentType::isTextType(component.type)) {
|
||||
return;
|
||||
}
|
||||
const auto textItem = component.attributes["chatTextItemHelper"_L1].value<ChatTextItemHelper *>();
|
||||
if (!textItem) {
|
||||
return;
|
||||
}
|
||||
append(CacheItem{
|
||||
.type = component.type,
|
||||
.content = textItem->toFragment(),
|
||||
});
|
||||
});
|
||||
}
|
||||
28
src/libneochat/blockcache.h
Normal file
28
src/libneochat/blockcache.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-FileCopyrightText: 2026 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QTextDocumentFragment>
|
||||
|
||||
#include "enums/messagecomponenttype.h"
|
||||
#include "messagecomponent.h"
|
||||
|
||||
namespace Block
|
||||
{
|
||||
struct CacheItem {
|
||||
MessageComponentType::Type type = MessageComponentType::Other;
|
||||
QTextDocumentFragment content;
|
||||
};
|
||||
|
||||
class Cache : private QList<CacheItem>
|
||||
{
|
||||
public:
|
||||
using QList<CacheItem>::constBegin, QList<CacheItem>::constEnd;
|
||||
using QList<CacheItem>::isEmpty;
|
||||
using QList<CacheItem>::clear;
|
||||
|
||||
void fill(QList<MessageComponent> components);
|
||||
};
|
||||
}
|
||||
@@ -33,6 +33,11 @@ ChatBarCache::ChatBarCache(QObject *parent)
|
||||
connect(this, &ChatBarCache::relationIdChanged, this, &ChatBarCache::relationAuthorIsPresentChanged);
|
||||
}
|
||||
|
||||
Block::Cache &ChatBarCache::cache()
|
||||
{
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
QString ChatBarCache::text() const
|
||||
{
|
||||
return m_text;
|
||||
@@ -55,27 +60,7 @@ QString ChatBarCache::sendText() const
|
||||
return text().isEmpty() ? path.mid(path.lastIndexOf(u'/') + 1) : text();
|
||||
}
|
||||
|
||||
return formatMentions();
|
||||
}
|
||||
|
||||
QString ChatBarCache::formatMentions() const
|
||||
{
|
||||
auto mentions = m_mentions;
|
||||
std::sort(mentions.begin(), mentions.end(), [](const auto &a, const auto &b) {
|
||||
return a.cursor.anchor() > b.cursor.anchor();
|
||||
});
|
||||
|
||||
auto formattedText = text();
|
||||
for (const auto &mention : mentions) {
|
||||
if (mention.text.isEmpty() || mention.id.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
formattedText = formattedText.replace(mention.cursor.anchor(),
|
||||
mention.cursor.position() - mention.cursor.anchor(),
|
||||
u"[%1](https://matrix.to/#/%2)"_s.arg(mention.text.toHtmlEscaped(), mention.id));
|
||||
}
|
||||
|
||||
return formattedText;
|
||||
return text();
|
||||
}
|
||||
|
||||
bool ChatBarCache::isReplying() const
|
||||
@@ -232,11 +217,6 @@ void ChatBarCache::clearRelations()
|
||||
Q_EMIT attachmentPathChanged();
|
||||
}
|
||||
|
||||
QList<Mention> *ChatBarCache::mentions()
|
||||
{
|
||||
return &m_mentions;
|
||||
}
|
||||
|
||||
QString ChatBarCache::savedText() const
|
||||
{
|
||||
return m_savedText;
|
||||
@@ -294,7 +274,6 @@ void ChatBarCache::postMessage()
|
||||
void ChatBarCache::clearCache()
|
||||
{
|
||||
setText({});
|
||||
m_mentions.clear();
|
||||
m_savedText = QString();
|
||||
clearRelations();
|
||||
}
|
||||
|
||||
@@ -8,22 +8,13 @@
|
||||
#include <QQuickTextDocument>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include "blockcache.h"
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class RoomMember;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Defines a user mention in the current chat or edit text.
|
||||
*/
|
||||
struct Mention {
|
||||
QTextCursor cursor; /**< Contains the mention's text and position in the text. */
|
||||
QString text; /**< The inserted text of the mention. */
|
||||
int start = 0; /**< Start position of the mention. */
|
||||
int position = 0; /**< End position of the mention. */
|
||||
QString id; /**< The id the mention (used to create link when sending the message). */
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ChatBarCache
|
||||
*
|
||||
@@ -147,6 +138,8 @@ public:
|
||||
|
||||
explicit ChatBarCache(QObject *parent = nullptr);
|
||||
|
||||
Block::Cache &cache();
|
||||
|
||||
QString text() const;
|
||||
QString sendText() const;
|
||||
void setText(const QString &text);
|
||||
@@ -178,11 +171,6 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE void clearRelations();
|
||||
|
||||
/**
|
||||
* @brief Retrieve the mentions for the current chat bar text.
|
||||
*/
|
||||
QList<Mention> *mentions();
|
||||
|
||||
/**
|
||||
* @brief Get the saved chat bar text.
|
||||
*/
|
||||
@@ -209,14 +197,14 @@ Q_SIGNALS:
|
||||
void relationAuthorIsPresentChanged();
|
||||
|
||||
private:
|
||||
Block::Cache m_cache;
|
||||
|
||||
QString m_text = QString();
|
||||
QString formatMentions() const;
|
||||
|
||||
QString m_relationId = QString();
|
||||
RelationType m_relationType = RelationType::None;
|
||||
QString m_threadId = QString();
|
||||
QString m_attachmentPath = QString();
|
||||
QList<Mention> m_mentions;
|
||||
QString m_savedText;
|
||||
|
||||
void clearCache();
|
||||
|
||||
@@ -4,22 +4,16 @@
|
||||
|
||||
#include "chatbarsyntaxhighlighter.h"
|
||||
|
||||
#include "chatbarcache.h"
|
||||
#include "chattextitemhelper.h"
|
||||
#include "enums/chatbartype.h"
|
||||
|
||||
ChatBarSyntaxHighlighter::ChatBarSyntaxHighlighter(QObject *parent)
|
||||
: QSyntaxHighlighter(parent)
|
||||
{
|
||||
m_theme = static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
||||
connect(m_theme, &Kirigami::Platform::PlatformTheme::colorsChanged, this, [this]() {
|
||||
m_mentionFormat.setForeground(m_theme->linkColor());
|
||||
m_errorFormat.setForeground(m_theme->negativeTextColor());
|
||||
});
|
||||
|
||||
m_mentionFormat.setFontWeight(QFont::Bold);
|
||||
m_mentionFormat.setForeground(m_theme->linkColor());
|
||||
|
||||
m_errorFormat.setForeground(m_theme->negativeTextColor());
|
||||
m_errorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
|
||||
|
||||
@@ -48,36 +42,4 @@ void ChatBarSyntaxHighlighter::highlightBlock(const QString &text)
|
||||
setFormat(error.first, error.second.size(), m_errorFormat);
|
||||
}
|
||||
}
|
||||
|
||||
if (!room || type == ChatBarType::None) {
|
||||
return;
|
||||
}
|
||||
auto mentions = room->cacheForType(type)->mentions();
|
||||
mentions->erase(std::remove_if(mentions->begin(),
|
||||
mentions->end(),
|
||||
[this](auto &mention) {
|
||||
if (document()->toPlainText().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mention.cursor.position() == 0 && mention.cursor.anchor() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mention.cursor.position() - mention.cursor.anchor() != mention.text.size()) {
|
||||
mention.cursor.setPosition(mention.start);
|
||||
mention.cursor.setPosition(mention.cursor.anchor() + mention.text.size(), QTextCursor::KeepAnchor);
|
||||
}
|
||||
|
||||
if (mention.cursor.selectedText() != mention.text) {
|
||||
return true;
|
||||
}
|
||||
if (currentBlock() == mention.cursor.block()) {
|
||||
mention.start = mention.cursor.anchor();
|
||||
mention.position = mention.cursor.position();
|
||||
setFormat(mention.cursor.selectionStart(), mention.cursor.selectedText().size(), m_mentionFormat);
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
mentions->end());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
|
||||
private:
|
||||
Kirigami::Platform::PlatformTheme *m_theme = nullptr;
|
||||
QTextCharFormat m_mentionFormat;
|
||||
QTextCharFormat m_errorFormat;
|
||||
|
||||
Sonnet::BackgroundChecker *m_checker = new Sonnet::BackgroundChecker(this);
|
||||
|
||||
@@ -92,7 +92,7 @@ void ChatTextItemHelper::setTextItem(QQuickItem *textItem)
|
||||
connect(doc, &QTextDocument::contentsChange, this, &ChatTextItemHelper::contentsChange);
|
||||
m_highlighter->setDocument(doc);
|
||||
}
|
||||
initializeChars();
|
||||
initialize();
|
||||
}
|
||||
|
||||
Q_EMIT textItemChanged();
|
||||
@@ -133,24 +133,21 @@ void ChatTextItemHelper::setFixedChars(const QString &startChars, const QString
|
||||
}
|
||||
m_fixedStartChars = startChars;
|
||||
m_fixedEndChars = endChars;
|
||||
initializeChars();
|
||||
initialize();
|
||||
}
|
||||
|
||||
QString ChatTextItemHelper::initialText() const
|
||||
QTextDocumentFragment ChatTextItemHelper::initialFragment() const
|
||||
{
|
||||
return m_initialText;
|
||||
return m_initialFragment;
|
||||
}
|
||||
|
||||
void ChatTextItemHelper::setInitialText(const QString &text)
|
||||
void ChatTextItemHelper::setInitialFragment(const QTextDocumentFragment &fragment)
|
||||
{
|
||||
if (text == m_initialText) {
|
||||
return;
|
||||
}
|
||||
m_initialText = text;
|
||||
initializeChars();
|
||||
m_initialFragment = fragment;
|
||||
initialize();
|
||||
}
|
||||
|
||||
void ChatTextItemHelper::initializeChars()
|
||||
void ChatTextItemHelper::initialize()
|
||||
{
|
||||
const auto doc = document();
|
||||
if (!doc) {
|
||||
@@ -166,8 +163,8 @@ void ChatTextItemHelper::initializeChars()
|
||||
|
||||
cursor.beginEditBlock();
|
||||
int finalCursorPos = cursor.position();
|
||||
if (doc->isEmpty() && !m_initialText.isEmpty()) {
|
||||
cursor.insertText(m_initialText);
|
||||
if (doc->isEmpty() && !m_initialFragment.isEmpty()) {
|
||||
cursor.insertFragment(m_initialFragment);
|
||||
finalCursorPos = cursor.position();
|
||||
}
|
||||
|
||||
@@ -618,6 +615,16 @@ QString ChatTextItemHelper::plainText() const
|
||||
return trim(doc->toPlainText());
|
||||
}
|
||||
|
||||
QTextDocumentFragment ChatTextItemHelper::toFragment() const
|
||||
{
|
||||
auto cursor = textCursor();
|
||||
if (cursor.isNull()) {
|
||||
return {};
|
||||
}
|
||||
cursor.select(QTextCursor::Document);
|
||||
return cursor.selection();
|
||||
}
|
||||
|
||||
QString ChatTextItemHelper::trim(QString string) const
|
||||
{
|
||||
while (string.startsWith(u"\n"_s)) {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <qtextdocumentfragment.h>
|
||||
|
||||
#include "enums/chatbartype.h"
|
||||
#include "enums/richformat.h"
|
||||
@@ -108,16 +110,16 @@ public:
|
||||
void setFixedChars(const QString &startChars, const QString &endChars);
|
||||
|
||||
/**
|
||||
* @brief Any text to initialise the text item with when set.
|
||||
* @brief Any QTextDocumentFragment to initialise the text item with when set.
|
||||
*/
|
||||
QString initialText() const;
|
||||
QTextDocumentFragment initialFragment() const;
|
||||
|
||||
/**
|
||||
* @brief Set the text to initialise the text item with when set.
|
||||
* @brief Set the QTextDocumentFragment to initialise the text item with when set.
|
||||
*
|
||||
* This text will only be set if the text item is empty when set.
|
||||
*/
|
||||
void setInitialText(const QString &text);
|
||||
void setInitialFragment(const QTextDocumentFragment &fragment);
|
||||
|
||||
/**
|
||||
* @brief The underlying QTextDocument.
|
||||
@@ -248,6 +250,11 @@ public:
|
||||
*/
|
||||
QString plainText() const;
|
||||
|
||||
/**
|
||||
* @brief Output the text in the text item as a QTextDocumentFragment.
|
||||
*/
|
||||
QTextDocumentFragment toFragment() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* @brief Emitted when the NeoChatRoom used by the syntax highlighter is changed.
|
||||
@@ -309,8 +316,8 @@ private:
|
||||
|
||||
QString m_fixedStartChars = {};
|
||||
QString m_fixedEndChars = {};
|
||||
QString m_initialText = {};
|
||||
void initializeChars();
|
||||
QTextDocumentFragment m_initialFragment = {};
|
||||
void initialize();
|
||||
bool m_initializingChars = false;
|
||||
|
||||
std::optional<int> lineLength(int lineNumber) const;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <QDebug>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include <Kirigami/Platform/PlatformTheme>
|
||||
|
||||
#include "chattextitemhelper.h"
|
||||
#include "completionproxymodel.h"
|
||||
#include "models/actionsmodel.h"
|
||||
@@ -24,35 +26,6 @@ CompletionModel::CompletionModel(QObject *parent)
|
||||
m_emojiModel->addSourceModel(&EmojiModel::instance());
|
||||
}
|
||||
|
||||
NeoChatRoom *CompletionModel::room() const
|
||||
{
|
||||
return m_room;
|
||||
}
|
||||
|
||||
void CompletionModel::setRoom(NeoChatRoom *room)
|
||||
{
|
||||
if (m_room == room) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_room = room;
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
ChatBarType::Type CompletionModel::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void CompletionModel::setType(ChatBarType::Type type)
|
||||
{
|
||||
if (type == m_type) {
|
||||
return;
|
||||
}
|
||||
m_type = type;
|
||||
Q_EMIT typeChanged();
|
||||
}
|
||||
|
||||
ChatTextItemHelper *CompletionModel::textItem() const
|
||||
{
|
||||
return m_textItem;
|
||||
@@ -322,29 +295,22 @@ void CompletionModel::insertCompletion(const QString &text, const QUrl &link)
|
||||
}
|
||||
cursor.removeSelectedText();
|
||||
|
||||
const int start = cursor.position();
|
||||
const auto insertString = u"%1 %2"_s.arg(text, link.isEmpty() ? QString() : u" "_s);
|
||||
cursor.insertText(insertString);
|
||||
cursor.setPosition(start);
|
||||
cursor.setPosition(start + text.size(), QTextCursor::KeepAnchor);
|
||||
cursor.setKeepPositionOnInsert(true);
|
||||
cursor.endEditBlock();
|
||||
if (!link.isEmpty()) {
|
||||
pushMention({
|
||||
.cursor = cursor,
|
||||
.text = text,
|
||||
.id = link.toString(),
|
||||
});
|
||||
const auto previousFormat = cursor.charFormat();
|
||||
auto charFormat = previousFormat;
|
||||
if (link.isValid()) {
|
||||
const auto theme = static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
||||
charFormat = QTextCharFormat();
|
||||
charFormat.setForeground(theme->linkColor());
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
charFormat.setAnchor(true);
|
||||
charFormat.setAnchorHref(link.toString());
|
||||
}
|
||||
cursor.insertText(text, charFormat);
|
||||
if (!link.isEmpty()) {
|
||||
cursor.insertText(u" "_s, previousFormat);
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
m_textItem->rehighlight();
|
||||
}
|
||||
|
||||
void CompletionModel::pushMention(const Mention mention) const
|
||||
{
|
||||
if (!m_room || m_type == ChatBarType::None) {
|
||||
return;
|
||||
}
|
||||
m_room->cacheForType(m_type)->mentions()->push_back(mention);
|
||||
}
|
||||
|
||||
#include "moc_completionmodel.cpp"
|
||||
|
||||
@@ -30,16 +30,6 @@ class CompletionModel : public QAbstractListModel
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
/**
|
||||
* @brief The current room that the text document is being handled for.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
|
||||
|
||||
/**
|
||||
* @brief The ChatBarType::Type of the chat bar.
|
||||
*/
|
||||
Q_PROPERTY(ChatBarType::Type type READ type WRITE setType NOTIFY typeChanged)
|
||||
|
||||
/**
|
||||
* @brief The QML text Item that completions are being provided for.
|
||||
*/
|
||||
@@ -94,12 +84,6 @@ public:
|
||||
|
||||
explicit CompletionModel(QObject *parent = nullptr);
|
||||
|
||||
NeoChatRoom *room() const;
|
||||
void setRoom(NeoChatRoom *room);
|
||||
|
||||
ChatBarType::Type type() const;
|
||||
void setType(ChatBarType::Type type);
|
||||
|
||||
ChatTextItemHelper *textItem() const;
|
||||
void setTextItem(ChatTextItemHelper *textItem);
|
||||
|
||||
@@ -140,8 +124,6 @@ public:
|
||||
Q_INVOKABLE void insertCompletion(const QString &text, const QUrl &link);
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void typeChanged();
|
||||
void textItemChanged();
|
||||
void autoCompletionTypeChanged();
|
||||
void roomListModelChanged();
|
||||
@@ -149,8 +131,6 @@ Q_SIGNALS:
|
||||
void isCompletingChanged();
|
||||
|
||||
private:
|
||||
QPointer<NeoChatRoom> m_room;
|
||||
ChatBarType::Type m_type = ChatBarType::None;
|
||||
QPointer<ChatTextItemHelper> m_textItem;
|
||||
|
||||
bool m_ignoreCurrentCompletion = false;
|
||||
@@ -165,6 +145,4 @@ private:
|
||||
UserListModel *m_userListModel;
|
||||
RoomListModel *m_roomListModel;
|
||||
QConcatenateTablesProxyModel *m_emojiModel;
|
||||
|
||||
void pushMention(const Mention mention) const;
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ QQC2.TextArea {
|
||||
*/
|
||||
property bool isReply: false
|
||||
|
||||
Layout.fillWidth: NeoChatConfig.compactLayout
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
Keys.onPressed: (event) => {
|
||||
|
||||
@@ -104,7 +104,7 @@ void ChatBarMessageContentModel::initializeModel(const QString &initialText)
|
||||
const auto textItem = new ChatTextItemHelper(this);
|
||||
textItem->setRoom(m_room);
|
||||
textItem->setType(m_type);
|
||||
textItem->setInitialText(initialText);
|
||||
textItem->setInitialFragment(QTextDocumentFragment::fromPlainText(initialText));
|
||||
connectTextItem(textItem);
|
||||
m_components += MessageComponent{
|
||||
.type = MessageComponentType::Text,
|
||||
@@ -125,25 +125,17 @@ void ChatBarMessageContentModel::initializeFromCache()
|
||||
|
||||
clearModel();
|
||||
|
||||
const auto currentCache = m_room->cacheForType(m_type);
|
||||
const auto textSections = (m_type == ChatBarType::Room ? currentCache->text() : currentCache->relationMessage()).split(u"\n\n"_s);
|
||||
if (textSections.length() == 1 && textSections[0].isEmpty()) {
|
||||
const auto ¤tCache = m_room->cacheForType(m_type);
|
||||
const auto &blockCache = currentCache->cache();
|
||||
if (blockCache.isEmpty()) {
|
||||
initializeModel();
|
||||
return;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
for (const auto §ion : textSections) {
|
||||
const auto type = MessageComponentType::typeForString(section);
|
||||
auto cleanText = section;
|
||||
if (type == MessageComponentType::Code) {
|
||||
cleanText.remove(0, 4);
|
||||
cleanText.remove(cleanText.length() - 4, 4);
|
||||
} else if (type == MessageComponentType::Quote) {
|
||||
cleanText.remove(0, 2);
|
||||
}
|
||||
insertComponent(rowCount(), type, {}, cleanText);
|
||||
}
|
||||
std::ranges::for_each(blockCache.constBegin(), blockCache.constEnd(), [this](const Block::CacheItem &cacheItem) {
|
||||
insertComponent(rowCount(), cacheItem.type, {}, cacheItem.content);
|
||||
});
|
||||
endResetModel();
|
||||
|
||||
if (currentCache->attachmentPath().length() > 0) {
|
||||
@@ -390,7 +382,7 @@ void ChatBarMessageContentModel::addAttachment(const QUrl &path)
|
||||
}
|
||||
|
||||
ChatBarMessageContentModel::ComponentIt
|
||||
ChatBarMessageContentModel::insertComponent(int row, MessageComponentType::Type type, QVariantMap attributes, const QString &intialText)
|
||||
ChatBarMessageContentModel::insertComponent(int row, MessageComponentType::Type type, QVariantMap attributes, const QTextDocumentFragment &intialFragment)
|
||||
{
|
||||
if (row < 0 || row > rowCount()) {
|
||||
return m_components.end();
|
||||
@@ -398,7 +390,7 @@ ChatBarMessageContentModel::insertComponent(int row, MessageComponentType::Type
|
||||
|
||||
if (MessageComponentType::isTextType(type)) {
|
||||
const auto textItemWrapper = new ChatTextItemHelper(this);
|
||||
textItemWrapper->setInitialText(intialText);
|
||||
textItemWrapper->setInitialFragment(intialFragment);
|
||||
textItemWrapper->setRoom(m_room);
|
||||
textItemWrapper->setType(m_type);
|
||||
if (type == MessageComponentType::Quote) {
|
||||
@@ -600,7 +592,8 @@ void ChatBarMessageContentModel::updateCache() const
|
||||
return;
|
||||
}
|
||||
|
||||
m_room->cacheForType(m_type)->setText(messageText());
|
||||
m_room->cacheForType(m_type)->cache().clear();
|
||||
m_room->cacheForType(m_type)->cache().fill(m_components);
|
||||
}
|
||||
|
||||
inline QString formatQuote(const QString &input)
|
||||
|
||||
@@ -143,7 +143,7 @@ private:
|
||||
QPointer<ChatKeyHelper> m_keyHelper;
|
||||
void connectKeyHelper();
|
||||
|
||||
ComponentIt insertComponent(int row, MessageComponentType::Type type, QVariantMap attributes = {}, const QString &intialText = {});
|
||||
ComponentIt insertComponent(int row, MessageComponentType::Type type, QVariantMap attributes = {}, const QTextDocumentFragment &intialFragment = {});
|
||||
ComponentIt removeComponent(ComponentIt it);
|
||||
void removeComponent(ChatTextItemHelper *textItem);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user