summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeepBlueV7.X <nicolas.werner@hotmail.de>2021-02-19 14:03:42 +0000
committerGitHub <noreply@github.com>2021-02-19 14:03:42 +0000
commit99efe2f06b310a8d5398fcb7647b99c269872e4e (patch)
treed6f5f0734a6e06a15c96ed69f6afdbd61ea24732
parentMerge pull request #474 from Jedi18/room_settings_qml (diff)
parentcheck for empty alias and percent encoding for alias in url (diff)
downloadnheko-99efe2f06b310a8d5398fcb7647b99c269872e4e.tar.xz
Merge pull request #479 from Jedi18/add_rooms_model_completer
Add rooms completion model
-rw-r--r--CMakeLists.txt2
-rw-r--r--resources/qml/Completer.qml29
-rw-r--r--resources/qml/MessageInput.qml3
-rw-r--r--src/RoomsModel.cpp69
-rw-r--r--src/RoomsModel.h33
-rw-r--r--src/timeline/InputBar.cpp6
6 files changed, 142 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82850947..05e54380 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -326,6 +326,7 @@ set(SRC_FILES
 	src/UserInfoWidget.cpp
 	src/UserSettingsPage.cpp
 	src/UsersModel.cpp
+	src/RoomsModel.cpp
 	src/Utils.cpp
 	src/WebRTCSession.cpp
 	src/WelcomePage.cpp
@@ -537,6 +538,7 @@ qt5_wrap_cpp(MOC_HEADERS
 	src/UserInfoWidget.h
 	src/UserSettingsPage.h
 	src/UsersModel.h
+	src/RoomsModel.h
 	src/WebRTCSession.h
 	src/WelcomePage.h
 	src/popups/PopupItem.h
diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml
index 27322172..f77f50e9 100644
--- a/resources/qml/Completer.qml
+++ b/resources/qml/Completer.qml
@@ -154,6 +154,35 @@ Popup {
 
                 }
 
+                DelegateChoice {
+                    roleValue: "room"
+
+                    RowLayout {
+                        id: del
+
+                        anchors.centerIn: parent
+
+                        Avatar {
+                            height: 24
+                            width: 24
+                            url: model.avatarUrl.replace("mxc://", "image://MxcImage/")
+                            onClicked: popup.completionClicked(completer.completionAt(model.index))
+                        }
+
+                        Label {
+                            text: model.roomName
+                            color: model.index == popup.currentIndex ? colors.highlightedText : colors.text
+                        }
+
+                        Label {
+                            text: "(" + model.roomAlias + ")"
+                            color: model.index == popup.currentIndex ? colors.highlightedText : colors.buttonText
+                        }
+
+                    }
+
+                }
+
             }
 
         }
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index b5c96660..7ecaf81a 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -183,6 +183,9 @@ Rectangle {
                     } else if (event.key == Qt.Key_Colon) {
                         messageInput.openCompleter(cursorPosition, "emoji");
                         popup.open();
+                    } else if (event.key == Qt.Key_NumberSign) {
+                        messageInput.openCompleter(cursorPosition, "room");
+                        popup.open();
                     } else if (event.key == Qt.Key_Escape && popup.opened) {
                         completerTriggeredAt = -1;
                         popup.completerName = "";
diff --git a/src/RoomsModel.cpp b/src/RoomsModel.cpp
new file mode 100644
index 00000000..4286f87b
--- /dev/null
+++ b/src/RoomsModel.cpp
@@ -0,0 +1,69 @@
+#include "RoomsModel.h"
+
+#include <QUrl>
+
+#include "Cache_p.h"
+#include "CompletionModelRoles.h"
+
+RoomsModel::RoomsModel(bool showOnlyRoomWithAliases, QObject *parent)
+  : QAbstractListModel(parent)
+  , showOnlyRoomWithAliases_(showOnlyRoomWithAliases)
+{
+        std::vector<std::string> rooms_ = cache::joinedRooms();
+        roomInfos                       = cache::getRoomInfo(rooms_);
+
+        for (const auto &r : rooms_) {
+                auto roomAliasesList = cache::client()->getRoomAliases(r);
+
+                if (showOnlyRoomWithAliases_) {
+                        if (roomAliasesList && !roomAliasesList->alias.empty()) {
+                                roomids.push_back(QString::fromStdString(r));
+                                roomAliases.push_back(
+                                  QString::fromStdString(roomAliasesList->alias));
+                        }
+                } else {
+                        roomids.push_back(QString::fromStdString(r));
+                        roomAliases.push_back(
+                          roomAliasesList ? QString::fromStdString(roomAliasesList->alias) : "");
+                }
+        }
+}
+
+QHash<int, QByteArray>
+RoomsModel::roleNames() const
+{
+        return {{CompletionModel::CompletionRole, "completionRole"},
+                {CompletionModel::SearchRole, "searchRole"},
+                {CompletionModel::SearchRole2, "searchRole2"},
+                {Roles::RoomAlias, "roomAlias"},
+                {Roles::AvatarUrl, "avatarUrl"},
+                {Roles::RoomID, "roomid"},
+                {Roles::RoomName, "roomName"}};
+}
+
+QVariant
+RoomsModel::data(const QModelIndex &index, int role) const
+{
+        if (hasIndex(index.row(), index.column(), index.parent())) {
+                switch (role) {
+                case CompletionModel::CompletionRole: {
+                        QString percentEncoding = QUrl::toPercentEncoding(roomAliases[index.row()]);
+                        return QString("[%1](https://matrix.to/#/%2)")
+                          .arg(roomAliases[index.row()], percentEncoding);
+                }
+                case CompletionModel::SearchRole:
+                case Qt::DisplayRole:
+                case Roles::RoomAlias:
+                        return roomAliases[index.row()];
+                case CompletionModel::SearchRole2:
+                case Roles::RoomName:
+                        return QString::fromStdString(roomInfos.at(roomids[index.row()]).name);
+                case Roles::AvatarUrl:
+                        return QString::fromStdString(
+                          roomInfos.at(roomids[index.row()]).avatar_url);
+                case Roles::RoomID:
+                        return roomids[index.row()];
+                }
+        }
+        return {};
+}
diff --git a/src/RoomsModel.h b/src/RoomsModel.h
new file mode 100644
index 00000000..0e006448
--- /dev/null
+++ b/src/RoomsModel.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "Cache.h"
+
+#include <QAbstractListModel>
+#include <QString>
+
+class RoomsModel : public QAbstractListModel
+{
+public:
+        enum Roles
+        {
+                AvatarUrl = Qt::UserRole,
+                RoomAlias,
+                RoomID,
+                RoomName,
+        };
+
+        RoomsModel(bool showOnlyRoomWithAliases = false, QObject *parent = nullptr);
+        QHash<int, QByteArray> roleNames() const override;
+        int rowCount(const QModelIndex &parent = QModelIndex()) const override
+        {
+                (void)parent;
+                return (int)roomids.size();
+        }
+        QVariant data(const QModelIndex &index, int role) const override;
+
+private:
+        std::vector<QString> roomids;
+        std::vector<QString> roomAliases;
+        std::map<QString, RoomInfo> roomInfos;
+        bool showOnlyRoomWithAliases_;
+};
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index 08cbd15b..5ef38ac7 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -19,6 +19,7 @@
 #include "MainWindow.h"
 #include "MatrixClient.h"
 #include "Olm.h"
+#include "RoomsModel.h"
 #include "TimelineModel.h"
 #include "TimelineViewManager.h"
 #include "UserSettingsPage.h"
@@ -186,6 +187,11 @@ InputBar::completerFor(QString completerName)
                 auto proxy      = new CompletionProxyModel(emojiModel);
                 emojiModel->setParent(proxy);
                 return proxy;
+        } else if (completerName == "room") {
+                auto roomModel = new RoomsModel(true);
+                auto proxy     = new CompletionProxyModel(roomModel);
+                roomModel->setParent(proxy);
+                return proxy;
         }
         return nullptr;
 }