Files
neochat/src/timeline/models/timelinemodel.cpp
James Graham 7e6b79d5d4 Release threads removing the feature flag.
This mr performs some final cleanup to make sure the threads are sized correctly and it all works with the new chatbar
2026-02-16 11:16:32 -05:00

191 lines
4.6 KiB
C++

// SPDX-FileCopyrightText: 2022 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 "timelinemodel.h"
#include <Quotient/qt_connection_util.h>
#include "enums/delegatetype.h"
TimelineModel::TimelineModel(QObject *parent)
: QConcatenateTablesProxyModel(parent)
{
m_timelineBeginningModel = new TimelineBeginningModel(this);
addSourceModel(m_timelineBeginningModel);
m_timelineMessageModel = new TimelineMessageModel(this);
addSourceModel(m_timelineMessageModel);
m_timelineEndModel = new TimelineEndModel(this);
addSourceModel(m_timelineEndModel);
}
NeoChatRoom *TimelineModel::room() const
{
return m_timelineMessageModel->room();
}
void TimelineModel::setRoom(NeoChatRoom *room)
{
// Both models do their own null checking so just pass along.
m_timelineMessageModel->setRoom(room);
m_timelineBeginningModel->setRoom(room);
m_timelineEndModel->setRoom(room);
}
TimelineMessageModel *TimelineModel::timelineMessageModel() const
{
return m_timelineMessageModel;
}
QHash<int, QByteArray> TimelineModel::roleNames() const
{
return m_timelineMessageModel->roleNames();
}
bool TimelineModel::canFetchMore(const QModelIndex &parent) const
{
if (!m_timelineMessageModel) {
return false;
}
return m_timelineMessageModel->canFetchMore(parent);
}
void TimelineModel::fetchMore(const QModelIndex &parent)
{
if (!m_timelineMessageModel) {
return;
}
return m_timelineMessageModel->fetchMore(parent);
}
TimelineBeginningModel::TimelineBeginningModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void TimelineBeginningModel::setRoom(NeoChatRoom *room)
{
if (room == m_room) {
return;
}
beginResetModel();
if (m_room != nullptr) {
m_room->disconnect(this);
}
m_room = room;
if (m_room != nullptr) {
Quotient::connectUntil(m_room.get(), &Quotient::Room::eventsHistoryJobChanged, this, [this]() {
if (m_room && m_room->allHistoryLoaded()) {
// HACK: We have to do it this way because DelegateChooser doesn't update dynamically.
beginRemoveRows({}, 0, 0);
endRemoveRows();
beginInsertRows({}, 0, 0);
endInsertRows();
return true;
}
return false;
});
}
endResetModel();
}
QVariant TimelineBeginningModel::data(const QModelIndex &idx, int role) const
{
if (m_room == nullptr) {
return {};
}
if (role == DelegateTypeRole) {
if (idx.row() == 0) {
return DelegateType::Spacer;
}
return DelegateType::Successor;
}
return {};
}
int TimelineBeginningModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
if (m_room == nullptr) {
return 1;
}
return m_room->successorId().isEmpty() ? 1 : 2;
}
QHash<int, QByteArray> TimelineBeginningModel::roleNames() const
{
return {{DelegateTypeRole, "delegateType"}};
}
TimelineEndModel::TimelineEndModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void TimelineEndModel::setRoom(NeoChatRoom *room)
{
if (room == m_room) {
return;
}
beginResetModel();
if (m_room != nullptr) {
m_room->disconnect(this);
}
m_room = room;
if (m_room != nullptr) {
connect(m_room, &Quotient::Room::eventsHistoryJobChanged, this, [this]() {
if (m_room->allHistoryLoaded()) {
// HACK: We have to do it this way because DelegateChooser doesn't update dynamically.
beginRemoveRows({}, 0, 0);
endRemoveRows();
beginInsertRows({}, 0, 0);
endInsertRows();
}
});
}
endResetModel();
}
QVariant TimelineEndModel::data(const QModelIndex &idx, int role) const
{
Q_UNUSED(idx)
if (m_room == nullptr) {
return {};
}
if (role == DelegateTypeRole) {
if (idx.row() == 1 || rowCount() == 1) {
return m_room->allHistoryLoaded() ? DelegateType::TimelineEnd : DelegateType::Loading;
} else {
return DelegateType::Predecessor;
}
}
return {};
}
int TimelineEndModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
if (m_room == nullptr) {
return 1;
}
return m_room->predecessorId().isEmpty() ? 1 : (m_room->allHistoryLoaded() ? 2 : 1);
}
QHash<int, QByteArray> TimelineEndModel::roleNames() const
{
return {{DelegateTypeRole, "delegateType"}};
}
#include "moc_timelinemodel.cpp"