Implement sorting rooms by category

This commit is contained in:
Tobias Fella
2020-11-08 16:13:53 +00:00
parent da4aa0fa21
commit 95e2993f70
8 changed files with 149 additions and 13 deletions

View File

@@ -25,7 +25,7 @@ ecm_setup_version(0.1.0
)
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Widgets Core Quick Gui QuickControls2 Multimedia Svg)
find_package(KF5 ${REQUIRED_KF5_VERSION} REQUIRED COMPONENTS Kirigami2 ItemModels I18n Notifications Config CoreAddons)
find_package(KF5 ${REQUIRED_KF5_VERSION} REQUIRED COMPONENTS Kirigami2 I18n Notifications Config CoreAddons)
if(ANDROID)
find_package(OpenSSL REQUIRED)

View File

@@ -14,6 +14,8 @@ import org.kde.kitemmodels 1.0
import Spectral.Component 2.0
import Spectral 0.1
import org.kde.neochat 1.0
Kirigami.ScrollablePage {
id: page
@@ -21,7 +23,7 @@ Kirigami.ScrollablePage {
property var enteredRoom
property var searchText: ""
onSearchTextChanged: sortedFilteredRoomListModel.invalidateFilter()
onSearchTextChanged: sortFilterRoomListModel.setFilterText(searchText)
signal enterRoom(var room)
signal leaveRoom(var room)
@@ -37,23 +39,25 @@ Kirigami.ScrollablePage {
}
ListView {
model: KSortFilterProxyModel {
id: sortedFilteredRoomListModel
model: SortFilterRoomListModel {
id: sortFilterRoomListModel
sourceModel: roomListModel
roomSortOrder: SortFilterRoomListModel.Categories
}
sortRole: "name"
sortOrder: Qt.AscendingOrder
filterRowCallback: function(row, parent) {
return (roomListModel.data(roomListModel.index(row, 0), RoomListModel.JoinStateRole) !== "upgraded") && roomListModel.data(roomListModel.index(row, 0), RoomListModel.NameRole).toLowerCase().includes(page.searchText.toLowerCase())
section.property: "category"
section.delegate: Kirigami.ListSectionHeader {
id: sectionHeader
label: roomListModel.categoryName(section)
MouseArea {
Layout.fillWidth: true
Layout.fillHeight: true
onClicked: roomListModel.setCategoryVisible(section, !roomListModel.categoryVisible(section))
}
}
section.property: "categoryName"
section.delegate: Kirigami.ListSectionHeader {
label: section
}
delegate: Kirigami.AbstractListItem {
visible: model.categoryVisible
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing

View File

@@ -15,6 +15,7 @@ add_executable(neochat
utils.cpp
main.cpp
notificationsmanager.cpp
sortfilterroomlistmodel.cpp
../res.qrc
)

View File

@@ -30,6 +30,7 @@
#include "publicroomlistmodel.h"
#include "room.h"
#include "roomlistmodel.h"
#include "sortfilterroomlistmodel.h"
#include "spectralroom.h"
#include "spectraluser.h"
#include "trayicon.h"
@@ -70,6 +71,7 @@ int main(int argc, char *argv[])
qmlRegisterType<EmojiModel>("Spectral", 0, 1, "EmojiModel");
qmlRegisterType<NotificationsManager>("Spectral", 0, 1, "NotificationsManager");
qmlRegisterType<TrayIcon>("Spectral", 0, 1, "TrayIcon");
qmlRegisterType<SortFilterRoomListModel>("org.kde.neochat", 1, 0, "SortFilterRoomListModel");
qmlRegisterUncreatableType<RoomMessageEvent>("Spectral", 0, 1, "RoomMessageEvent", "ENUM");
qmlRegisterUncreatableType<RoomType>("Spectral", 0, 1, "RoomType", "ENUM");
qmlRegisterUncreatableType<UserType>("Spectral", 0, 1, "UserType", "ENUM");

View File

@@ -10,6 +10,8 @@
#include <QDebug>
#include <QStandardPaths>
#include <KLocalizedString>
RoomListModel::RoomListModel(QObject *parent)
: QAbstractListModel(parent)
{
@@ -249,6 +251,8 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
}
if (role == CurrentRoomRole)
return QVariant::fromValue(room);
if (role == CategoryVisibleRole)
return m_categoryVisibility.value(data(index, CategoryRole).toInt(), true);
return QVariant();
}
@@ -277,5 +281,36 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
roles[LastActiveTimeRole] = "lastActiveTime";
roles[JoinStateRole] = "joinState";
roles[CurrentRoomRole] = "currentRoom";
roles[CategoryVisibleRole] = "categoryVisible";
return roles;
}
QString RoomListModel::categoryName(int section) const
{
switch (section) {
case 1:
return i18n("Invited");
case 2:
return i18n("Favorite");
case 3:
return i18n("Direct Messages");
case 4:
return i18n("Normal");
case 5:
return i18n("Low priority");
default:
return i18n("Deadbeef");
}
}
void RoomListModel::setCategoryVisible(int category, bool visible)
{
beginResetModel();
m_categoryVisibility[category] = visible;
endResetModel();
}
bool RoomListModel::categoryVisible(int category) const
{
return m_categoryVisibility.value(category, true);
}

View File

@@ -44,6 +44,7 @@ public:
LastActiveTimeRole,
JoinStateRole,
CurrentRoomRole,
CategoryVisibleRole,
};
Q_ENUM(EventRoles)
@@ -64,6 +65,10 @@ public:
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE QString categoryName(int category) const;
Q_INVOKABLE void setCategoryVisible(int category, bool visible);
Q_INVOKABLE bool categoryVisible(int category) const;
int notificationCount() const
{
return m_notificationCount;
@@ -80,6 +85,8 @@ private:
Connection *m_connection = nullptr;
QList<SpectralRoom *> m_rooms;
QMap<int, bool> m_categoryVisibility;
int m_notificationCount = 0;
void connectRoomSignals(SpectralRoom *room);

View File

@@ -0,0 +1,46 @@
/**
* SPDX-FileCopyrightText: Tobias Fella <fella@posteo.de>
*
* SPDX-LicenseIdentifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "sortfilterroomlistmodel.h"
#include "roomlistmodel.h"
SortFilterRoomListModel::SortFilterRoomListModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
setFilterRole(RoomListModel::NameRole);
setFilterCaseSensitivity(Qt::CaseInsensitive);
sort(0);
}
void SortFilterRoomListModel::setRoomSortOrder(SortFilterRoomListModel::RoomSortOrder sortOrder)
{
m_sortOrder = sortOrder;
Q_EMIT roomSortOrderChanged();
if (sortOrder == SortFilterRoomListModel::Alphabetical)
setSortRole(RoomListModel::NameRole);
else if (sortOrder == SortFilterRoomListModel::LastActivity)
setSortRole(RoomListModel::LastActiveTimeRole);
}
SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder() const
{
return m_sortOrder;
}
bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (m_sortOrder != SortFilterRoomListModel::Categories)
return QSortFilterProxyModel::lessThan(source_left, source_right);
if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole))
return sourceModel()->data(source_left, RoomListModel::CategoryRole) < sourceModel()->data(source_right, RoomListModel::CategoryRole);
return sourceModel()->data(source_left, RoomListModel::NameRole) < sourceModel()->data(source_right, RoomListModel::NameRole);
}
void SortFilterRoomListModel::setFilterText(const QString &text)
{
setFilterFixedString(text);
}

View File

@@ -0,0 +1,41 @@
/**
* SPDX-FileCopyrightText: Tobias Fella <fella@posteo.de>
*
* SPDX-LicenseIdentifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <QSortFilterProxyModel>
class SortFilterRoomListModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(RoomSortOrder roomSortOrder READ roomSortOrder WRITE setRoomSortOrder NOTIFY roomSortOrderChanged)
Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)
public:
enum RoomSortOrder {
Alphabetical,
LastActivity,
Categories,
};
Q_ENUM(RoomSortOrder)
SortFilterRoomListModel(QObject *parent = nullptr);
void setRoomSortOrder(RoomSortOrder sortOrder);
RoomSortOrder roomSortOrder() const;
Q_INVOKABLE void setFilterText(const QString &text);
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
Q_SIGNALS:
void roomSortOrderChanged();
void sourceModelChanged();
private:
RoomSortOrder m_sortOrder;
};