From 32d419d14f19436c2c8352de06b5c6051e8cc0ab Mon Sep 17 00:00:00 2001 From: Jedi18 Date: Sun, 21 Feb 2021 23:10:21 +0530 Subject: add quick switcher qml file and moved completerFor from inputbar to timeline view class --- src/timeline/TimelineViewManager.cpp | 25 +++++++++++++++++++++++++ src/timeline/TimelineViewManager.h | 1 + 2 files changed, 26 insertions(+) (limited to 'src/timeline') diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index f2e6d571..dc041cb9 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -11,13 +11,16 @@ #include "BlurhashProvider.h" #include "ChatPage.h" #include "ColorImageProvider.h" +#include "CompletionProxyModel.h" #include "DelegateChooser.h" #include "DeviceVerificationFlow.h" #include "Logging.h" #include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" +#include "RoomsModel.h" #include "UserSettingsPage.h" +#include "UsersModel.h" #include "dialogs/ImageOverlay.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" @@ -552,3 +555,25 @@ TimelineViewManager::focusMessageInput() { emit focusInput(); } + +QObject * +TimelineViewManager::completerFor(QString completerName, QString roomId) +{ + if (completerName == "user") { + auto userModel = new UsersModel(roomId.toStdString()); + auto proxy = new CompletionProxyModel(userModel); + userModel->setParent(proxy); + return proxy; + } else if (completerName == "emoji") { + auto emojiModel = new emoji::EmojiModel(); + 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; +} \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 61fce574..d6383806 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -138,6 +138,7 @@ public slots: } void backToRooms() { emit showRoomList(); } + QObject *completerFor(QString completerName, QString roomId = ""); private: #ifdef USE_QUICK_VIEW -- cgit 1.4.1 From 0922a8e4c755dec9170820ae6263a1fc3122468c Mon Sep 17 00:00:00 2001 From: Jedi18 Date: Mon, 22 Feb 2021 00:01:50 +0530 Subject: add room alias delegate, fix some quickswitcher ui problems --- resources/qml/Completer.qml | 29 +++++++++++++++++++++++++++-- resources/qml/MessageInput.qml | 2 +- resources/qml/QuickSwitcher.qml | 18 +++++++++++++----- src/timeline/TimelineViewManager.cpp | 5 +++++ 4 files changed, 46 insertions(+), 8 deletions(-) (limited to 'src/timeline') diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index ec5030e7..76e08e7e 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -11,6 +11,7 @@ Popup { property string completerName property var completer property bool bottomToTop: true + property bool fullWidth: false property alias count: listView.count signal completionClicked(string completion) @@ -75,14 +76,14 @@ Popup { id: listView anchors.fill: parent - implicitWidth: contentItem.childrenRect.width + implicitWidth: fullWidth ? parent.width : contentItem.childrenRect.width model: completer verticalLayoutDirection: popup.bottomToTop ? ListView.BottomToTop : ListView.TopToBottom delegate: Rectangle { color: model.index == popup.currentIndex ? colors.highlight : colors.base height: chooser.childrenRect.height + 4 - implicitWidth: chooser.childrenRect.width + 4 + implicitWidth: fullWidth ? popup.width : chooser.childrenRect.width + 4 MouseArea { id: mouseArea @@ -161,6 +162,30 @@ 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 + } + + } + + } + + DelegateChoice { + roleValue: "roomAliases" + RowLayout { id: del diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index 7ecaf81a..e6b6762d 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -184,7 +184,7 @@ Rectangle { messageInput.openCompleter(cursorPosition, "emoji"); popup.open(); } else if (event.key == Qt.Key_NumberSign) { - messageInput.openCompleter(cursorPosition, "room"); + messageInput.openCompleter(cursorPosition, "roomAliases"); popup.open(); } else if (event.key == Qt.Key_Escape && popup.opened) { completerTriggeredAt = -1; diff --git a/resources/qml/QuickSwitcher.qml b/resources/qml/QuickSwitcher.qml index 317c96b3..ca7a5eeb 100644 --- a/resources/qml/QuickSwitcher.qml +++ b/resources/qml/QuickSwitcher.qml @@ -6,17 +6,16 @@ Popup { x: parent.width / 2 - width / 2 y: parent.height / 4 - height / 2 width: parent.width / 2 - height: 100 modal: true - focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside parent: Overlay.overlay TextInput { id: roomTextInput - anchors.fill: parent focus: true + anchors.fill: parent + color: colors.text onTextEdited: { completerPopup.completer.setSearchString(text) @@ -26,13 +25,22 @@ Popup { Completer { id: completerPopup - x: roomTextInput.x + 100 - y: roomTextInput.y - 20 + x: roomTextInput.x + y: roomTextInput.y + parent.height + width: parent.width completerName: "room" bottomToTop: true + fullWidth: true + + closePolicy: Popup.NoAutoClose } onOpened: { completerPopup.open() + roomTextInput.forceActiveFocus() + } + + onClosed: { + completerPopup.close() } } \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index dc041cb9..74d416bb 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -570,6 +570,11 @@ TimelineViewManager::completerFor(QString completerName, QString roomId) emojiModel->setParent(proxy); return proxy; } else if (completerName == "room") { + auto roomModel = new RoomsModel(false); + auto proxy = new CompletionProxyModel(roomModel); + roomModel->setParent(proxy); + return proxy; + } else if (completerName == "roomAliases") { auto roomModel = new RoomsModel(true); auto proxy = new CompletionProxyModel(roomModel); roomModel->setParent(proxy); -- cgit 1.4.1 From b1dec6f6acec929495f66ef7d0fcb3cac9ee25e3 Mon Sep 17 00:00:00 2001 From: Jedi18 Date: Tue, 23 Feb 2021 00:18:31 +0530 Subject: enter key now works, fix room highlighting and add overlay --- resources/qml/Completer.qml | 7 +++++++ resources/qml/QuickSwitcher.qml | 9 +++++++++ resources/qml/TimelineView.qml | 1 - src/ChatPage.cpp | 6 ++++++ src/ChatPage.h | 1 + src/timeline/TimelineViewManager.cpp | 6 ++++++ src/timeline/TimelineViewManager.h | 1 + 7 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/timeline') diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index a4f81e6e..cef19fbf 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -52,6 +52,12 @@ Popup { return null; } + function finishCompletion() { + if(popup.completerName == "room") { + popup.completionSelected(listView.itemAtIndex(currentIndex).modelData.roomid) + } + } + onCompleterNameChanged: { if (completerName) { if (completerName == "user") { @@ -85,6 +91,7 @@ Popup { color: model.index == popup.currentIndex ? colors.highlight : colors.base height: chooser.childrenRect.height + 4 implicitWidth: fullWidth ? popup.width : chooser.childrenRect.width + 4 + property variant modelData: model MouseArea { id: mouseArea diff --git a/resources/qml/QuickSwitcher.qml b/resources/qml/QuickSwitcher.qml index b94fc0e2..609c443f 100644 --- a/resources/qml/QuickSwitcher.qml +++ b/resources/qml/QuickSwitcher.qml @@ -11,6 +11,10 @@ Popup { closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside parent: Overlay.overlay + Overlay.modal: Rectangle { + color: "#aa1E1E1E" + } + TextInput { id: roomTextInput @@ -29,6 +33,9 @@ Popup { } else if (event.key == Qt.Key_Down && completerPopup.opened) { event.accepted = true; completerPopup.down(); + } else if (event.matches(StandardKey.InsertParagraphSeparator)) { + completerPopup.finishCompletion() + event.accepted = true; } } } @@ -57,7 +64,9 @@ Popup { Connections { onCompletionSelected: { + console.log(id) TimelineManager.setHistoryView(id) + TimelineManager.highlightRoom(id) quickSwitcher.close() } target: completerPopup diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index f575e133..8c84c145 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -72,7 +72,6 @@ Page { id: quickSwitcherComponent QuickSwitcher { - id: quickSwitcher } } diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 9c814bd1..b862e129 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -1429,3 +1429,9 @@ ChatPage::handleMatrixUri(const QUrl &uri) { handleMatrixUri(uri.toString(QUrl::ComponentFormattingOption::FullyEncoded).toUtf8()); } + +void +ChatPage::highlightRoom(const QString &room_id) +{ + room_list_->highlightSelectedRoom(room_id); +} \ No newline at end of file diff --git a/src/ChatPage.h b/src/ChatPage.h index 917bd785..47acd807 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -116,6 +116,7 @@ public slots: void startChat(QString userid); void leaveRoom(const QString &room_id); void createRoom(const mtx::requests::CreateRoom &req); + void highlightRoom(const QString &room_id); void joinRoom(const QString &room); void joinRoomVia(const std::string &room_id, const std::vector &via); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 74d416bb..49072ef4 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -333,6 +333,12 @@ TimelineViewManager::setHistoryView(const QString &room_id) } } +void +TimelineViewManager::highlightRoom(const QString &room_id) +{ + ChatPage::instance()->highlightRoom(room_id); +} + QString TimelineViewManager::escapeEmoji(QString str) const { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index d6383806..dfc2e386 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -100,6 +100,7 @@ public slots: } void setHistoryView(const QString &room_id); + void highlightRoom(const QString &room_id); TimelineModel *getHistoryView(const QString &room_id) { auto room = models.find(room_id); -- cgit 1.4.1 From ee232c5c60740921f7f3a72a97e46b2523882441 Mon Sep 17 00:00:00 2001 From: Jedi18 Date: Tue, 23 Feb 2021 00:46:40 +0530 Subject: fix timeline focus --- resources/qml/TimelineView.qml | 1 + src/timeline/TimelineViewManager.cpp | 6 ++++++ src/timeline/TimelineViewManager.h | 1 + 3 files changed, 8 insertions(+) (limited to 'src/timeline') diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 8c84c145..02032393 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -79,6 +79,7 @@ Page { sequence: "Ctrl+L" onActivated: { var quickSwitch = quickSwitcherComponent.createObject(timelineRoot); + TimelineManager.focusTimeline() quickSwitch.open(); } } diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 49072ef4..7d74496d 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -587,4 +587,10 @@ TimelineViewManager::completerFor(QString completerName, QString roomId) return proxy; } return nullptr; +} + +void +TimelineViewManager::focusTimeline() +{ + getWidget()->setFocus(); } \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index dfc2e386..f1c360ef 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -101,6 +101,7 @@ public slots: void setHistoryView(const QString &room_id); void highlightRoom(const QString &room_id); + void focusTimeline(); TimelineModel *getHistoryView(const QString &room_id) { auto room = models.find(room_id); -- cgit 1.4.1 From 8870455f9dd6463f9b8ef04516d69efef3c6287d Mon Sep 17 00:00:00 2001 From: Jedi18 Date: Sun, 7 Mar 2021 00:18:24 +0530 Subject: change allowed mistakes, fix minor style issues, remove old completer function from inputbar --- resources/qml/Completer.qml | 2 ++ resources/qml/MatrixTextField.qml | 7 +++++- resources/qml/QuickSwitcher.qml | 9 ++++---- src/CompletionProxyModel.cpp | 7 ++++-- src/CompletionProxyModel.h | 42 +++++++++++++++++++++--------------- src/timeline/InputBar.cpp | 22 ------------------- src/timeline/InputBar.h | 2 -- src/timeline/TimelineViewManager.cpp | 2 +- 8 files changed, 43 insertions(+), 50 deletions(-) (limited to 'src/timeline') diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index 3abf8f38..4a692c55 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -92,6 +92,7 @@ Popup { model: completer verticalLayoutDirection: popup.bottomToTop ? ListView.BottomToTop : ListView.TopToBottom spacing: rowSpacing + pixelAligned: true delegate: Rectangle { color: model.index == popup.currentIndex ? colors.highlight : colors.base @@ -202,6 +203,7 @@ Popup { Label { text: model.roomName + font.pixelSize: popup.avatarHeight * 0.5 color: model.index == popup.currentIndex ? colors.highlightedText : colors.text } diff --git a/resources/qml/MatrixTextField.qml b/resources/qml/MatrixTextField.qml index 037a0b71..9e8d286b 100644 --- a/resources/qml/MatrixTextField.qml +++ b/resources/qml/MatrixTextField.qml @@ -2,8 +2,13 @@ import QtQuick 2.13 import QtQuick.Layouts 1.13 import QtQuick.Controls 2.13 -TextInput { +TextField { id: input + palette: colors + + background: Rectangle { + color: colors.base + } Rectangle { id: blueBar diff --git a/resources/qml/QuickSwitcher.qml b/resources/qml/QuickSwitcher.qml index ab037d4e..29d9a9b2 100644 --- a/resources/qml/QuickSwitcher.qml +++ b/resources/qml/QuickSwitcher.qml @@ -5,7 +5,7 @@ import im.nheko 1.0 Popup { id: quickSwitcher - property int textHeight: 48 + property int textHeight: 32 property int textMargin: 8 x: parent.width / 2 - width / 2 @@ -49,9 +49,9 @@ Popup { Completer { id: completerPopup - x: roomTextInput.x - 5 - y: roomTextInput.y + roomTextInput.height + 5 - width: parent.width + 10 + x: roomTextInput.x + y: roomTextInput.y + roomTextInput.height + textMargin + width: parent.width completerName: "room" bottomToTop: false fullWidth: true @@ -77,7 +77,6 @@ Popup { Connections { onCompletionSelected: { - console.log(id) TimelineManager.setHistoryView(id) TimelineManager.highlightRoom(id) quickSwitcher.close() diff --git a/src/CompletionProxyModel.cpp b/src/CompletionProxyModel.cpp index fa5b3c2d..35b8d0a9 100644 --- a/src/CompletionProxyModel.cpp +++ b/src/CompletionProxyModel.cpp @@ -6,8 +6,11 @@ #include "Logging.h" #include "Utils.h" -CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, QObject *parent) +CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, + int max_mistakes, + QObject *parent) : QAbstractProxyModel(parent) + , maxMistakes_(max_mistakes) { setSourceModel(model); QRegularExpression splitPoints("\\s+|-"); @@ -59,7 +62,7 @@ CompletionProxyModel::invalidate() { auto key = searchString.toUcs4(); beginResetModel(); - mapping = trie_.search(key, 7); + mapping = trie_.search(key, 7, maxMistakes_); endResetModel(); std::string temp; diff --git a/src/CompletionProxyModel.h b/src/CompletionProxyModel.h index 1517505f..fc419702 100644 --- a/src/CompletionProxyModel.h +++ b/src/CompletionProxyModel.h @@ -54,19 +54,19 @@ struct trie } std::vector search(const QVector &keys, //< TODO(Nico): replace this with a span - size_t limit, - size_t max_distance = 2) const + size_t result_count_limit, + size_t max_edit_distance = 2) const { std::vector ret; - if (!limit) + if (!result_count_limit) return ret; if (keys.isEmpty()) - return valuesAndSubvalues(limit); + return valuesAndSubvalues(result_count_limit); - auto append = [&ret, limit](std::vector &&in) { + auto append = [&ret, result_count_limit](std::vector &&in) { for (auto &&v : in) { - if (ret.size() >= limit) + if (ret.size() >= result_count_limit) return; if (std::find(ret.begin(), ret.end(), v) == ret.end()) { @@ -76,11 +76,12 @@ struct trie }; if (auto e = this->next.find(keys[0]); e != this->next.end()) { - append(e->second.search(keys.mid(1), limit, max_distance)); + append( + e->second.search(keys.mid(1), result_count_limit, max_edit_distance)); } - if (max_distance && ret.size() < limit) { - max_distance -= 1; + if (max_edit_distance && ret.size() < result_count_limit) { + max_edit_distance -= 1; // swap chars case if (keys.size() >= 2) { @@ -95,27 +96,31 @@ struct trie } if (t) { - append(t->search( - keys.mid(2), (limit - ret.size()) * 2, max_distance)); + append(t->search(keys.mid(2), + (result_count_limit - ret.size()) * 2, + max_edit_distance)); } } // delete character case - append(this->search(keys.mid(1), (limit - ret.size()) * 2, max_distance)); + append(this->search( + keys.mid(1), (result_count_limit - ret.size()) * 2, max_edit_distance)); // substitute and insert cases for (const auto &[k, t] : this->next) { - if (k == keys[0] || ret.size() >= limit) + if (k == keys[0] || ret.size() >= result_count_limit) break; // substitute - append(t.search(keys.mid(1), limit - ret.size(), max_distance)); + append(t.search( + keys.mid(1), result_count_limit - ret.size(), max_edit_distance)); - if (ret.size() >= limit) + if (ret.size() >= result_count_limit) break; // insert - append(t.search(keys, limit - ret.size(), max_distance)); + append(t.search( + keys, result_count_limit - ret.size(), max_edit_distance)); } } @@ -128,7 +133,9 @@ class CompletionProxyModel : public QAbstractProxyModel Q_OBJECT public: - CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr); + CompletionProxyModel(QAbstractItemModel *model, + int max_mistakes = 2, + QObject *parent = nullptr); void invalidate(); @@ -156,4 +163,5 @@ private: QString searchString; trie trie_; std::vector mapping; + int maxMistakes_; }; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index 5ef38ac7..ab0fc3d7 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -174,28 +174,6 @@ InputBar::nextText() return text(); } -QObject * -InputBar::completerFor(QString completerName) -{ - if (completerName == "user") { - auto userModel = new UsersModel(room->roomId().toStdString()); - auto proxy = new CompletionProxyModel(userModel); - userModel->setParent(proxy); - return proxy; - } else if (completerName == "emoji") { - auto emojiModel = new emoji::EmojiModel(); - 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; -} - void InputBar::send() { diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index 696a0dd9..678d953d 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -51,8 +51,6 @@ public slots: bool uploading() const { return uploading_; } void message(QString body, MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED); - QObject *completerFor(QString completerName); - private slots: void startTyping(); void stopTyping(); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 7d74496d..04af7060 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -577,7 +577,7 @@ TimelineViewManager::completerFor(QString completerName, QString roomId) return proxy; } else if (completerName == "room") { auto roomModel = new RoomsModel(false); - auto proxy = new CompletionProxyModel(roomModel); + auto proxy = new CompletionProxyModel(roomModel, 4); roomModel->setParent(proxy); return proxy; } else if (completerName == "roomAliases") { -- cgit 1.4.1