mirror of https://github.com/Nheko-Reborn/nheko
add user search to invite dialog (#1253)
parent
3abb49c4a2
commit
5ed3bfc8f8
@ -0,0 +1,53 @@ |
|||||||
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors |
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors |
||||||
|
// SPDX-FileCopyrightText: 2023 Nheko Contributors |
||||||
|
// |
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later |
||||||
|
|
||||||
|
import ".." |
||||||
|
import QtQuick 2.12 |
||||||
|
import QtQuick.Controls 2.12 |
||||||
|
import QtQuick.Layouts 1.12 |
||||||
|
import im.nheko 1.0 |
||||||
|
|
||||||
|
ItemDelegate { |
||||||
|
property alias bgColor: background.color |
||||||
|
property alias userid: avatar.userid |
||||||
|
property alias displayName: avatar.displayName |
||||||
|
property string avatarUrl |
||||||
|
implicitHeight: layout.implicitHeight + Nheko.paddingSmall * 2 |
||||||
|
background: Rectangle {id: background} |
||||||
|
GridLayout { |
||||||
|
id: layout |
||||||
|
anchors.centerIn: parent |
||||||
|
width: parent.width - Nheko.paddingSmall * 2 |
||||||
|
rows: 2 |
||||||
|
columns: 2 |
||||||
|
rowSpacing: Nheko.paddingSmall |
||||||
|
columnSpacing: Nheko.paddingMedium |
||||||
|
|
||||||
|
Avatar { |
||||||
|
id: avatar |
||||||
|
Layout.rowSpan: 2 |
||||||
|
Layout.preferredWidth: Nheko.avatarSize |
||||||
|
Layout.preferredHeight: Nheko.avatarSize |
||||||
|
Layout.alignment: Qt.AlignLeft |
||||||
|
url: avatarUrl.replace("mxc://", "image://MxcImage/") |
||||||
|
enabled: false |
||||||
|
} |
||||||
|
Label { |
||||||
|
Layout.fillWidth: true |
||||||
|
text: displayName |
||||||
|
color: TimelineManager.userColor(userid, Nheko.colors.window) |
||||||
|
font.pointSize: fontMetrics.font.pointSize |
||||||
|
} |
||||||
|
|
||||||
|
Label { |
||||||
|
Layout.fillWidth: true |
||||||
|
Layout.alignment: Qt.AlignTop |
||||||
|
text: userid |
||||||
|
color: Nheko.colors.buttonText |
||||||
|
font.pointSize: fontMetrics.font.pointSize * 0.9 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,105 @@ |
|||||||
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
// SPDX-FileCopyrightText: 2023 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "UserDirectoryModel.h" |
||||||
|
|
||||||
|
#include "Cache.h" |
||||||
|
#include "Logging.h" |
||||||
|
#include <QSharedPointer> |
||||||
|
#include "MatrixClient.h" |
||||||
|
#include "mtx/responses/users.hpp" |
||||||
|
|
||||||
|
UserDirectoryModel::UserDirectoryModel(QObject *parent) |
||||||
|
: QAbstractListModel{parent} |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
QHash<int, QByteArray> |
||||||
|
UserDirectoryModel::roleNames() const |
||||||
|
{ |
||||||
|
return { |
||||||
|
{Roles::DisplayName, "displayName"}, |
||||||
|
{Roles::Mxid, "userid"}, |
||||||
|
{Roles::AvatarUrl, "avatarUrl"}, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
UserDirectoryModel::setSearchString(const QString &f) |
||||||
|
{ |
||||||
|
userSearchString_ = f.toStdString(); |
||||||
|
nhlog::ui()->debug("Received user directory query: {}", userSearchString_); |
||||||
|
beginResetModel(); |
||||||
|
results_.clear(); |
||||||
|
if (userSearchString_ == "") |
||||||
|
nhlog::ui()->debug("Rejecting empty search string"); |
||||||
|
else |
||||||
|
canFetchMore_ = true; |
||||||
|
endResetModel(); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
UserDirectoryModel::fetchMore(const QModelIndex &) |
||||||
|
{ |
||||||
|
if (!canFetchMore_) |
||||||
|
return; |
||||||
|
|
||||||
|
nhlog::net()->debug("Fetching users from mtxclient..."); |
||||||
|
std::string searchTerm = userSearchString_; |
||||||
|
searchingUsers_ = true; |
||||||
|
emit searchingUsersChanged(); |
||||||
|
auto job = QSharedPointer<FetchUsersFromDirectoryJob>::create(); |
||||||
|
connect(job.data(), |
||||||
|
&FetchUsersFromDirectoryJob::fetchedSearchResults, |
||||||
|
this, |
||||||
|
&UserDirectoryModel::displaySearchResults); |
||||||
|
http::client()->search_user_directory( |
||||||
|
searchTerm, |
||||||
|
[job, searchTerm](const mtx::responses::Users &res, mtx::http::RequestErr err) { |
||||||
|
if (err) { |
||||||
|
nhlog::net()->error("Failed to retrieve users from mtxclient - {} - {} - {}", |
||||||
|
mtx::errors::to_string(err->matrix_error.errcode), |
||||||
|
err->matrix_error.error, |
||||||
|
err->parse_error); |
||||||
|
} else { |
||||||
|
emit job->fetchedSearchResults(res.results, searchTerm); |
||||||
|
} |
||||||
|
}, |
||||||
|
50); |
||||||
|
} |
||||||
|
|
||||||
|
QVariant |
||||||
|
UserDirectoryModel::data(const QModelIndex &index, int role) const |
||||||
|
{ |
||||||
|
if (!index.isValid() || index.row() >= (int)results_.size() || index.row() < 0) |
||||||
|
return {}; |
||||||
|
switch (role) { |
||||||
|
case Roles::DisplayName: |
||||||
|
return QString::fromStdString(results_[index.row()].display_name); |
||||||
|
case Roles::Mxid: |
||||||
|
return QString::fromStdString(results_[index.row()].user_id); |
||||||
|
case Roles::AvatarUrl: |
||||||
|
return QString::fromStdString(results_[index.row()].avatar_url); |
||||||
|
} |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
UserDirectoryModel::displaySearchResults(std::vector<mtx::responses::User> results, const std::string &searchTerm) |
||||||
|
{ |
||||||
|
if (searchTerm != this->userSearchString_) |
||||||
|
return; |
||||||
|
searchingUsers_ = false; |
||||||
|
emit searchingUsersChanged(); |
||||||
|
if (results.empty()) { |
||||||
|
nhlog::net()->debug("mtxclient helper thread yielded no results!"); |
||||||
|
return; |
||||||
|
} |
||||||
|
beginInsertRows(QModelIndex(), 0, static_cast<int>(results.size()) - 1); |
||||||
|
results_ = results; |
||||||
|
endInsertRows(); |
||||||
|
canFetchMore_ = false; |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
// SPDX-FileCopyrightText: 2023 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QAbstractListModel> |
||||||
|
#include <QString> |
||||||
|
#include <string> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include <mtx/responses/users.hpp> |
||||||
|
|
||||||
|
class FetchUsersFromDirectoryJob final : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
explicit FetchUsersFromDirectoryJob(QObject *p = nullptr) |
||||||
|
: QObject(p) |
||||||
|
{ |
||||||
|
} |
||||||
|
signals: |
||||||
|
void fetchedSearchResults(std::vector<mtx::responses::User> results, const std::string &searchTerm); |
||||||
|
}; |
||||||
|
class UserDirectoryModel : public QAbstractListModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
Q_PROPERTY(bool searchingUsers READ searchingUsers NOTIFY searchingUsersChanged) |
||||||
|
|
||||||
|
public: |
||||||
|
explicit UserDirectoryModel(QObject *parent = nullptr); |
||||||
|
|
||||||
|
enum Roles |
||||||
|
{ |
||||||
|
DisplayName, |
||||||
|
Mxid, |
||||||
|
AvatarUrl, |
||||||
|
}; |
||||||
|
QHash<int, QByteArray> roleNames() const override; |
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override; |
||||||
|
|
||||||
|
inline int rowCount(const QModelIndex &parent = QModelIndex()) const override |
||||||
|
{ |
||||||
|
(void)parent; |
||||||
|
return static_cast<int>(results_.size()); |
||||||
|
} |
||||||
|
bool canFetchMore(const QModelIndex &) const override { return canFetchMore_; } |
||||||
|
void fetchMore(const QModelIndex &) override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::vector<mtx::responses::User> results_; |
||||||
|
std::string userSearchString_; |
||||||
|
bool searchingUsers_{false}; |
||||||
|
bool canFetchMore_{false}; |
||||||
|
|
||||||
|
signals: |
||||||
|
void searchingUsersChanged(); |
||||||
|
|
||||||
|
public slots: |
||||||
|
void setSearchString(const QString &f); |
||||||
|
bool searchingUsers() const { return searchingUsers_; } |
||||||
|
|
||||||
|
private slots: |
||||||
|
void displaySearchResults(std::vector<mtx::responses::User> results, const std::string &searchTerm); |
||||||
|
}; |
Loading…
Reference in new issue