The intention is that NeochatRoomMember can be created passed to QML and then be fully managed by it. It effectively just grabs the current RoomMember, calls the correct function then discards it so that we don't end up trying to access an already deleted state event. (cherry picked from commit11fd4f88ec)a2a8ad09Create NeochatRoomMember as a shim for RoomMember so it can be safely passed to QML0867eef5Fix showAuthor0f72ccd0Mamange the creation of NeochatRoomMembers and only create one per member rather than event.dba88fe2REmove getAuthor as no longer needed4e3a61d1Update include32d4d9f7Pass NeochatRoomMembers rather than RoomMembers to menus8e4b2034Don't leak memoryc2f2bb26Fix code component regression.5aee89beMake sure the sender Id is intialised properly for pending eventsc10c2677Tweak intialisationb3146034Make sure event objects are created for new pending eventse4fab6d9Pass an empty NeochatRoomMember when not in the map Co-authored-by: James Graham <james.h.graham@protonmail.com>
204 lines
5.4 KiB
C++
204 lines
5.4 KiB
C++
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
|
|
#include "searchmodel.h"
|
|
|
|
#include "enums/delegatetype.h"
|
|
#include "eventhandler.h"
|
|
#include "models/messagecontentmodel.h"
|
|
#include "neochatroom.h"
|
|
#include "neochatroommember.h"
|
|
|
|
#include <QGuiApplication>
|
|
|
|
#include <Quotient/events/stickerevent.h>
|
|
|
|
#include <KLocalizedString>
|
|
|
|
using namespace Quotient;
|
|
|
|
// TODO search only in the current room
|
|
|
|
SearchModel::SearchModel(QObject *parent)
|
|
: QAbstractListModel(parent)
|
|
{
|
|
}
|
|
|
|
QString SearchModel::searchText() const
|
|
{
|
|
return m_searchText;
|
|
}
|
|
|
|
void SearchModel::setSearchText(const QString &searchText)
|
|
{
|
|
m_searchText = searchText;
|
|
Q_EMIT searchTextChanged();
|
|
}
|
|
|
|
void SearchModel::search()
|
|
{
|
|
Q_ASSERT(m_room);
|
|
setSearching(true);
|
|
if (m_job) {
|
|
m_job->abandon();
|
|
m_job = nullptr;
|
|
}
|
|
|
|
RoomEventFilter filter;
|
|
filter.unreadThreadNotifications = std::nullopt;
|
|
filter.lazyLoadMembers = true;
|
|
filter.includeRedundantMembers = false;
|
|
filter.notRooms = QStringList();
|
|
filter.rooms = QStringList{m_room->id()};
|
|
filter.containsUrl = false;
|
|
|
|
SearchJob::RoomEventsCriteria criteria{
|
|
.searchTerm = m_searchText,
|
|
.keys = {},
|
|
.filter = filter,
|
|
.orderBy = "recent"_ls,
|
|
.eventContext = SearchJob::IncludeEventContext{3, 3, true},
|
|
.includeState = false,
|
|
.groupings = std::nullopt,
|
|
|
|
};
|
|
|
|
auto job = m_room->connection()->callApi<SearchJob>(SearchJob::Categories{criteria});
|
|
m_job = job;
|
|
connect(job, &BaseJob::finished, this, [this, job] {
|
|
beginResetModel();
|
|
m_memberObjects.clear();
|
|
m_result = job->searchCategories().roomEvents;
|
|
|
|
if (m_result.has_value()) {
|
|
for (const auto &result : m_result.value().results) {
|
|
if (!m_memberObjects.contains(result.result->senderId())) {
|
|
m_memberObjects[result.result->senderId()] = std::unique_ptr<NeochatRoomMember>(new NeochatRoomMember(m_room, result.result->senderId()));
|
|
}
|
|
}
|
|
}
|
|
|
|
endResetModel();
|
|
setSearching(false);
|
|
m_job = nullptr;
|
|
// TODO error handling
|
|
});
|
|
}
|
|
|
|
QVariant SearchModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
auto row = index.row();
|
|
const auto &event = *m_result->results[row].result;
|
|
|
|
EventHandler eventHandler(m_room, &event);
|
|
|
|
switch (role) {
|
|
case AuthorRole:
|
|
return QVariant::fromValue<NeochatRoomMember *>(m_memberObjects.at(event.senderId()).get());
|
|
case ShowSectionRole:
|
|
if (row == 0) {
|
|
return true;
|
|
}
|
|
return event.originTimestamp().date() != m_result->results[row - 1].result->originTimestamp().date();
|
|
case SectionRole:
|
|
return eventHandler.getTimeString(true);
|
|
case ShowReactionsRole:
|
|
return false;
|
|
case ShowReadMarkersRole:
|
|
return false;
|
|
case IsPendingRole:
|
|
return false;
|
|
case HighlightRole:
|
|
return eventHandler.isHighlighted();
|
|
case EventIdRole:
|
|
return eventHandler.getId();
|
|
case IsThreadedRole:
|
|
return eventHandler.isThreaded();
|
|
case ThreadRootRole:
|
|
return eventHandler.threadRoot();
|
|
case ContentModelRole: {
|
|
if (!event.isStateEvent()) {
|
|
return QVariant::fromValue<MessageContentModel *>(new MessageContentModel(m_room, &event));
|
|
}
|
|
if (event.isStateEvent()) {
|
|
if (event.matrixType() == QStringLiteral("org.matrix.msc3672.beacon_info")) {
|
|
return QVariant::fromValue<MessageContentModel *>(new MessageContentModel(m_room, &event));
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
case IsEditableRole: {
|
|
return false;
|
|
}
|
|
}
|
|
return DelegateType::Message;
|
|
}
|
|
|
|
int SearchModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
Q_UNUSED(parent);
|
|
if (m_result.has_value()) {
|
|
return m_result->results.size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
QHash<int, QByteArray> SearchModel::roleNames() const
|
|
{
|
|
return {
|
|
{DelegateTypeRole, "delegateType"},
|
|
{AuthorRole, "author"},
|
|
{ShowSectionRole, "showSection"},
|
|
{SectionRole, "section"},
|
|
{EventIdRole, "eventId"},
|
|
{ExcessReadMarkersRole, "excessReadMarkers"},
|
|
{HighlightRole, "isHighlighted"},
|
|
{ReadMarkersString, "readMarkersString"},
|
|
{VerifiedRole, "verified"},
|
|
{ShowReactionsRole, "showReactions"},
|
|
{ReactionRole, "reaction"},
|
|
{ReadMarkersRole, "readMarkers"},
|
|
{IsPendingRole, "isPending"},
|
|
{ShowReadMarkersRole, "showReadMarkers"},
|
|
{IsThreadedRole, "isThreaded"},
|
|
{ThreadRootRole, "threadRoot"},
|
|
{ContentModelRole, "contentModel"},
|
|
{IsEditableRole, "isEditable"},
|
|
};
|
|
}
|
|
|
|
NeoChatRoom *SearchModel::room() const
|
|
{
|
|
return m_room;
|
|
}
|
|
|
|
void SearchModel::setRoom(NeoChatRoom *room)
|
|
{
|
|
if (m_room) {
|
|
disconnect(m_room, nullptr, this, nullptr);
|
|
}
|
|
m_room = room;
|
|
Q_EMIT roomChanged();
|
|
}
|
|
|
|
bool SearchModel::searching() const
|
|
{
|
|
return m_searching;
|
|
}
|
|
|
|
bool SearchModel::event(QEvent *event)
|
|
{
|
|
if (event->type() == QEvent::ApplicationPaletteChange) {
|
|
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), {AuthorRole, ReadMarkersRole});
|
|
}
|
|
return QObject::event(event);
|
|
}
|
|
|
|
void SearchModel::setSearching(bool searching)
|
|
{
|
|
m_searching = searching;
|
|
Q_EMIT searchingChanged();
|
|
}
|
|
|
|
#include "moc_searchmodel.cpp"
|