Add user directory.

This commit is contained in:
Black Hat
2019-12-25 21:20:23 +08:00
parent d25a9fb3a4
commit 282b1750ef
14 changed files with 626 additions and 12 deletions

View File

@@ -20,6 +20,7 @@
#include "spectralroom.h"
#include "spectraluser.h"
#include "trayicon.h"
#include "userdirectorylistmodel.h"
#include "userlistmodel.h"
using namespace Quotient;
@@ -42,6 +43,8 @@ int main(int argc, char* argv[]) {
qmlRegisterType<UserListModel>("Spectral", 0, 1, "UserListModel");
qmlRegisterType<MessageEventModel>("Spectral", 0, 1, "MessageEventModel");
qmlRegisterType<PublicRoomListModel>("Spectral", 0, 1, "PublicRoomListModel");
qmlRegisterType<UserDirectoryListModel>("Spectral", 0, 1,
"UserDirectoryListModel");
qmlRegisterType<EmojiModel>("Spectral", 0, 1, "EmojiModel");
qmlRegisterType<NotificationsManager>("Spectral", 0, 1,
"NotificationsManager");

View File

@@ -573,3 +573,12 @@ void SpectralRoom::toggleReaction(const QString& eventId,
postReaction(eventId, reaction);
}
}
bool SpectralRoom::containsUser(QString userID) const {
auto u = Room::user(userID);
if (!u)
return false;
return Room::memberJoinState(u) != JoinState::Leave;
}

View File

@@ -73,6 +73,8 @@ class SpectralRoom : public Room {
Qt::TextFormat format = Qt::PlainText,
bool removeReply = true) const;
Q_INVOKABLE bool containsUser(QString userID) const;
private:
QString m_cachedInput;
QSet<const Quotient::RoomEvent*> highlights;

View File

@@ -0,0 +1,156 @@
#include "userdirectorylistmodel.h"
UserDirectoryListModel::UserDirectoryListModel(QObject* parent)
: QAbstractListModel(parent) {}
void UserDirectoryListModel::setConnection(Connection* conn) {
if (m_connection == conn)
return;
beginResetModel();
m_limited = false;
attempted = false;
users.clear();
if (m_connection) {
m_connection->disconnect(this);
}
endResetModel();
m_connection = conn;
if (job) {
job->abandon();
job = nullptr;
}
emit connectionChanged();
emit limitedChanged();
}
void UserDirectoryListModel::setKeyword(const QString& value) {
if (m_keyword == value)
return;
m_keyword = value;
m_limited = false;
attempted = false;
if (job) {
job->abandon();
job = nullptr;
}
emit keywordChanged();
emit limitedChanged();
}
void UserDirectoryListModel::search(int count) {
if (count < 1)
return;
if (job) {
qDebug() << "UserDirectoryListModel: Other jobs running, ignore";
return;
}
if (attempted)
return;
job = m_connection->callApi<SearchUserDirectoryJob>(m_keyword, count);
connect(job, &BaseJob::finished, this, [=] {
attempted = true;
if (job->status() == BaseJob::Success) {
auto users = job->results();
this->beginResetModel();
this->users = users;
this->m_limited = job->limited();
this->endResetModel();
}
this->job = nullptr;
emit limitedChanged();
});
}
QVariant UserDirectoryListModel::data(const QModelIndex& index,
int role) const {
if (!index.isValid())
return QVariant();
if (index.row() >= users.count()) {
qDebug() << "UserDirectoryListModel, something's wrong: index.row() >= "
"users.count()";
return {};
}
auto user = users.at(index.row());
if (role == NameRole) {
auto displayName = user.displayName;
if (!displayName.isEmpty()) {
return displayName;
}
displayName = user.userId;
if (!displayName.isEmpty()) {
return displayName;
}
return "Unknown User";
}
if (role == AvatarRole) {
auto avatarUrl = user.avatarUrl;
if (avatarUrl.isEmpty()) {
return "";
}
return avatarUrl.remove(0, 6);
}
if (role == UserIDRole) {
return user.userId;
}
if (role == DirectChatsRole) {
if (!m_connection)
return {};
auto userObj = m_connection->user(user.userId);
auto directChats = m_connection->directChats();
if (userObj && directChats.contains(userObj)) {
auto directChatsForUser = directChats.values(userObj);
if (!directChatsForUser.isEmpty()) {
return QVariant::fromValue(directChatsForUser);
}
}
}
return {};
}
QHash<int, QByteArray> UserDirectoryListModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[AvatarRole] = "avatar";
roles[UserIDRole] = "userID";
roles[DirectChatsRole] = "directChats";
return roles;
}
int UserDirectoryListModel::rowCount(const QModelIndex& parent) const {
if (parent.isValid())
return 0;
return users.count();
}

View File

@@ -0,0 +1,62 @@
#ifndef USERDIRECTORYLISTMODEL_H
#define USERDIRECTORYLISTMODEL_H
#include <QAbstractListModel>
#include <QObject>
#include "connection.h"
#include "csapi/users.h"
using namespace Quotient;
class UserDirectoryListModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(Connection* connection READ connection WRITE setConnection NOTIFY
connectionChanged)
Q_PROPERTY(
QString keyword READ keyword WRITE setKeyword NOTIFY keywordChanged)
Q_PROPERTY(bool limited READ limited NOTIFY limitedChanged)
public:
enum EventRoles {
NameRole = Qt::DisplayRole + 1,
AvatarRole,
UserIDRole,
DirectChatsRole,
};
UserDirectoryListModel(QObject* parent = nullptr);
QVariant data(const QModelIndex& index, int role = NameRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
Connection* connection() const { return m_connection; }
void setConnection(Connection* value);
QString keyword() const { return m_keyword; }
void setKeyword(const QString& value);
bool limited() const { return m_limited; }
Q_INVOKABLE void search(int count = 50);
private:
Connection* m_connection = nullptr;
QString m_keyword;
bool m_limited = false;
bool attempted = false;
QVector<SearchUserDirectoryJob::User> users;
SearchUserDirectoryJob* job = nullptr;
signals:
void connectionChanged();
void keywordChanged();
void limitedChanged();
};
#endif // USERDIRECTORYLISTMODEL_H