mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Working User completer
This commit is contained in:
parent
a3c4fece7e
commit
add5903fb0
9 changed files with 83 additions and 38 deletions
|
@ -492,6 +492,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/ChatPage.h
|
||||
src/CommunitiesList.h
|
||||
src/CommunitiesListItem.h
|
||||
src/CompletionProxyModel.h
|
||||
src/DeviceVerificationFlow.h
|
||||
src/InviteeItem.h
|
||||
src/LoginPage.h
|
||||
|
@ -508,6 +509,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/TrayIcon.h
|
||||
src/UserInfoWidget.h
|
||||
src/UserSettingsPage.h
|
||||
src/UsersModel.h
|
||||
src/WebRTCSession.h
|
||||
src/WelcomePage.h
|
||||
src/popups/PopupItem.h
|
||||
|
|
|
@ -34,11 +34,17 @@ Popup {
|
|||
onCompleterNameChanged: {
|
||||
if (completerName)
|
||||
completer = TimelineManager.timeline.input.completerFor(completerName);
|
||||
|
||||
else
|
||||
completer = undefined;
|
||||
}
|
||||
padding: 0
|
||||
onAboutToShow: currentIndex = -1
|
||||
|
||||
Connections {
|
||||
onTimelineChanged: completer = null
|
||||
target: TimelineManager
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
|
|
@ -77,14 +77,13 @@ Rectangle {
|
|||
onTextChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
|
||||
onCursorPositionChanged: {
|
||||
TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text);
|
||||
if (cursorPosition < completerTriggeredAt) {
|
||||
if (cursorPosition <= completerTriggeredAt) {
|
||||
completerTriggeredAt = -1;
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
onSelectionStartChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
|
||||
onSelectionEndChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
|
||||
// Ensure that we get escape key press events first.
|
||||
Keys.onShortcutOverride: event.accepted = (completerTriggeredAt != -1 && (event.key === Qt.Key_Escape || event.key === Qt.Key_Tab || event.key === Qt.Key_Enter))
|
||||
Keys.onPressed: {
|
||||
if (event.matches(StandardKey.Paste)) {
|
||||
|
@ -97,18 +96,20 @@ Rectangle {
|
|||
} else if (event.modifiers == Qt.ControlModifier && event.key == Qt.Key_N) {
|
||||
textArea.text = TimelineManager.timeline.input.nextText();
|
||||
} else if (event.key == Qt.Key_At) {
|
||||
completerTriggeredAt = cursorPosition + 1;
|
||||
completerTriggeredAt = cursorPosition;
|
||||
popup.completerName = "user";
|
||||
popup.open();
|
||||
} else if (event.key == Qt.Key_Escape && popup.opened) {
|
||||
completerTriggeredAt = -1;
|
||||
popup.completerName = "";
|
||||
event.accepted = true;
|
||||
popup.close();
|
||||
} else if (event.matches(StandardKey.InsertParagraphSeparator) && popup.opened) {
|
||||
var currentCompletion = popup.currentCompletion();
|
||||
popup.completerName = "";
|
||||
popup.close();
|
||||
if (currentCompletion) {
|
||||
textArea.remove(completerTriggeredAt - 1, cursorPosition);
|
||||
textArea.remove(completerTriggeredAt, cursorPosition);
|
||||
textArea.insert(cursorPosition, currentCompletion);
|
||||
event.accepted = true;
|
||||
return ;
|
||||
|
@ -129,6 +130,17 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
onTimelineChanged: {
|
||||
textArea.clear();
|
||||
textArea.append(TimelineManager.timeline.input.text());
|
||||
textArea.completerTriggeredAt = -1;
|
||||
popup.completerName = "";
|
||||
}
|
||||
target: TimelineManager
|
||||
}
|
||||
// Ensure that we get escape key press events first.
|
||||
|
||||
Completer {
|
||||
id: popup
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// Class for showing a limited amount of completions at a time
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class CompletionModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
CompletionModel(QAbstractItemModel *model, QObject *parent = nullptr)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(model);
|
||||
}
|
||||
int rowCount(const QModelIndex &parent) const override
|
||||
{
|
||||
auto row_count = QSortFilterProxyModel::rowCount(parent);
|
||||
return (row_count < 7) ? row_count : 7;
|
||||
}
|
||||
};
|
|
@ -10,6 +10,6 @@ enum Roles
|
|||
{
|
||||
CompletionRole = Qt::UserRole * 2, // The string to replace the active completion
|
||||
SearchRole, // String completer uses for search
|
||||
SearchRole2, // Secondary string completer uses for search
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,17 +4,36 @@
|
|||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "CompletionModelRoles.h"
|
||||
|
||||
class CompletionProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CompletionProxyModel(QAbstractItemModel *model, QObject *parent = nullptr)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(model);
|
||||
}
|
||||
int rowCount(const QModelIndex &parent) const override
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override
|
||||
{
|
||||
return this->sourceModel()->roleNames();
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
auto row_count = QSortFilterProxyModel::rowCount(parent);
|
||||
return (row_count < 7) ? row_count : 7;
|
||||
}
|
||||
|
||||
public slots:
|
||||
QVariant completionAt(int i) const
|
||||
{
|
||||
if (i >= 0 && i < rowCount())
|
||||
return data(index(i, 0), CompletionModel::CompletionRole);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,12 +3,23 @@
|
|||
#include "Cache.h"
|
||||
#include "CompletionModelRoles.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
UsersModel::UsersModel(const std::string &roomId, QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, room_id(roomId)
|
||||
{
|
||||
roomMembers_ = cache::getMembers(roomId, 0, 9999);
|
||||
roomMembers_ = cache::roomMembers(roomId);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
UsersModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{CompletionModel::CompletionRole, "completionRole"},
|
||||
{CompletionModel::SearchRole, "searchRole"},
|
||||
{CompletionModel::SearchRole2, "searchRole2"},
|
||||
{Roles::DisplayName, "displayName"},
|
||||
{Roles::AvatarUrl, "avatarUrl"},
|
||||
};
|
||||
}
|
||||
|
||||
QVariant
|
||||
|
@ -19,9 +30,14 @@ UsersModel::data(const QModelIndex &index, int role) const
|
|||
case CompletionModel::CompletionRole:
|
||||
case CompletionModel::SearchRole:
|
||||
case Qt::DisplayRole:
|
||||
return roomMembers_[index.row()].display_name;
|
||||
case Avatar:
|
||||
return roomMembers_[index.row()].avatar;
|
||||
case Roles::DisplayName:
|
||||
return QString::fromStdString(
|
||||
cache::displayName(room_id, roomMembers_[index.row()]));
|
||||
case CompletionModel::SearchRole2:
|
||||
return QString::fromStdString(roomMembers_[index.row()]);
|
||||
case Roles::AvatarUrl:
|
||||
return cache::avatarUrl(QString::fromStdString(room_id),
|
||||
QString::fromStdString(roomMembers_[index.row()]));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
|
|
|
@ -2,23 +2,25 @@
|
|||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
class RoomMember;
|
||||
|
||||
class UsersModel : public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
enum Roles
|
||||
{
|
||||
Avatar = Qt::UserRole // QImage avatar
|
||||
AvatarUrl = Qt::UserRole,
|
||||
DisplayName,
|
||||
};
|
||||
|
||||
UsersModel(const std::string &roomId, QObject *parent = nullptr);
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
return (parent == QModelIndex()) ? roomMembers_.size() : 0;
|
||||
(void)parent;
|
||||
return roomMembers_.size();
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
private:
|
||||
std::vector<RoomMember> roomMembers_;
|
||||
std::string room_id;
|
||||
std::vector<std::string> roomMembers_;
|
||||
};
|
||||
|
|
|
@ -14,12 +14,14 @@
|
|||
#include "Cache.h"
|
||||
#include "CallManager.h"
|
||||
#include "ChatPage.h"
|
||||
#include "CompletionProxyModel.h"
|
||||
#include "Logging.h"
|
||||
#include "MainWindow.h"
|
||||
#include "MatrixClient.h"
|
||||
#include "Olm.h"
|
||||
#include "TimelineModel.h"
|
||||
#include "UserSettingsPage.h"
|
||||
#include "UsersModel.h"
|
||||
#include "Utils.h"
|
||||
#include "dialogs/PlaceCall.h"
|
||||
#include "dialogs/PreviewUploadOverlay.h"
|
||||
|
@ -166,6 +168,12 @@ InputBar::nextText()
|
|||
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;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue