Working public room directory.
Fix "no known servers". Rename all QMatrixClient to Quotient.
This commit is contained in:
@@ -97,14 +97,14 @@ Dialog {
|
|||||||
Layout.preferredHeight: 48
|
Layout.preferredHeight: 48
|
||||||
|
|
||||||
color: MPalette.foreground
|
color: MPalette.foreground
|
||||||
icon: "\ue7ff"
|
icon: "\ue5d2"
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
color: MPalette.foreground
|
color: MPalette.foreground
|
||||||
text: "Start a Chat"
|
text: "Explore Rooms"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ Dialog {
|
|||||||
|
|
||||||
onPrimaryClicked: {
|
onPrimaryClicked: {
|
||||||
joinRoomDialog.createObject(ApplicationWindow.overlay, {"controller": spectralController, "connection": spectralController.connection}).open()
|
joinRoomDialog.createObject(ApplicationWindow.overlay, {"controller": spectralController, "connection": spectralController.connection}).open()
|
||||||
root.destroy()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Dialog {
|
|||||||
|
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
title: "Start a Chat"
|
title: "Explore Rooms"
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
@@ -30,17 +30,39 @@ Dialog {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
AutoTextField {
|
AutoTextField {
|
||||||
|
property bool isRoomAlias: text.match(/#(.+):(.+)/g)
|
||||||
|
property var room: isRoomAlias ? connection.roomByAlias(text) : null
|
||||||
|
property bool isJoined: room != null
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
id: identifierField
|
id: identifierField
|
||||||
|
|
||||||
placeholderText: "Room Alias/User ID"
|
placeholderText: "Find a room..."
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
onEditingFinished: {
|
||||||
keyword = text
|
keyword = text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: joinButton
|
||||||
|
|
||||||
|
visible: identifierField.isRoomAlias
|
||||||
|
|
||||||
|
text: identifierField.isJoined ? "View" : "Join"
|
||||||
|
highlighted: true
|
||||||
|
flat: identifierField.isJoined
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (identifierField.isJoined) {
|
||||||
|
roomListForm.joinRoom(identifierField.room)
|
||||||
|
} else {
|
||||||
|
spectralController.joinRoom(connection, identifierField.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
Layout.maximumWidth: 120
|
Layout.maximumWidth: 120
|
||||||
|
|
||||||
@@ -88,14 +110,13 @@ Dialog {
|
|||||||
keyword: root.keyword
|
keyword: root.keyword
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Control {
|
||||||
width: publicRoomsListView.width
|
width: publicRoomsListView.width
|
||||||
height: 40
|
height: 48
|
||||||
|
|
||||||
RowLayout {
|
padding: 8
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: 4
|
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
Avatar {
|
Avatar {
|
||||||
@@ -109,20 +130,52 @@ Dialog {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Label {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
text: name
|
spacing: 4
|
||||||
color: MPalette.foreground
|
|
||||||
font.pixelSize: 13
|
Label {
|
||||||
textFormat: Text.PlainText
|
Layout.fillWidth: true
|
||||||
elide: Text.ElideRight
|
Layout.fillHeight: true
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
|
text: name
|
||||||
|
color: MPalette.foreground
|
||||||
|
font.pixelSize: 13
|
||||||
|
textFormat: Text.PlainText
|
||||||
|
elide: Text.ElideRight
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: allowGuests
|
||||||
|
|
||||||
|
text: "GUESTS CAN JOIN"
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 10
|
||||||
|
padding: 4
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MPalette.banner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: worldReadable
|
||||||
|
|
||||||
|
text: "WORLD READABLE"
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 10
|
||||||
|
padding: 4
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MPalette.banner
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -139,10 +192,67 @@ Dialog {
|
|||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RippleEffect {
|
MaterialIcon {
|
||||||
anchors.fill: parent
|
Layout.preferredWidth: 16
|
||||||
|
Layout.preferredHeight: 16
|
||||||
|
|
||||||
|
icon: "\ue7fc"
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.preferredWidth: 36
|
||||||
|
|
||||||
|
text: memberCount
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.preferredWidth: 32
|
||||||
|
Layout.preferredHeight: 32
|
||||||
|
|
||||||
|
visible: isJoined
|
||||||
|
|
||||||
|
contentItem: MaterialIcon {
|
||||||
|
icon: "\ue89e"
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
background: RippleEffect {
|
||||||
|
circular: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
roomListForm.joinRoom(connection.room(roomID))
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.preferredWidth: 32
|
||||||
|
Layout.preferredHeight: 32
|
||||||
|
|
||||||
|
visible: !isJoined
|
||||||
|
|
||||||
|
contentItem: MaterialIcon {
|
||||||
|
icon: "\ue7f0"
|
||||||
|
color: MPalette.lighter
|
||||||
|
font.pixelSize: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
background: RippleEffect {
|
||||||
|
circular: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
spectralController.joinRoom(connection, roomID)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,17 +265,5 @@ Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// standardButtons: Dialog.Ok | Dialog.Cancel
|
|
||||||
|
|
||||||
// onAccepted: {
|
|
||||||
// var identifier = identifierField.text
|
|
||||||
// var firstChar = identifier.charAt(0)
|
|
||||||
// if (firstChar == "@") {
|
|
||||||
// spectralController.createDirectChat(spectralController.connection, identifier)
|
|
||||||
// } else if (firstChar == "!" || firstChar == "#") {
|
|
||||||
// spectralController.joinRoom(spectralController.connection, identifier)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,13 +296,7 @@ Item {
|
|||||||
if (category === RoomType.Invited) {
|
if (category === RoomType.Invited) {
|
||||||
acceptInvitationDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom}).open()
|
acceptInvitationDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom}).open()
|
||||||
} else {
|
} else {
|
||||||
if (enteredRoom) {
|
joinRoom(currentRoom)
|
||||||
leaveRoom(enteredRoom)
|
|
||||||
enteredRoom.displayed = false
|
|
||||||
}
|
|
||||||
enterRoom(currentRoom)
|
|
||||||
enteredRoom = currentRoom
|
|
||||||
currentRoom.displayed = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onSecondaryClicked: roomListContextMenu.createObject(parent, {"room": currentRoom}).popup()
|
onSecondaryClicked: roomListContextMenu.createObject(parent, {"room": currentRoom}).popup()
|
||||||
@@ -427,4 +421,14 @@ Item {
|
|||||||
|
|
||||||
AcceptInvitationDialog {}
|
AcceptInvitationDialog {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function joinRoom(room) {
|
||||||
|
if (enteredRoom) {
|
||||||
|
leaveRoom(enteredRoom)
|
||||||
|
enteredRoom.displayed = false
|
||||||
|
}
|
||||||
|
enterRoom(room)
|
||||||
|
enteredRoom = room
|
||||||
|
room.displayed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void Controller::addConnection(Connection* c) {
|
|||||||
c->sync(30000);
|
c->sync(30000);
|
||||||
});
|
});
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ void Controller::dropConnection(Connection* c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::invokeLogin() {
|
void Controller::invokeLogin() {
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
const auto accounts = SettingsGroup("Accounts").childGroups();
|
const auto accounts = SettingsGroup("Accounts").childGroups();
|
||||||
for (const auto& accountId : accounts) {
|
for (const auto& accountId : accounts) {
|
||||||
AccountSettings account{accountId};
|
AccountSettings account{accountId};
|
||||||
@@ -342,7 +342,11 @@ bool Controller::saveAccessTokenToKeyChain(const AccountSettings& account,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::joinRoom(Connection* c, const QString& alias) {
|
void Controller::joinRoom(Connection* c, const QString& alias) {
|
||||||
auto joinRoomJob = c->joinRoom(alias);
|
if (!alias.contains(":"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto knownServer = alias.mid(alias.indexOf(":") + 1);
|
||||||
|
auto joinRoomJob = c->joinRoom(alias, QStringList{knownServer});
|
||||||
joinRoomJob->connect(joinRoomJob, &JoinRoomJob::failure, [=] {
|
joinRoomJob->connect(joinRoomJob, &JoinRoomJob::failure, [=] {
|
||||||
emit errorOccured("Join Room Failed", joinRoomJob->errorString());
|
emit errorOccured("Join Room Failed", joinRoomJob->errorString());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "trayicon.h"
|
#include "trayicon.h"
|
||||||
#include "userlistmodel.h"
|
#include "userlistmodel.h"
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
@@ -53,6 +53,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
qRegisterMetaType<User*>("User*");
|
qRegisterMetaType<User*>("User*");
|
||||||
qRegisterMetaType<User*>("const User*");
|
qRegisterMetaType<User*>("const User*");
|
||||||
|
qRegisterMetaType<User*>("const Quotient::User*");
|
||||||
qRegisterMetaType<Room*>("Room*");
|
qRegisterMetaType<Room*>("Room*");
|
||||||
qRegisterMetaType<Connection*>("Connection*");
|
qRegisterMetaType<Connection*>("Connection*");
|
||||||
qRegisterMetaType<MessageEventType>("MessageEventType");
|
qRegisterMetaType<MessageEventType>("MessageEventType");
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
using QMatrixClient::BaseJob;
|
using Quotient::BaseJob;
|
||||||
|
|
||||||
ThumbnailResponse::ThumbnailResponse(QMatrixClient::Connection* c,
|
ThumbnailResponse::ThumbnailResponse(Quotient::Connection* c,
|
||||||
QString id,
|
QString id,
|
||||||
const QSize& size)
|
const QSize& size)
|
||||||
: c(c),
|
: c(c),
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
#include "messageeventmodel.h"
|
#include "messageeventmodel.h"
|
||||||
|
|
||||||
#include <connection.h>
|
#include <connection.h>
|
||||||
#include <settings.h>
|
|
||||||
#include <user.h>
|
|
||||||
|
|
||||||
#include <events/reactionevent.h>
|
#include <events/reactionevent.h>
|
||||||
#include <events/redactionevent.h>
|
#include <events/redactionevent.h>
|
||||||
#include <events/roomavatarevent.h>
|
#include <events/roomavatarevent.h>
|
||||||
#include <events/roommemberevent.h>
|
#include <events/roommemberevent.h>
|
||||||
#include <events/simplestateevents.h>
|
#include <events/simplestateevents.h>
|
||||||
|
#include <settings.h>
|
||||||
|
#include <user.h>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtQml> // for qmlRegisterType()
|
#include <QtQml> // for qmlRegisterType()
|
||||||
@@ -42,7 +41,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const {
|
|||||||
|
|
||||||
MessageEventModel::MessageEventModel(QObject* parent)
|
MessageEventModel::MessageEventModel(QObject* parent)
|
||||||
: QAbstractListModel(parent), m_currentRoom(nullptr) {
|
: QAbstractListModel(parent), m_currentRoom(nullptr) {
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
qmlRegisterType<FileTransferInfo>();
|
qmlRegisterType<FileTransferInfo>();
|
||||||
qRegisterMetaType<FileTransferInfo>();
|
qRegisterMetaType<FileTransferInfo>();
|
||||||
qmlRegisterUncreatableType<EventStatus>(
|
qmlRegisterUncreatableType<EventStatus>(
|
||||||
@@ -64,7 +63,7 @@ void MessageEventModel::setRoom(SpectralRoom* room) {
|
|||||||
if (room) {
|
if (room) {
|
||||||
lastReadEventId = room->readMarkerEventId();
|
lastReadEventId = room->readMarkerEventId();
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
connect(m_currentRoom, &Room::aboutToAddNewMessages, this,
|
connect(m_currentRoom, &Room::aboutToAddNewMessages, this,
|
||||||
[=](RoomEventsRange events) {
|
[=](RoomEventsRange events) {
|
||||||
beginInsertRows({}, timelineBaseIndex(),
|
beginInsertRows({}, timelineBaseIndex(),
|
||||||
@@ -207,12 +206,12 @@ int MessageEventModel::refreshEventRoles(const QString& id,
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool hasValidTimestamp(const QMatrixClient::TimelineItem& ti) {
|
inline bool hasValidTimestamp(const Quotient::TimelineItem& ti) {
|
||||||
return ti->timestamp().isValid();
|
return ti->timestamp().isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime MessageEventModel::makeMessageTimestamp(
|
QDateTime MessageEventModel::makeMessageTimestamp(
|
||||||
const QMatrixClient::Room::rev_iter_t& baseIt) const {
|
const Quotient::Room::rev_iter_t& baseIt) const {
|
||||||
const auto& timeline = m_currentRoom->messageEvents();
|
const auto& timeline = m_currentRoom->messageEvents();
|
||||||
auto ts = baseIt->event()->timestamp();
|
auto ts = baseIt->event()->timestamp();
|
||||||
if (ts.isValid())
|
if (ts.isValid())
|
||||||
@@ -220,7 +219,7 @@ QDateTime MessageEventModel::makeMessageTimestamp(
|
|||||||
|
|
||||||
// The event is most likely redacted or just invalid.
|
// The event is most likely redacted or just invalid.
|
||||||
// Look for the nearest date around and slap zero time to it.
|
// Look for the nearest date around and slap zero time to it.
|
||||||
using QMatrixClient::TimelineItem;
|
using Quotient::TimelineItem;
|
||||||
auto rit = std::find_if(baseIt, timeline.rend(), hasValidTimestamp);
|
auto rit = std::find_if(baseIt, timeline.rend(), hasValidTimestamp);
|
||||||
if (rit != timeline.rend())
|
if (rit != timeline.rend())
|
||||||
return {rit->event()->timestamp().date(), {0, 0}, Qt::LocalTime};
|
return {rit->event()->timestamp().date(), {0, 0}, Qt::LocalTime};
|
||||||
@@ -269,16 +268,18 @@ int MessageEventModel::rowCount(const QModelIndex& parent) const {
|
|||||||
return m_currentRoom->timelineSize();
|
return m_currentRoom->timelineSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QVariantMap userAtEvent(SpectralUser* user, SpectralRoom* room, const RoomEvent& evt) {
|
inline QVariantMap userAtEvent(SpectralUser* user,
|
||||||
return QVariantMap{
|
SpectralRoom* room,
|
||||||
{"isLocalUser", user->id() == room->localUser()->id()},
|
const RoomEvent& evt) {
|
||||||
{"id", user->id()},
|
return QVariantMap{
|
||||||
{"avatarMediaId", user->avatarMediaId(room)},
|
{"isLocalUser", user->id() == room->localUser()->id()},
|
||||||
{"avatarUrl", user->avatarUrl(room)},
|
{"id", user->id()},
|
||||||
{"displayName", user->displayname(room)},
|
{"avatarMediaId", user->avatarMediaId(room)},
|
||||||
{"color", user->color()},
|
{"avatarUrl", user->avatarUrl(room)},
|
||||||
{"object", QVariant::fromValue(user)},
|
{"displayName", user->displayname(room)},
|
||||||
};
|
{"color", user->color()},
|
||||||
|
{"object", QVariant::fromValue(user)},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
||||||
@@ -340,9 +341,10 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
|||||||
return EventTypeRegistry::getMatrixType(evt.type());
|
return EventTypeRegistry::getMatrixType(evt.type());
|
||||||
|
|
||||||
if (role == AuthorRole) {
|
if (role == AuthorRole) {
|
||||||
auto author = static_cast<SpectralUser*>(isPending ? m_currentRoom->localUser()
|
auto author = static_cast<SpectralUser*>(
|
||||||
: m_currentRoom->user(evt.senderId()));
|
isPending ? m_currentRoom->localUser()
|
||||||
return userAtEvent(author, m_currentRoom, evt);
|
: m_currentRoom->user(evt.senderId()));
|
||||||
|
return userAtEvent(author, m_currentRoom, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == ContentTypeRole) {
|
if (role == ContentTypeRole) {
|
||||||
@@ -455,8 +457,9 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
|||||||
return QVariantMap{
|
return QVariantMap{
|
||||||
{"eventId", replyEventId},
|
{"eventId", replyEventId},
|
||||||
{"display", m_currentRoom->eventToString(replyEvt, Qt::RichText)},
|
{"display", m_currentRoom->eventToString(replyEvt, Qt::RichText)},
|
||||||
{"author",
|
{"author", userAtEvent(static_cast<SpectralUser*>(
|
||||||
userAtEvent(static_cast<SpectralUser*>(m_currentRoom->user(replyEvt.senderId())), m_currentRoom, evt)}};
|
m_currentRoom->user(replyEvt.senderId())),
|
||||||
|
m_currentRoom, evt)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == ShowAuthorRole) {
|
if (role == ShowAuthorRole) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#ifndef MESSAGEEVENTMODEL_H
|
#ifndef MESSAGEEVENTMODEL_H
|
||||||
#define MESSAGEEVENTMODEL_H
|
#define MESSAGEEVENTMODEL_H
|
||||||
|
|
||||||
|
#include <QtCore/QAbstractListModel>
|
||||||
|
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "spectralroom.h"
|
#include "spectralroom.h"
|
||||||
|
|
||||||
#include <QtCore/QAbstractListModel>
|
|
||||||
|
|
||||||
class MessageEventModel : public QAbstractListModel {
|
class MessageEventModel : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(SpectralRoom* room READ room WRITE setRoom NOTIFY roomChanged)
|
Q_PROPERTY(SpectralRoom* room READ room WRITE setRoom NOTIFY roomChanged)
|
||||||
@@ -72,7 +72,7 @@ class MessageEventModel : public QAbstractListModel {
|
|||||||
|
|
||||||
int timelineBaseIndex() const;
|
int timelineBaseIndex() const;
|
||||||
QDateTime makeMessageTimestamp(
|
QDateTime makeMessageTimestamp(
|
||||||
const QMatrixClient::Room::rev_iter_t& baseIt) const;
|
const Quotient::Room::rev_iter_t& baseIt) const;
|
||||||
QString renderDate(QDateTime timestamp) const;
|
QString renderDate(QDateTime timestamp) const;
|
||||||
|
|
||||||
void refreshLastUserEvents(int baseRow);
|
void refreshLastUserEvents(int baseRow);
|
||||||
|
|||||||
@@ -167,6 +167,24 @@ QVariant PublicRoomListModel::data(const QModelIndex& index, int role) const {
|
|||||||
if (role == TopicRole) {
|
if (role == TopicRole) {
|
||||||
return room.topic;
|
return room.topic;
|
||||||
}
|
}
|
||||||
|
if (role == RoomIDRole) {
|
||||||
|
return room.roomId;
|
||||||
|
}
|
||||||
|
if (role == MemberCountRole) {
|
||||||
|
return room.numJoinedMembers;
|
||||||
|
}
|
||||||
|
if (role == AllowGuestsRole) {
|
||||||
|
return room.guestCanJoin;
|
||||||
|
}
|
||||||
|
if (role == WorldReadableRole) {
|
||||||
|
return room.worldReadable;
|
||||||
|
}
|
||||||
|
if (role == IsJoinedRole) {
|
||||||
|
if (!m_connection)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return m_connection->room(room.roomId, JoinState::Join) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -177,6 +195,11 @@ QHash<int, QByteArray> PublicRoomListModel::roleNames() const {
|
|||||||
roles[NameRole] = "name";
|
roles[NameRole] = "name";
|
||||||
roles[AvatarRole] = "avatar";
|
roles[AvatarRole] = "avatar";
|
||||||
roles[TopicRole] = "topic";
|
roles[TopicRole] = "topic";
|
||||||
|
roles[RoomIDRole] = "roomID";
|
||||||
|
roles[MemberCountRole] = "memberCount";
|
||||||
|
roles[AllowGuestsRole] = "allowGuests";
|
||||||
|
roles[WorldReadableRole] = "worldReadable";
|
||||||
|
roles[IsJoinedRole] = "isJoined";
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,16 @@ class PublicRoomListModel : public QAbstractListModel {
|
|||||||
Q_PROPERTY(bool hasMore READ hasMore NOTIFY hasMoreChanged)
|
Q_PROPERTY(bool hasMore READ hasMore NOTIFY hasMoreChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum EventRoles { NameRole = Qt::DisplayRole + 1, AvatarRole, TopicRole };
|
enum EventRoles {
|
||||||
|
NameRole = Qt::DisplayRole + 1,
|
||||||
|
AvatarRole,
|
||||||
|
TopicRole,
|
||||||
|
RoomIDRole,
|
||||||
|
MemberCountRole,
|
||||||
|
AllowGuestsRole,
|
||||||
|
WorldReadableRole,
|
||||||
|
IsJoinedRole,
|
||||||
|
};
|
||||||
|
|
||||||
PublicRoomListModel(QObject* parent = nullptr);
|
PublicRoomListModel(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
#include "spectralroom.h"
|
#include "spectralroom.h"
|
||||||
|
|
||||||
#include "connection.h"
|
#include <cmark.h>
|
||||||
#include "user.h"
|
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QMimeDatabase>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
#include "csapi/account-data.h"
|
#include "csapi/account-data.h"
|
||||||
#include "csapi/content-repo.h"
|
#include "csapi/content-repo.h"
|
||||||
#include "csapi/leaving.h"
|
#include "csapi/leaving.h"
|
||||||
@@ -14,18 +22,7 @@
|
|||||||
#include "events/roommessageevent.h"
|
#include "events/roommessageevent.h"
|
||||||
#include "events/typingevent.h"
|
#include "events/typingevent.h"
|
||||||
#include "jobs/downloadfilejob.h"
|
#include "jobs/downloadfilejob.h"
|
||||||
|
#include "user.h"
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QImageReader>
|
|
||||||
#include <QMetaObject>
|
|
||||||
#include <QMimeDatabase>
|
|
||||||
#include <QTextDocument>
|
|
||||||
|
|
||||||
#include <cmark.h>
|
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
SpectralRoom::SpectralRoom(Connection* connection,
|
SpectralRoom::SpectralRoom(Connection* connection,
|
||||||
@@ -117,8 +114,7 @@ QString SpectralRoom::lastEvent() const {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
return user(evt->senderId())->displayname() +
|
return user(evt->senderId())->displayname() +
|
||||||
(evt->isStateEvent() ? " " : ": ") +
|
(evt->isStateEvent() ? " " : ": ") + eventToString(*evt);
|
||||||
eventToString(*evt);
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -127,7 +123,7 @@ bool SpectralRoom::isEventHighlighted(const RoomEvent* e) const {
|
|||||||
return highlights.contains(e);
|
return highlights.contains(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectralRoom::checkForHighlights(const QMatrixClient::TimelineItem& ti) {
|
void SpectralRoom::checkForHighlights(const Quotient::TimelineItem& ti) {
|
||||||
auto localUserId = localUser()->id();
|
auto localUserId = localUser()->id();
|
||||||
if (ti->senderId() == localUserId)
|
if (ti->senderId() == localUserId)
|
||||||
return;
|
return;
|
||||||
@@ -230,20 +226,21 @@ QString SpectralRoom::avatarMediaId() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString SpectralRoom::eventToString(const RoomEvent& evt,
|
QString SpectralRoom::eventToString(const RoomEvent& evt,
|
||||||
Qt::TextFormat format, bool removeReply) const {
|
Qt::TextFormat format,
|
||||||
|
bool removeReply) const {
|
||||||
const bool prettyPrint = (format == Qt::RichText);
|
const bool prettyPrint = (format == Qt::RichText);
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace Quotient;
|
||||||
return visit(
|
return visit(
|
||||||
evt,
|
evt,
|
||||||
[prettyPrint, removeReply](const RoomMessageEvent& e) {
|
[prettyPrint, removeReply](const RoomMessageEvent& e) {
|
||||||
using namespace MessageEventContent;
|
using namespace MessageEventContent;
|
||||||
|
|
||||||
if (prettyPrint && e.hasTextContent() &&
|
if (prettyPrint && e.hasTextContent() &&
|
||||||
e.mimeType().name() != "text/plain") {
|
e.mimeType().name() != "text/plain") {
|
||||||
auto htmlBody = static_cast<const TextContent*>(e.content())->body;
|
auto htmlBody = static_cast<const TextContent*>(e.content())->body;
|
||||||
if (removeReply) {
|
if (removeReply) {
|
||||||
htmlBody.remove(utils::removeRichReplyRegex);
|
htmlBody.remove(utils::removeRichReplyRegex);
|
||||||
}
|
}
|
||||||
htmlBody.replace(utils::userPillRegExp, "<b>\\1</b>");
|
htmlBody.replace(utils::userPillRegExp, "<b>\\1</b>");
|
||||||
htmlBody.replace(utils::strikethroughRegExp, "<s>\\1</s>");
|
htmlBody.replace(utils::strikethroughRegExp, "<s>\\1</s>");
|
||||||
@@ -255,24 +252,23 @@ QString SpectralRoom::eventToString(const RoomEvent& evt,
|
|||||||
auto fileCaption =
|
auto fileCaption =
|
||||||
e.content()->fileInfo()->originalName.toHtmlEscaped();
|
e.content()->fileInfo()->originalName.toHtmlEscaped();
|
||||||
if (fileCaption.isEmpty()) {
|
if (fileCaption.isEmpty()) {
|
||||||
fileCaption = prettyPrint
|
fileCaption = prettyPrint ? Quotient::prettyPrint(e.plainBody())
|
||||||
? QMatrixClient::prettyPrint(e.plainBody())
|
: e.plainBody();
|
||||||
: e.plainBody();
|
|
||||||
} else if (e.content()->fileInfo()->originalName != e.plainBody()) {
|
} else if (e.content()->fileInfo()->originalName != e.plainBody()) {
|
||||||
fileCaption = e.plainBody() + " | " + fileCaption;
|
fileCaption = e.plainBody() + " | " + fileCaption;
|
||||||
}
|
}
|
||||||
return !fileCaption.isEmpty() ? fileCaption : tr("a file");
|
return !fileCaption.isEmpty() ? fileCaption : tr("a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prettyPrint) {
|
if (prettyPrint) {
|
||||||
auto plainBody = e.plainBody();
|
auto plainBody = e.plainBody();
|
||||||
if (removeReply) {
|
if (removeReply) {
|
||||||
plainBody.remove(utils::removeReplyRegex);
|
plainBody.remove(utils::removeReplyRegex);
|
||||||
}
|
}
|
||||||
return QMatrixClient::prettyPrint(plainBody);
|
return Quotient::prettyPrint(plainBody);
|
||||||
}
|
}
|
||||||
if (removeReply) {
|
if (removeReply) {
|
||||||
return e.plainBody().remove(utils::removeReplyRegex);
|
return e.plainBody().remove(utils::removeReplyRegex);
|
||||||
}
|
}
|
||||||
return e.plainBody();
|
return e.plainBody();
|
||||||
},
|
},
|
||||||
@@ -364,9 +360,8 @@ QString SpectralRoom::eventToString(const RoomEvent& evt,
|
|||||||
return (e.topic().isEmpty())
|
return (e.topic().isEmpty())
|
||||||
? tr("cleared the topic")
|
? tr("cleared the topic")
|
||||||
: tr("set the topic to: %1")
|
: tr("set the topic to: %1")
|
||||||
.arg(prettyPrint
|
.arg(prettyPrint ? Quotient::prettyPrint(e.topic())
|
||||||
? QMatrixClient::prettyPrint(e.topic())
|
: e.topic());
|
||||||
: e.topic());
|
|
||||||
},
|
},
|
||||||
[](const RoomAvatarEvent&) { return tr("changed the room avatar"); },
|
[](const RoomAvatarEvent&) { return tr("changed the room avatar"); },
|
||||||
[](const EncryptionEvent&) {
|
[](const EncryptionEvent&) {
|
||||||
@@ -486,21 +481,20 @@ void SpectralRoom::postPlainMessage(const QString& text,
|
|||||||
if (isReply) {
|
if (isReply) {
|
||||||
const auto& replyEvt = **replyIt;
|
const auto& replyEvt = **replyIt;
|
||||||
|
|
||||||
QJsonObject json{
|
QJsonObject json{{"msgtype", msgTypeToString(type)},
|
||||||
{"msgtype", msgTypeToString(type)},
|
{"body", "> <" + replyEvt.senderId() + "> " +
|
||||||
{"body", "> <" + replyEvt.senderId() + "> " + eventToString(replyEvt) +
|
eventToString(replyEvt) + "\n\n" + text},
|
||||||
"\n\n" + text},
|
{"format", "org.matrix.custom.html"},
|
||||||
{"format", "org.matrix.custom.html"},
|
{"m.relates_to",
|
||||||
{"m.relates_to",
|
QJsonObject{{"m.in_reply_to",
|
||||||
QJsonObject{
|
QJsonObject{{"event_id", replyEventId}}}}},
|
||||||
{"m.in_reply_to", QJsonObject{{"event_id", replyEventId}}}}},
|
{"formatted_body",
|
||||||
{"formatted_body",
|
"<mx-reply><blockquote><a href=\"https://matrix.to/#/" +
|
||||||
"<mx-reply><blockquote><a href=\"https://matrix.to/#/" + id() + "/" +
|
id() + "/" + replyEventId +
|
||||||
replyEventId +
|
"\">In reply to</a> <a href=\"https://matrix.to/#/" +
|
||||||
"\">In reply to</a> <a href=\"https://matrix.to/#/" +
|
replyEvt.senderId() + "\">" + replyEvt.senderId() +
|
||||||
replyEvt.senderId() + "\">" + replyEvt.senderId() + "</a><br>" +
|
"</a><br>" + eventToString(replyEvt, Qt::RichText) +
|
||||||
eventToString(replyEvt, Qt::RichText) +
|
"</blockquote></mx-reply>" + text.toHtmlEscaped()}};
|
||||||
"</blockquote></mx-reply>" + text.toHtmlEscaped()}};
|
|
||||||
postJson("m.room.message", json);
|
postJson("m.room.message", json);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -521,21 +515,20 @@ void SpectralRoom::postHtmlMessage(const QString& text,
|
|||||||
if (isReply) {
|
if (isReply) {
|
||||||
const auto& replyEvt = **replyIt;
|
const auto& replyEvt = **replyIt;
|
||||||
|
|
||||||
QJsonObject json{
|
QJsonObject json{{"msgtype", msgTypeToString(type)},
|
||||||
{"msgtype", msgTypeToString(type)},
|
{"body", "> <" + replyEvt.senderId() + "> " +
|
||||||
{"body", "> <" + replyEvt.senderId() + "> " + eventToString(replyEvt) +
|
eventToString(replyEvt) + "\n\n" + text},
|
||||||
"\n\n" + text},
|
{"format", "org.matrix.custom.html"},
|
||||||
{"format", "org.matrix.custom.html"},
|
{"m.relates_to",
|
||||||
{"m.relates_to",
|
QJsonObject{{"m.in_reply_to",
|
||||||
QJsonObject{
|
QJsonObject{{"event_id", replyEventId}}}}},
|
||||||
{"m.in_reply_to", QJsonObject{{"event_id", replyEventId}}}}},
|
{"formatted_body",
|
||||||
{"formatted_body",
|
"<mx-reply><blockquote><a href=\"https://matrix.to/#/" +
|
||||||
"<mx-reply><blockquote><a href=\"https://matrix.to/#/" + id() + "/" +
|
id() + "/" + replyEventId +
|
||||||
replyEventId +
|
"\">In reply to</a> <a href=\"https://matrix.to/#/" +
|
||||||
"\">In reply to</a> <a href=\"https://matrix.to/#/" +
|
replyEvt.senderId() + "\">" + replyEvt.senderId() +
|
||||||
replyEvt.senderId() + "\">" + replyEvt.senderId() + "</a><br>" +
|
"</a><br>" + eventToString(replyEvt, Qt::RichText) +
|
||||||
eventToString(replyEvt, Qt::RichText) +
|
"</blockquote></mx-reply>" + html}};
|
||||||
"</blockquote></mx-reply>" + html}};
|
|
||||||
postJson("m.room.message", json);
|
postJson("m.room.message", json);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
#ifndef SpectralRoom_H
|
#ifndef SpectralRoom_H
|
||||||
#define SpectralRoom_H
|
#define SpectralRoom_H
|
||||||
|
|
||||||
#include "room.h"
|
|
||||||
#include "spectraluser.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <events/encryptionevent.h>
|
#include <events/encryptionevent.h>
|
||||||
#include <events/redactionevent.h>
|
#include <events/redactionevent.h>
|
||||||
#include <events/roomavatarevent.h>
|
#include <events/roomavatarevent.h>
|
||||||
@@ -16,7 +9,14 @@
|
|||||||
#include <events/roommessageevent.h>
|
#include <events/roommessageevent.h>
|
||||||
#include <events/simplestateevents.h>
|
#include <events/simplestateevents.h>
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "room.h"
|
||||||
|
#include "spectraluser.h"
|
||||||
|
|
||||||
|
using namespace Quotient;
|
||||||
|
|
||||||
class SpectralRoom : public Room {
|
class SpectralRoom : public Room {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -37,7 +37,7 @@ class SpectralRoom : public Room {
|
|||||||
QVariantList getUsersTyping() const;
|
QVariantList getUsersTyping() const;
|
||||||
|
|
||||||
QString lastEvent() const;
|
QString lastEvent() const;
|
||||||
bool isEventHighlighted(const QMatrixClient::RoomEvent* e) const;
|
bool isEventHighlighted(const Quotient::RoomEvent* e) const;
|
||||||
|
|
||||||
QDateTime lastActiveTime() const;
|
QDateTime lastActiveTime() const;
|
||||||
|
|
||||||
@@ -70,16 +70,17 @@ class SpectralRoom : public Room {
|
|||||||
QString avatarMediaId() const;
|
QString avatarMediaId() const;
|
||||||
|
|
||||||
QString eventToString(const RoomEvent& evt,
|
QString eventToString(const RoomEvent& evt,
|
||||||
Qt::TextFormat format = Qt::PlainText, bool removeReply = true) const;
|
Qt::TextFormat format = Qt::PlainText,
|
||||||
|
bool removeReply = true) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_cachedInput;
|
QString m_cachedInput;
|
||||||
QSet<const QMatrixClient::RoomEvent*> highlights;
|
QSet<const Quotient::RoomEvent*> highlights;
|
||||||
|
|
||||||
bool m_hasFileUploading = false;
|
bool m_hasFileUploading = false;
|
||||||
int m_fileUploadingProgress = 0;
|
int m_fileUploadingProgress = 0;
|
||||||
|
|
||||||
void checkForHighlights(const QMatrixClient::TimelineItem& ti);
|
void checkForHighlights(const Quotient::TimelineItem& ti);
|
||||||
|
|
||||||
void onAddNewTimelineEvents(timeline_iter_t from) override;
|
void onAddNewTimelineEvents(timeline_iter_t from) override;
|
||||||
void onAddHistoricalTimelineEvents(rev_iter_t from) override;
|
void onAddHistoricalTimelineEvents(rev_iter_t from) override;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#ifndef SpectralUser_H
|
#ifndef SpectralUser_H
|
||||||
#define SpectralUser_H
|
#define SpectralUser_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#include <QObject>
|
using namespace Quotient;
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
|
||||||
|
|
||||||
class SpectralUser : public User {
|
class SpectralUser : public User {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
UserListModel::UserListModel(QObject* parent)
|
UserListModel::UserListModel(QObject* parent)
|
||||||
: QAbstractListModel(parent), m_currentRoom(nullptr) {}
|
: QAbstractListModel(parent), m_currentRoom(nullptr) {}
|
||||||
|
|
||||||
void UserListModel::setRoom(QMatrixClient::Room* room) {
|
void UserListModel::setRoom(Quotient::Room* room) {
|
||||||
if (m_currentRoom == room)
|
if (m_currentRoom == room)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ void UserListModel::setRoom(QMatrixClient::Room* room) {
|
|||||||
emit roomChanged();
|
emit roomChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMatrixClient::User* UserListModel::userAt(QModelIndex index) const {
|
Quotient::User* UserListModel::userAt(QModelIndex index) const {
|
||||||
if (index.row() < 0 || index.row() >= m_users.size())
|
if (index.row() < 0 || index.row() >= m_users.size())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return m_users.at(index.row());
|
return m_users.at(index.row());
|
||||||
@@ -89,16 +89,16 @@ int UserListModel::rowCount(const QModelIndex& parent) const {
|
|||||||
return m_users.count();
|
return m_users.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserListModel::userAdded(QMatrixClient::User* user) {
|
void UserListModel::userAdded(Quotient::User* user) {
|
||||||
auto pos = findUserPos(user);
|
auto pos = findUserPos(user);
|
||||||
beginInsertRows(QModelIndex(), pos, pos);
|
beginInsertRows(QModelIndex(), pos, pos);
|
||||||
m_users.insert(pos, user);
|
m_users.insert(pos, user);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
connect(user, &QMatrixClient::User::avatarChanged, this,
|
connect(user, &Quotient::User::avatarChanged, this,
|
||||||
&UserListModel::avatarChanged);
|
&UserListModel::avatarChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserListModel::userRemoved(QMatrixClient::User* user) {
|
void UserListModel::userRemoved(Quotient::User* user) {
|
||||||
auto pos = findUserPos(user);
|
auto pos = findUserPos(user);
|
||||||
if (pos != m_users.size()) {
|
if (pos != m_users.size()) {
|
||||||
beginRemoveRows(QModelIndex(), pos, pos);
|
beginRemoveRows(QModelIndex(), pos, pos);
|
||||||
@@ -109,7 +109,7 @@ void UserListModel::userRemoved(QMatrixClient::User* user) {
|
|||||||
qWarning() << "Trying to remove a room member not in the user list";
|
qWarning() << "Trying to remove a room member not in the user list";
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserListModel::refresh(QMatrixClient::User* user, QVector<int> roles) {
|
void UserListModel::refresh(Quotient::User* user, QVector<int> roles) {
|
||||||
auto pos = findUserPos(user);
|
auto pos = findUserPos(user);
|
||||||
if (pos != m_users.size())
|
if (pos != m_users.size())
|
||||||
emit dataChanged(index(pos), index(pos), roles);
|
emit dataChanged(index(pos), index(pos), roles);
|
||||||
@@ -117,8 +117,8 @@ void UserListModel::refresh(QMatrixClient::User* user, QVector<int> roles) {
|
|||||||
qWarning() << "Trying to access a room member not in the user list";
|
qWarning() << "Trying to access a room member not in the user list";
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserListModel::avatarChanged(QMatrixClient::User* user,
|
void UserListModel::avatarChanged(Quotient::User* user,
|
||||||
const QMatrixClient::Room* context) {
|
const Quotient::Room* context) {
|
||||||
if (context == m_currentRoom)
|
if (context == m_currentRoom)
|
||||||
refresh(user, {AvatarRole});
|
refresh(user, {AvatarRole});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user