Alter code structure && change room list filtering mechanics && add
sorting && init categoriy for rooms.
This commit is contained in:
parent
a1941784eb
commit
d44383545a
|
@ -1,3 +0,0 @@
|
||||||
[submodule "matrix/libqmatrixclient"]
|
|
||||||
path = matrix/libqmatrixclient
|
|
||||||
url = https://github.com/QMatrixClient/libqmatrixclient
|
|
26
matrique.pro
26
matrique.pro
|
@ -1,7 +1,9 @@
|
||||||
QT += quick
|
QT += quick
|
||||||
CONFIG += c++14
|
CONFIG += c++14
|
||||||
|
CONFIG += object_parallel_to_source
|
||||||
|
|
||||||
include(matrix/libqmatrixclient/libqmatrixclient.pri)
|
include(include/SortFilterProxyModel/SortFilterProxyModel.pri)
|
||||||
|
include(include/libqmatrixclient/libqmatrixclient.pri)
|
||||||
|
|
||||||
# The following define makes your compiler emit warnings if you use
|
# The following define makes your compiler emit warnings if you use
|
||||||
# any feature of Qt which as been marked deprecated (the exact warnings
|
# any feature of Qt which as been marked deprecated (the exact warnings
|
||||||
|
@ -14,12 +16,12 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
matrix/controller.cpp \
|
src/controller.cpp \
|
||||||
matrix/roomlistmodel.cpp \
|
src/roomlistmodel.cpp \
|
||||||
matrix/imageprovider.cpp \
|
src/imageprovider.cpp \
|
||||||
matrix/messageeventmodel.cpp \
|
src/messageeventmodel.cpp \
|
||||||
matrix/imageproviderconnection.cpp
|
src/imageproviderconnection.cpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
res.qrc
|
res.qrc
|
||||||
|
@ -51,8 +53,8 @@ DISTFILES += \
|
||||||
qml/js/md.js
|
qml/js/md.js
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
matrix/controller.h \
|
src/controller.h \
|
||||||
matrix/roomlistmodel.h \
|
src/roomlistmodel.h \
|
||||||
matrix/imageprovider.h \
|
src/imageprovider.h \
|
||||||
matrix/messageeventmodel.h \
|
src/messageeventmodel.h \
|
||||||
matrix/imageproviderconnection.h
|
src/imageproviderconnection.h
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit e66cae5fd3e74c5839804e560332e5690709931a
|
|
|
@ -18,7 +18,7 @@ Page {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
ListForm {
|
RoomListForm {
|
||||||
id: roomListForm
|
id: roomListForm
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
|
@ -19,12 +19,9 @@ Item {
|
||||||
background: Item {
|
background: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: !currentRoom
|
visible: !currentRoom
|
||||||
Pane {
|
Pane { anchors.fill: parent }
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
z: 10
|
|
||||||
text: "Please choose a room."
|
text: "Please choose a room."
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
@ -43,9 +40,7 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 80
|
Layout.preferredHeight: 80
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle { color: Material.theme == Material.Light ? "#eaeaea" : "#242424" }
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -97,14 +92,12 @@ Item {
|
||||||
id: messageEventModel
|
id: messageEventModel
|
||||||
room: currentRoom
|
room: currentRoom
|
||||||
|
|
||||||
onRoomChanged: {
|
onRoomChanged: room.timelineSize === 0 ? room.getPreviousContent(50) : {}
|
||||||
if (room.timelineSize === 0) room.getPreviousContent(50)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: MessageDelegate {}
|
delegate: MessageDelegate {}
|
||||||
|
|
||||||
onAtYBeginningChanged: if (atYBeginning && currentRoom) currentRoom.getPreviousContent(50)
|
onAtYBeginningChanged: atYBeginning && currentRoom ? currentRoom.getPreviousContent(50) : {}
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {}
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
|
@ -128,9 +121,7 @@ Item {
|
||||||
|
|
||||||
onClicked: parent.positionViewAtBeginning()
|
onClicked: parent.positionViewAtBeginning()
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity { NumberAnimation { duration: 200 } }
|
||||||
PropertyAnimation { easing.type: Easing.Linear; duration: 200 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +165,7 @@ Item {
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle { color: Material.theme == Material.Light ? "#eaeaea" : "#242424" }
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
if (inputField.text) {
|
if (inputField.text) {
|
||||||
|
@ -240,9 +229,7 @@ Item {
|
||||||
|
|
||||||
contentItem: MaterialIcon { icon: "\ue24e" }
|
contentItem: MaterialIcon { icon: "\ue24e" }
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle { color: Material.theme == Material.Light ? "#eaeaea" : "#242424" }
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,127 @@ import QtGraphicalEffects 1.0
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import QtQml.Models 2.3
|
import QtQml.Models 2.3
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import "qrc:/qml/component"
|
import "qrc:/qml/component"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias listModel: delegateModel.model
|
property alias listModel: roomListProxyModel.sourceModel
|
||||||
property alias currentIndex: listView.currentIndex
|
property alias currentIndex: listView.currentIndex
|
||||||
readonly property bool mini: width <= 80 // Used as an indicator of whether the listform should be displayed as "Mini mode".
|
readonly property bool mini: width <= 80 // Used as an indicator of whether the listform should be displayed as "Mini mode".
|
||||||
|
|
||||||
DelegateModel {
|
ColumnLayout {
|
||||||
id: delegateModel
|
anchors.fill: parent
|
||||||
groups: [
|
spacing: 0
|
||||||
DelegateModelGroup {
|
|
||||||
name: "filterGroup"; includeByDefault: true
|
Pane {
|
||||||
|
z: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 80
|
||||||
|
background: Rectangle {
|
||||||
|
color: Qt.tint(Material.accent, "#20FFFFFF")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: searchField
|
||||||
|
width: parent.width
|
||||||
|
height: 36
|
||||||
|
leftPadding: mini ? 4 : 16
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
icon: "\ue8b6"
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
width: mini ? parent.width : parent.height
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
height: parent.height
|
||||||
|
visible: !mini
|
||||||
|
text: "Search"
|
||||||
|
color: "white"
|
||||||
|
font.pointSize: 12
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: searchField.activeFocus || searchField.text ? parent.width : 0
|
||||||
|
height: parent.height
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
z: 10
|
||||||
|
text: mini ? "Empty" : "Here? No, not here."
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: listView.count === 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SortFilterProxyModel {
|
||||||
|
id: roomListProxyModel
|
||||||
|
filters: RegExpFilter {
|
||||||
|
roleName: "name"
|
||||||
|
pattern: searchField.text
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
|
}
|
||||||
|
proxyRoles: [
|
||||||
|
ExpressionRole { name: "isFavorite"; expression: category === "Favorites" },
|
||||||
|
ExpressionRole { name: "isLowPriority"; expression: category === "Low Priorities" }
|
||||||
]
|
]
|
||||||
filterOnGroup: "filterGroup"
|
sorters: [
|
||||||
|
RoleSorter { roleName: "isFavorite"; sortOrder: Qt.DescendingOrder },
|
||||||
|
RoleSorter { roleName: "isLowPriority" },
|
||||||
|
StringSorter { roleName: "name" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listView
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
model: roomListProxyModel
|
||||||
|
|
||||||
|
highlight: Rectangle {
|
||||||
|
color: Material.accent
|
||||||
|
opacity: 0.2
|
||||||
|
}
|
||||||
|
highlightMoveDuration: 250
|
||||||
|
|
||||||
|
currentIndex: -1
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar { id: scrollBar }
|
||||||
|
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -81,114 +186,12 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyFilter(filterName){
|
section.property: "category"
|
||||||
var roomCount = listModel.rowCount();
|
section.criteria: ViewSection.FullString
|
||||||
for (var i = 0; i < roomCount; i++){
|
section.delegate: Rectangle {
|
||||||
var roomName = listModel.roomAt(i).displayName;
|
|
||||||
if (roomName.toLowerCase().indexOf(filterName.toLowerCase()) !== -1) {
|
|
||||||
items.addGroups(i, 1, "filterGroup");
|
|
||||||
} else {items.removeGroups(i, 1, "filterGroup");}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Pane {
|
|
||||||
z: 10
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 80
|
|
||||||
background: Rectangle {
|
|
||||||
color: Qt.tint(Material.accent, "#20FFFFFF")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: searchField
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 36
|
height: 16
|
||||||
leftPadding: mini ? 4 : 16
|
}
|
||||||
topPadding: 0
|
|
||||||
bottomPadding: 0
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
background: Item {
|
|
||||||
Row {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
icon: "\ue8b6"
|
|
||||||
color: "white"
|
|
||||||
|
|
||||||
width: mini ? parent.width : parent.height
|
|
||||||
height: parent.height
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
height: parent.height
|
|
||||||
visible: !mini
|
|
||||||
text: "Search"
|
|
||||||
color: "white"
|
|
||||||
font.pointSize: 12
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: searchField.activeFocus || searchField.text ? parent.width : 0
|
|
||||||
height: parent.height
|
|
||||||
color: "white"
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextChanged: {
|
|
||||||
delegateModel.applyFilter(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pane {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
background: Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
z: 10
|
|
||||||
text: mini ? "Empty" : "Here? No, not here."
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: listView.count === 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: listView
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
highlight: Rectangle {
|
|
||||||
color: Material.accent
|
|
||||||
opacity: 0.2
|
|
||||||
}
|
|
||||||
highlightMoveDuration: 250
|
|
||||||
|
|
||||||
currentIndex: -1
|
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar { id: scrollBar }
|
|
||||||
|
|
||||||
model: delegateModel
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
2
res.qrc
2
res.qrc
|
@ -12,7 +12,6 @@
|
||||||
<file>qml/form/RoomForm.qml</file>
|
<file>qml/form/RoomForm.qml</file>
|
||||||
<file>qml/Room.qml</file>
|
<file>qml/Room.qml</file>
|
||||||
<file>qml/form/DetailForm.qml</file>
|
<file>qml/form/DetailForm.qml</file>
|
||||||
<file>qml/form/ListForm.qml</file>
|
|
||||||
<file>qml/component/SideNavButton.qml</file>
|
<file>qml/component/SideNavButton.qml</file>
|
||||||
<file>qml/component/MaterialIcon.qml</file>
|
<file>qml/component/MaterialIcon.qml</file>
|
||||||
<file>asset/img/icon.png</file>
|
<file>asset/img/icon.png</file>
|
||||||
|
@ -24,5 +23,6 @@
|
||||||
<file>qml/component/DownloadableContent.qml</file>
|
<file>qml/component/DownloadableContent.qml</file>
|
||||||
<file>qml/component/FileBubble.qml</file>
|
<file>qml/component/FileBubble.qml</file>
|
||||||
<file>qml/component/AvatarContainer.qml</file>
|
<file>qml/component/AvatarContainer.qml</file>
|
||||||
|
<file>qml/form/RoomListForm.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
|
||||||
#include "matrix/controller.h"
|
#include "controller.h"
|
||||||
#include "matrix/imageprovider.h"
|
#include "imageprovider.h"
|
||||||
#include "matrix/messageeventmodel.h"
|
#include "messageeventmodel.h"
|
||||||
#include "matrix/roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
|
@ -21,7 +21,8 @@ void RoomListModel::setConnection(QMatrixClient::Connection* connection) {
|
||||||
// &RoomListModel::updateRoom);
|
// &RoomListModel::updateRoom);
|
||||||
// connect(connection, &Connection::joinedRoom, this,
|
// connect(connection, &Connection::joinedRoom, this,
|
||||||
// &RoomListModel::updateRoom);
|
// &RoomListModel::updateRoom);
|
||||||
// connect(connection, &Connection::leftRoom, this, &RoomListModel::updateRoom);
|
// connect(connection, &Connection::leftRoom, this,
|
||||||
|
// &RoomListModel::updateRoom);
|
||||||
connect(connection, &Connection::aboutToDeleteRoom, this,
|
connect(connection, &Connection::aboutToDeleteRoom, this,
|
||||||
&RoomListModel::deleteRoom);
|
&RoomListModel::deleteRoom);
|
||||||
|
|
||||||
|
@ -61,22 +62,27 @@ QVariant RoomListModel::data(const QModelIndex& index, int role) const {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
QMatrixClient::Room* room = m_rooms.at(index.row());
|
QMatrixClient::Room* room = m_rooms.at(index.row());
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == NameRole) {
|
||||||
return room->displayName();
|
return room->displayName();
|
||||||
}
|
}
|
||||||
if (role == Qt::ForegroundRole) {
|
if (role == AvatarRole) {
|
||||||
if (room->highlightCount() > 0) return QBrush(QColor("orange"));
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
if (role == Qt::DecorationRole) {
|
|
||||||
if (room->avatarUrl().toString() != "") {
|
if (room->avatarUrl().toString() != "") {
|
||||||
return room->avatarUrl();
|
return room->avatarUrl();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
if (role == Qt::StatusTipRole) {
|
if (role == TopicRole) {
|
||||||
return room->topic();
|
return room->topic();
|
||||||
}
|
}
|
||||||
|
if (role == CategoryRole) {
|
||||||
|
if (room->isFavourite()) return "Favorites";
|
||||||
|
if (room->isLowPriority()) return "Low Priorities";
|
||||||
|
return "Rooms";
|
||||||
|
}
|
||||||
|
if (role == HighlightRole) {
|
||||||
|
if (room->highlightCount() > 0) return QBrush(QColor("orange"));
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +98,10 @@ void RoomListModel::unreadMessagesChanged(QMatrixClient::Room* room) {
|
||||||
|
|
||||||
QHash<int, QByteArray> RoomListModel::roleNames() const {
|
QHash<int, QByteArray> RoomListModel::roleNames() const {
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles[Qt::DisplayRole] = "name";
|
roles[NameRole] = "name";
|
||||||
roles[Qt::DecorationRole] = "avatar";
|
roles[AvatarRole] = "avatar";
|
||||||
roles[Qt::StatusTipRole] = "topic";
|
roles[TopicRole] = "topic";
|
||||||
|
roles[CategoryRole] = "category";
|
||||||
|
roles[HighlightRole] = "highlight";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
|
@ -11,6 +11,14 @@ class RoomListModel : public QAbstractListModel {
|
||||||
setConnection)
|
setConnection)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum EventRoles {
|
||||||
|
NameRole = Qt::UserRole + 1,
|
||||||
|
AvatarRole,
|
||||||
|
TopicRole,
|
||||||
|
CategoryRole,
|
||||||
|
HighlightRole,
|
||||||
|
};
|
||||||
|
|
||||||
RoomListModel(QObject* parent = 0);
|
RoomListModel(QObject* parent = 0);
|
||||||
virtual ~RoomListModel();
|
virtual ~RoomListModel();
|
||||||
|
|
Loading…
Reference in New Issue