Allow the condition for when messages are automatically marked as read to be configurable.
Title this adds a number of options for when messages should be automatically marked as read for the user to choose from.
{width=480 height=262}
This commit is contained in:
@@ -57,7 +57,7 @@ void TimelineMessageModelTest::switchEmptyRoom()
|
|||||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
||||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s);
|
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s);
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
QSignalSpy spy(model, SIGNAL(roomChanged(NeoChatRoom *, NeoChatRoom *)));
|
||||||
|
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
model->setRoom(firstRoom);
|
model->setRoom(firstRoom);
|
||||||
@@ -77,7 +77,7 @@ void TimelineMessageModelTest::switchSyncedRoom()
|
|||||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
||||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
QSignalSpy spy(model, SIGNAL(roomChanged(NeoChatRoom *, NeoChatRoom *)));
|
||||||
|
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
model->setRoom(firstRoom);
|
model->setRoom(firstRoom);
|
||||||
|
|||||||
@@ -78,6 +78,12 @@
|
|||||||
<label>Use a compact room list layout</label>
|
<label>Use a compact room list layout</label>
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="MarkReadCondition" type="Enum">
|
||||||
|
<label>The sort order for the rooms in the list.</label>
|
||||||
|
<choices name="::TimelineMarkReadCondition::Condition">
|
||||||
|
</choices>
|
||||||
|
<default>2</default>
|
||||||
|
</entry>
|
||||||
<entry name="ShowStateEvent" type="bool">
|
<entry name="ShowStateEvent" type="bool">
|
||||||
<label>Show state events in the timeline</label>
|
<label>Show state events in the timeline</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
|
|||||||
@@ -104,11 +104,14 @@ Kirigami.Page {
|
|||||||
id: timelineViewLoader
|
id: timelineViewLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentRoom && !root.currentRoom.isInvite && !root.currentRoom.isSpace
|
active: root.currentRoom && !root.currentRoom.isInvite && !root.currentRoom.isSpace
|
||||||
|
// We need the loader to be active but invisible while the room is loading messages so signals in TimelineView work.
|
||||||
|
visible: !root.loading
|
||||||
sourceComponent: TimelineView {
|
sourceComponent: TimelineView {
|
||||||
id: timelineView
|
id: timelineView
|
||||||
messageFilterModel: root.messageFilterModel
|
messageFilterModel: root.messageFilterModel
|
||||||
compactLayout: NeoChatConfig.compactLayout
|
compactLayout: NeoChatConfig.compactLayout
|
||||||
fileDropEnabled: !Controller.isFlatpak
|
fileDropEnabled: !Controller.isFlatpak
|
||||||
|
markReadCondition: NeoChatConfig.markReadCondition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ target_sources(LibNeoChat PRIVATE
|
|||||||
enums/pushrule.h
|
enums/pushrule.h
|
||||||
enums/roomsortparameter.cpp
|
enums/roomsortparameter.cpp
|
||||||
enums/roomsortorder.h
|
enums/roomsortorder.h
|
||||||
|
enums/timelinemarkreadcondition.h
|
||||||
events/imagepackevent.cpp
|
events/imagepackevent.cpp
|
||||||
events/pollevent.cpp
|
events/pollevent.cpp
|
||||||
jobs/neochatgetcommonroomsjob.cpp
|
jobs/neochatgetcommonroomsjob.cpp
|
||||||
|
|||||||
32
src/libneochat/enums/timelinemarkreadcondition.h
Normal file
32
src/libneochat/enums/timelinemarkreadcondition.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2025 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 <QObject>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class TimelineMarkReadCondition
|
||||||
|
*
|
||||||
|
* This class is designed to define the TimelineMarkReadCondition enumeration.
|
||||||
|
*/
|
||||||
|
class TimelineMarkReadCondition : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
QML_UNCREATABLE("")
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief The condition for marking messages as read.
|
||||||
|
*/
|
||||||
|
enum Condition {
|
||||||
|
Never = 0, /**< Messages should never be marked automatically. */
|
||||||
|
Entry, /**< Messages should be marked automatically on entry to the room. */
|
||||||
|
EntryVisible, /**< Messages should be marked automatically on entry to the room if all messages are visible. */
|
||||||
|
Exit, /**< Messages should be marked automatically on exiting the room. */
|
||||||
|
ExitVisible, /**< Messages should be marked automatically on exiting the room if all messages are visible. */
|
||||||
|
};
|
||||||
|
Q_ENUM(Condition);
|
||||||
|
};
|
||||||
@@ -134,9 +134,45 @@ FormCard.FormCardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FormCard.FormHeader {
|
FormCard.FormHeader {
|
||||||
title: i18n("Timeline Events")
|
title: i18nc("@title", "Timeline")
|
||||||
}
|
}
|
||||||
FormCard.FormCard {
|
FormCard.FormCard {
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
id: markAsReadCombo
|
||||||
|
text: i18n("Mark messages as read when:")
|
||||||
|
textRole: "name"
|
||||||
|
valueRole: "value"
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
name: i18n("Never"),
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: i18nc("@item:inlistbox As in mark messages in the room as read when entering the room", "Entering the room"),
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: i18nc("@item:inlistbox As in mark messages in the room as read when entering the room and all messages are visible on screen", "Entering the room and all unread messages are visible"),
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: i18nc("@item:inlistbox As in mark messages in the room as read when exiting the room", "Exiting the room"),
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: i18nc("@item:inlistbox As in mark messages in the room as read when exiting the room and all messages are visible on screen", "Exiting the room and all unread messages are visible"),
|
||||||
|
value: 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Component.onCompleted: currentIndex = NeoChatConfig.markReadCondition
|
||||||
|
onCurrentValueChanged: NeoChatConfig.markReadCondition = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {
|
||||||
|
above: markAsReadCombo
|
||||||
|
below: showDeletedMessages
|
||||||
|
}
|
||||||
|
|
||||||
FormCard.FormCheckDelegate {
|
FormCard.FormCheckDelegate {
|
||||||
id: showDeletedMessages
|
id: showDeletedMessages
|
||||||
text: i18n("Show deleted messages")
|
text: i18n("Show deleted messages")
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ QQC2.ScrollView {
|
|||||||
*/
|
*/
|
||||||
property bool fileDropEnabled: true
|
property bool fileDropEnabled: true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The TimelineMarkReadCondition to use for when messages should be marked as read automatically.
|
||||||
|
*/
|
||||||
|
required property int markReadCondition
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shift the view to the given event ID.
|
* @brief Shift the view to the given event ID.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +59,6 @@ QQC2.ScrollView {
|
|||||||
* All messages will be marked as read.
|
* All messages will be marked as read.
|
||||||
*/
|
*/
|
||||||
function goToLastMessage() {
|
function goToLastMessage() {
|
||||||
_private.room.markAllMessagesAsRead();
|
|
||||||
messageListView.positionViewAtBeginning();
|
messageListView.positionViewAtBeginning();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +158,8 @@ QQC2.ScrollView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onReadMarkerAdded() {
|
function onReadMarkerAdded() {
|
||||||
if (messageListView.allUnreadVisible()) {
|
if (root.markReadCondition == LibNeoChat.TimelineMarkReadCondition.EntryVisible && messageListView.allUnreadVisible()) {
|
||||||
_private.room.markAllMessagesAsRead();
|
root.room.markAllMessagesAsRead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +167,20 @@ QQC2.ScrollView {
|
|||||||
messageListView.positionViewAtBeginning();
|
messageListView.positionViewAtBeginning();
|
||||||
_private.room.markAllMessagesAsRead();
|
_private.room.markAllMessagesAsRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onRoomAboutToChange(oldRoom, newRoom) {
|
||||||
|
if (root.markReadCondition == LibNeoChat.TimelineMarkReadCondition.Exit ||
|
||||||
|
(root.markReadCondition == LibNeoChat.TimelineMarkReadCondition.ExitVisible && messageListView.allUnreadVisible())
|
||||||
|
) {
|
||||||
|
oldRoom.markAllMessagesAsRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRoomChanged(oldRoom, newRoom) {
|
||||||
|
if (root.markReadCondition == LibNeoChat.TimelineMarkReadCondition.Entry) {
|
||||||
|
newRoom.markAllMessagesAsRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAtYEndChanged: if (atYEnd && _private.hasScrolledUpBefore) {
|
onAtYEndChanged: if (atYEnd && _private.hasScrolledUpBefore) {
|
||||||
|
|||||||
@@ -34,18 +34,15 @@ MessageModel::MessageModel(QObject *parent)
|
|||||||
{
|
{
|
||||||
connect(this, &MessageModel::newEventAdded, this, &MessageModel::createEventObjects);
|
connect(this, &MessageModel::newEventAdded, this, &MessageModel::createEventObjects);
|
||||||
|
|
||||||
connect(this, &MessageModel::modelAboutToBeReset, this, [this]() {
|
connect(this, &MessageModel::modelAboutToReset, this, [this]() {
|
||||||
resetting = true;
|
m_resetting = true;
|
||||||
});
|
});
|
||||||
connect(this, &MessageModel::modelReset, this, [this]() {
|
connect(this, &MessageModel::modelReset, this, [this]() {
|
||||||
resetting = false;
|
m_resetting = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &MessageModel::threadsEnabledChanged, this, [this]() {
|
connect(this, &MessageModel::threadsEnabledChanged, this, [this]() {
|
||||||
Q_EMIT modelAboutToBeReset();
|
Q_EMIT dataChanged(index(0), index(rowCount() - 1), {IsThreadedRole});
|
||||||
beginResetModel();
|
|
||||||
endResetModel();
|
|
||||||
Q_EMIT modelResetComplete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,17 +57,25 @@ void MessageModel::setRoom(NeoChatRoom *room)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto oldRoom = m_room;
|
||||||
|
Q_EMIT roomAboutToChange(oldRoom, room);
|
||||||
clearModel();
|
clearModel();
|
||||||
|
|
||||||
Q_EMIT modelAboutToBeReset();
|
if (!m_resetting) {
|
||||||
beginResetModel();
|
m_resetting = true;
|
||||||
|
Q_EMIT modelAboutToReset();
|
||||||
|
beginResetModel();
|
||||||
|
}
|
||||||
m_room = room;
|
m_room = room;
|
||||||
if (m_room != nullptr) {
|
if (m_room != nullptr) {
|
||||||
m_room->setVisible(true);
|
m_room->setVisible(true);
|
||||||
}
|
}
|
||||||
Q_EMIT roomChanged();
|
if (m_resetting) {
|
||||||
endResetModel();
|
endResetModel();
|
||||||
Q_EMIT modelResetComplete();
|
Q_EMIT modelResetComplete();
|
||||||
|
m_resetting = false;
|
||||||
|
}
|
||||||
|
Q_EMIT roomChanged(oldRoom, m_room);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MessageModel::timelineServerIndex() const
|
int MessageModel::timelineServerIndex() const
|
||||||
@@ -444,7 +449,7 @@ void MessageModel::createEventObjects(const Quotient::RoomEvent *event)
|
|||||||
// If a model already exists but now has no reactions remove it
|
// If a model already exists but now has no reactions remove it
|
||||||
if (m_readMarkerModels[eventId]->rowCount() <= 0) {
|
if (m_readMarkerModels[eventId]->rowCount() <= 0) {
|
||||||
m_readMarkerModels.remove(eventId);
|
m_readMarkerModels.remove(eventId);
|
||||||
if (!resetting) {
|
if (!m_resetting) {
|
||||||
refreshEventRoles(eventId, {ReadMarkersRole, ShowReadMarkersRole});
|
refreshEventRoles(eventId, {ReadMarkersRole, ShowReadMarkersRole});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,7 +461,7 @@ void MessageModel::createEventObjects(const Quotient::RoomEvent *event)
|
|||||||
auto newModel = QSharedPointer<ReadMarkerModel>(new ReadMarkerModel(eventId, m_room));
|
auto newModel = QSharedPointer<ReadMarkerModel>(new ReadMarkerModel(eventId, m_room));
|
||||||
if (newModel->rowCount() > 0) {
|
if (newModel->rowCount() > 0) {
|
||||||
m_readMarkerModels[eventId] = newModel;
|
m_readMarkerModels[eventId] = newModel;
|
||||||
if (!resetting) {
|
if (!m_resetting) {
|
||||||
refreshEventRoles(eventId, {ReadMarkersRole, ShowReadMarkersRole});
|
refreshEventRoles(eventId, {ReadMarkersRole, ShowReadMarkersRole});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -512,12 +517,18 @@ void MessageModel::clearModel()
|
|||||||
|
|
||||||
// HACK: Reset the model to a null room first to make sure QML dismantles
|
// HACK: Reset the model to a null room first to make sure QML dismantles
|
||||||
// last room's objects before the room is actually changed
|
// last room's objects before the room is actually changed
|
||||||
Q_EMIT modelAboutToBeReset();
|
if (!m_resetting) {
|
||||||
beginResetModel();
|
m_resetting = true;
|
||||||
|
Q_EMIT modelAboutToReset();
|
||||||
|
beginResetModel();
|
||||||
|
}
|
||||||
m_room->disconnect(this);
|
m_room->disconnect(this);
|
||||||
m_room = nullptr;
|
m_room = nullptr;
|
||||||
endResetModel();
|
if (m_resetting) {
|
||||||
Q_EMIT modelResetComplete();
|
endResetModel();
|
||||||
|
Q_EMIT modelResetComplete();
|
||||||
|
m_resetting = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Because we don't want any of the object deleted before the model is cleared.
|
// Because we don't want any of the object deleted before the model is cleared.
|
||||||
oldRoom->setVisible(false);
|
oldRoom->setVisible(false);
|
||||||
|
|||||||
@@ -125,7 +125,12 @@ Q_SIGNALS:
|
|||||||
/**
|
/**
|
||||||
* @brief Emitted when the room is changed.
|
* @brief Emitted when the room is changed.
|
||||||
*/
|
*/
|
||||||
void roomChanged();
|
void roomAboutToChange(NeoChatRoom *oldRoom, NeoChatRoom *newRoom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Emitted when the room is changed.
|
||||||
|
*/
|
||||||
|
void roomChanged(NeoChatRoom *oldRoom, NeoChatRoom *newRoom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Emitted when the reader marker is added.
|
* @brief Emitted when the reader marker is added.
|
||||||
@@ -140,7 +145,7 @@ Q_SIGNALS:
|
|||||||
/**
|
/**
|
||||||
* @brief Emitted when the model is about to reset.
|
* @brief Emitted when the model is about to reset.
|
||||||
*/
|
*/
|
||||||
void modelAboutToBeReset();
|
void modelAboutToReset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Emitted when the model has been reset.
|
* @brief Emitted when the model has been reset.
|
||||||
@@ -169,6 +174,9 @@ protected:
|
|||||||
virtual int timelineServerIndex() const;
|
virtual int timelineServerIndex() const;
|
||||||
virtual std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const;
|
virtual std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const;
|
||||||
|
|
||||||
|
bool m_resetting = false;
|
||||||
|
bool m_movingEvent = false;
|
||||||
|
|
||||||
void fullEventRefresh(int row);
|
void fullEventRefresh(int row);
|
||||||
int refreshEventRoles(const QString &eventId, const QList<int> &roles = {});
|
int refreshEventRoles(const QString &eventId, const QList<int> &roles = {});
|
||||||
void refreshEventRoles(int row, const QList<int> &roles = {});
|
void refreshEventRoles(int row, const QList<int> &roles = {});
|
||||||
@@ -182,9 +190,6 @@ protected:
|
|||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool resetting = false;
|
|
||||||
bool movingEvent = false;
|
|
||||||
|
|
||||||
QMap<QString, QSharedPointer<ReadMarkerModel>> m_readMarkerModels;
|
QMap<QString, QSharedPointer<ReadMarkerModel>> m_readMarkerModels;
|
||||||
|
|
||||||
void createEventObjects(const Quotient::RoomEvent *event);
|
void createEventObjects(const Quotient::RoomEvent *event);
|
||||||
|
|||||||
@@ -28,12 +28,16 @@ void TimelineMessageModel::connectNewRoom()
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(m_room, &Room::aboutToAddNewMessages, this, [this](RoomEventsRange events) {
|
connect(m_room, &Room::aboutToAddNewMessages, this, [this](RoomEventsRange events) {
|
||||||
m_initialized = true;
|
if (!m_resetting) {
|
||||||
beginInsertRows({}, timelineServerIndex(), timelineServerIndex() + int(events.size()) - 1);
|
m_initialized = true;
|
||||||
|
beginInsertRows({}, timelineServerIndex(), timelineServerIndex() + int(events.size()) - 1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
connect(m_room, &Room::aboutToAddHistoricalMessages, this, [this](RoomEventsRange events) {
|
connect(m_room, &Room::aboutToAddHistoricalMessages, this, [this](RoomEventsRange events) {
|
||||||
m_initialized = true;
|
if (!m_resetting) {
|
||||||
beginInsertRows({}, rowCount(), rowCount() + int(events.size()) - 1);
|
m_initialized = true;
|
||||||
|
beginInsertRows({}, rowCount(), rowCount() + int(events.size()) - 1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
connect(m_room, &Room::addedMessages, this, [this](int lowest, int biggest) {
|
connect(m_room, &Room::addedMessages, this, [this](int lowest, int biggest) {
|
||||||
if (m_initialized) {
|
if (m_initialized) {
|
||||||
@@ -58,17 +62,21 @@ void TimelineMessageModel::connectNewRoom()
|
|||||||
});
|
});
|
||||||
#if Quotient_VERSION_MINOR > 9 || (Quotient_VERSION_MINOR == 9 && Quotient_VERSION_PATCH > 0)
|
#if Quotient_VERSION_MINOR > 9 || (Quotient_VERSION_MINOR == 9 && Quotient_VERSION_PATCH > 0)
|
||||||
connect(m_room, &Room::pendingEventAdded, this, [this](const Quotient::RoomEvent *event) {
|
connect(m_room, &Room::pendingEventAdded, this, [this](const Quotient::RoomEvent *event) {
|
||||||
m_initialized = true;
|
|
||||||
Q_EMIT newEventAdded(event);
|
Q_EMIT newEventAdded(event);
|
||||||
Q_EMIT newLocalUserEventAdded();
|
Q_EMIT newLocalUserEventAdded();
|
||||||
beginInsertRows({}, 0, 0);
|
if (!m_resetting) {
|
||||||
endInsertRows();
|
beginInsertRows({}, 0, 0);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
connect(m_room, &Room::pendingEventAboutToAdd, this, [this](Quotient::RoomEvent *event) {
|
connect(m_room, &Room::pendingEventAboutToAdd, this, [this](Quotient::RoomEvent *event) {
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
Q_EMIT newEventAdded(event);
|
Q_EMIT newEventAdded(event);
|
||||||
beginInsertRows({}, 0, 0);
|
if (!m_resetting) {
|
||||||
|
beginInsertRows({}, 0, 0);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
connect(m_room, &Room::pendingEventAdded, this, &TimelineMessageModel::endInsertRows);
|
connect(m_room, &Room::pendingEventAdded, this, &TimelineMessageModel::endInsertRows);
|
||||||
#endif
|
#endif
|
||||||
@@ -78,15 +86,15 @@ void TimelineMessageModel::connectNewRoom()
|
|||||||
return; // No need to move anything, just refresh
|
return; // No need to move anything, just refresh
|
||||||
}
|
}
|
||||||
|
|
||||||
movingEvent = true;
|
m_movingEvent = true;
|
||||||
// Reverse i because row 0 is bottommost in the model
|
// Reverse i because row 0 is bottommost in the model
|
||||||
const auto row = timelineServerIndex() - i - 1;
|
const auto row = timelineServerIndex() - i - 1;
|
||||||
beginMoveRows({}, row, row, {}, timelineServerIndex());
|
beginMoveRows({}, row, row, {}, timelineServerIndex());
|
||||||
});
|
});
|
||||||
connect(m_room, &Room::pendingEventMerged, this, [this] {
|
connect(m_room, &Room::pendingEventMerged, this, [this] {
|
||||||
if (movingEvent) {
|
if (m_movingEvent) {
|
||||||
endMoveRows();
|
endMoveRows();
|
||||||
movingEvent = false;
|
m_movingEvent = false;
|
||||||
}
|
}
|
||||||
fullEventRefresh(timelineServerIndex());
|
fullEventRefresh(timelineServerIndex());
|
||||||
refreshLastUserEvents(0);
|
refreshLastUserEvents(0);
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ private:
|
|||||||
std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const override;
|
std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const override;
|
||||||
|
|
||||||
int rowBelowInserted = -1;
|
int rowBelowInserted = -1;
|
||||||
bool resetting = false;
|
|
||||||
bool movingEvent = false;
|
|
||||||
|
|
||||||
int timelineServerIndex() const override;
|
int timelineServerIndex() const override;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user