Why can't we be friends
Update the UX to refer to structure direct chats as friends. The direct chats are pulled into their own tab in the space drawer. The `UserDetailDialog` is also updated to check whether a direct chat already exists and if not ask to invite as friend. 
This commit is contained in:
@@ -368,6 +368,9 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == ReplacementIdRole) {
|
if (role == ReplacementIdRole) {
|
||||||
return room->successorId();
|
return room->successorId();
|
||||||
}
|
}
|
||||||
|
if (role == IsDirectChat) {
|
||||||
|
return room->isDirectChat();
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@@ -401,6 +404,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
|
|||||||
roles[IsSpaceRole] = "isSpace";
|
roles[IsSpaceRole] = "isSpace";
|
||||||
roles[RoomIdRole] = "roomId";
|
roles[RoomIdRole] = "roomId";
|
||||||
roles[IsChildSpaceRole] = "isChildSpace";
|
roles[IsChildSpaceRole] = "isChildSpace";
|
||||||
|
roles[IsDirectChat] = "isDirectChat";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +416,7 @@ QString RoomListModel::categoryName(int category)
|
|||||||
case NeoChatRoomType::Favorite:
|
case NeoChatRoomType::Favorite:
|
||||||
return i18n("Favorite");
|
return i18n("Favorite");
|
||||||
case NeoChatRoomType::Direct:
|
case NeoChatRoomType::Direct:
|
||||||
return i18n("Direct Messages");
|
return i18n("Friends");
|
||||||
case NeoChatRoomType::Normal:
|
case NeoChatRoomType::Normal:
|
||||||
return i18n("Normal");
|
return i18n("Normal");
|
||||||
case NeoChatRoomType::Deprioritized:
|
case NeoChatRoomType::Deprioritized:
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ public:
|
|||||||
IsSpaceRole, /**< Whether the room is a space. */
|
IsSpaceRole, /**< Whether the room is a space. */
|
||||||
IsChildSpaceRole, /**< Whether this space is a child of a different space. */
|
IsChildSpaceRole, /**< Whether this space is a child of a different space. */
|
||||||
ReplacementIdRole, /**< The room id of the room replacing this one, if any. */
|
ReplacementIdRole, /**< The room id of the room replacing this one, if any. */
|
||||||
|
IsDirectChat, /**< Whether this room is a direct chat. */
|
||||||
};
|
};
|
||||||
Q_ENUM(EventRoles)
|
Q_ENUM(EventRoles)
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,21 @@ bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex
|
|||||||
{
|
{
|
||||||
Q_UNUSED(source_parent);
|
Q_UNUSED(source_parent);
|
||||||
|
|
||||||
|
bool acceptRoom =
|
||||||
|
sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::DisplayNameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
||||||
|
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsSpaceRole).toBool() == false;
|
||||||
|
|
||||||
|
bool isDirectChat = sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsDirectChat).toBool();
|
||||||
|
// In `show direct chats` mode we only care about whether or not it's a direct chat or if the filter string matches.'
|
||||||
|
if (m_mode == DirectChats) {
|
||||||
|
return isDirectChat && acceptRoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When not in `show direct chats` mode, filter them out.
|
||||||
|
if (isDirectChat && m_mode == Rooms) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() == QStringLiteral("upgraded")
|
if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() == QStringLiteral("upgraded")
|
||||||
&& dynamic_cast<RoomListModel *>(sourceModel())
|
&& dynamic_cast<RoomListModel *>(sourceModel())
|
||||||
->connection()
|
->connection()
|
||||||
@@ -90,10 +105,6 @@ bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptRoom =
|
|
||||||
sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::DisplayNameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
|
|
||||||
&& sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsSpaceRole).toBool() == false;
|
|
||||||
|
|
||||||
if (m_activeSpaceId.isEmpty()) {
|
if (m_activeSpaceId.isEmpty()) {
|
||||||
return acceptRoom;
|
return acceptRoom;
|
||||||
} else {
|
} else {
|
||||||
@@ -116,4 +127,20 @@ void SortFilterRoomListModel::setActiveSpaceId(const QString &spaceId)
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortFilterRoomListModel::Mode SortFilterRoomListModel::mode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortFilterRoomListModel::setMode(SortFilterRoomListModel::Mode mode)
|
||||||
|
{
|
||||||
|
if (m_mode == mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mode = mode;
|
||||||
|
Q_EMIT modeChanged();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_sortfilterroomlistmodel.cpp"
|
#include "moc_sortfilterroomlistmodel.cpp"
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ class SortFilterRoomListModel : public QSortFilterProxyModel
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(QString activeSpaceId READ activeSpaceId WRITE setActiveSpaceId NOTIFY activeSpaceIdChanged)
|
Q_PROPERTY(QString activeSpaceId READ activeSpaceId WRITE setActiveSpaceId NOTIFY activeSpaceIdChanged)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether only direct chats should be shown.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum RoomSortOrder {
|
enum RoomSortOrder {
|
||||||
Alphabetical,
|
Alphabetical,
|
||||||
@@ -55,6 +60,13 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(RoomSortOrder)
|
Q_ENUM(RoomSortOrder)
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
Rooms,
|
||||||
|
DirectChats,
|
||||||
|
All,
|
||||||
|
};
|
||||||
|
Q_ENUM(Mode)
|
||||||
|
|
||||||
explicit SortFilterRoomListModel(QObject *parent = nullptr);
|
explicit SortFilterRoomListModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
void setRoomSortOrder(RoomSortOrder sortOrder);
|
void setRoomSortOrder(RoomSortOrder sortOrder);
|
||||||
@@ -66,6 +78,9 @@ public:
|
|||||||
QString activeSpaceId() const;
|
QString activeSpaceId() const;
|
||||||
void setActiveSpaceId(const QString &spaceId);
|
void setActiveSpaceId(const QString &spaceId);
|
||||||
|
|
||||||
|
Mode mode() const;
|
||||||
|
void setMode(Mode mode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Returns true if the value of source_left is less than source_right.
|
* @brief Returns true if the value of source_left is less than source_right.
|
||||||
@@ -85,9 +100,11 @@ Q_SIGNALS:
|
|||||||
void roomSortOrderChanged();
|
void roomSortOrderChanged();
|
||||||
void filterTextChanged();
|
void filterTextChanged();
|
||||||
void activeSpaceIdChanged();
|
void activeSpaceIdChanged();
|
||||||
|
void modeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RoomSortOrder m_sortOrder = Categories;
|
RoomSortOrder m_sortOrder = Categories;
|
||||||
|
Mode m_mode = All;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
QString m_activeSpaceId;
|
QString m_activeSpaceId;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "jobs/neochatdeactivateaccountjob.h"
|
#include "jobs/neochatdeactivateaccountjob.h"
|
||||||
#include "roommanager.h"
|
#include "roommanager.h"
|
||||||
|
|
||||||
|
#include <Quotient/connection.h>
|
||||||
|
#include <Quotient/quotient_common.h>
|
||||||
#include <qt6keychain/keychain.h>
|
#include <qt6keychain/keychain.h>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
#include <Quotient/database.h>
|
#include <Quotient/database.h>
|
||||||
#include <Quotient/jobs/downloadfilejob.h>
|
#include <Quotient/jobs/downloadfilejob.h>
|
||||||
#include <Quotient/qt_connection_util.h>
|
#include <Quotient/qt_connection_util.h>
|
||||||
|
#include <Quotient/room.h>
|
||||||
#include <Quotient/settings.h>
|
#include <Quotient/settings.h>
|
||||||
#include <Quotient/user.h>
|
#include <Quotient/user.h>
|
||||||
|
|
||||||
@@ -55,6 +58,34 @@ NeoChatConnection::NeoChatConnection(QObject *parent)
|
|||||||
RoomManager::instance().warning(i18n("File too large to download."), i18n("Contact your matrix server administrator for support."));
|
RoomManager::instance().warning(i18n("File too large to download."), i18n("Contact your matrix server administrator for support."));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(this, &NeoChatConnection::directChatsListChanged, this, [this](DirectChatsMap additions, DirectChatsMap removals) {
|
||||||
|
Q_EMIT directChatInvitesChanged();
|
||||||
|
for (const auto &chatId : additions) {
|
||||||
|
if (const auto chat = room(chatId)) {
|
||||||
|
connect(chat, &Room::unreadStatsChanged, this, [this]() {
|
||||||
|
Q_EMIT directChatNotificationsChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &chatId : removals) {
|
||||||
|
if (const auto chat = room(chatId)) {
|
||||||
|
disconnect(chat, &Room::unreadStatsChanged, this, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(this, &NeoChatConnection::joinedRoom, this, [this](Room *room) {
|
||||||
|
if (room->isDirectChat()) {
|
||||||
|
connect(room, &Room::unreadStatsChanged, this, [this]() {
|
||||||
|
Q_EMIT directChatNotificationsChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(this, &NeoChatConnection::leftRoom, this, [this](Room *room, Room *prev) {
|
||||||
|
Q_UNUSED(room)
|
||||||
|
if (prev && prev->isDirectChat()) {
|
||||||
|
Q_EMIT directChatInvitesChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NeoChatConnection::NeoChatConnection(const QUrl &server, QObject *parent)
|
NeoChatConnection::NeoChatConnection(const QUrl &server, QObject *parent)
|
||||||
@@ -65,6 +96,34 @@ NeoChatConnection::NeoChatConnection(const QUrl &server, QObject *parent)
|
|||||||
Q_EMIT labelChanged();
|
Q_EMIT labelChanged();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(this, &NeoChatConnection::directChatsListChanged, this, [this](DirectChatsMap additions, DirectChatsMap removals) {
|
||||||
|
Q_EMIT directChatInvitesChanged();
|
||||||
|
for (const auto &chatId : additions) {
|
||||||
|
if (const auto chat = room(chatId)) {
|
||||||
|
connect(chat, &Room::unreadStatsChanged, this, [this]() {
|
||||||
|
Q_EMIT directChatNotificationsChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &chatId : removals) {
|
||||||
|
if (const auto chat = room(chatId)) {
|
||||||
|
disconnect(chat, &Room::unreadStatsChanged, this, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(this, &NeoChatConnection::joinedRoom, this, [this](Room *room) {
|
||||||
|
if (room->isDirectChat()) {
|
||||||
|
connect(room, &Room::unreadStatsChanged, this, [this]() {
|
||||||
|
Q_EMIT directChatNotificationsChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(this, &NeoChatConnection::leftRoom, this, [this](Room *room, Room *prev) {
|
||||||
|
Q_UNUSED(room)
|
||||||
|
if (prev && prev->isDirectChat()) {
|
||||||
|
Q_EMIT directChatInvitesChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeoChatConnection::logout(bool serverSideLogout)
|
void NeoChatConnection::logout(bool serverSideLogout)
|
||||||
@@ -244,6 +303,11 @@ void NeoChatConnection::createSpace(const QString &name, const QString &topic, c
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NeoChatConnection::directChatExists(Quotient::User *user)
|
||||||
|
{
|
||||||
|
return directChats().contains(user);
|
||||||
|
}
|
||||||
|
|
||||||
void NeoChatConnection::openOrCreateDirectChat(User *user)
|
void NeoChatConnection::openOrCreateDirectChat(User *user)
|
||||||
{
|
{
|
||||||
const auto existing = directChats();
|
const auto existing = directChats();
|
||||||
@@ -258,6 +322,32 @@ void NeoChatConnection::openOrCreateDirectChat(User *user)
|
|||||||
requestDirectChat(user);
|
requestDirectChat(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qsizetype NeoChatConnection::directChatNotifications() const
|
||||||
|
{
|
||||||
|
qsizetype notifications = 0;
|
||||||
|
QStringList added; // The same ID can be in the list multiple times.
|
||||||
|
for (const auto &chatId : directChats()) {
|
||||||
|
if (!added.contains(chatId)) {
|
||||||
|
if (const auto chat = room(chatId)) {
|
||||||
|
notifications += chat->notificationCount();
|
||||||
|
added += chatId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NeoChatConnection::directChatInvites() const
|
||||||
|
{
|
||||||
|
auto inviteRooms = rooms(JoinState::Invite);
|
||||||
|
for (const auto inviteRoom : inviteRooms) {
|
||||||
|
if (inviteRoom->isDirectChat()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QCoro::Task<void> NeoChatConnection::setupPushNotifications(QString endpoint)
|
QCoro::Task<void> NeoChatConnection::setupPushNotifications(QString endpoint)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
#ifdef HAVE_KUNIFIEDPUSH
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ class NeoChatConnection : public Quotient::Connection
|
|||||||
Q_PROPERTY(QString deviceKey READ deviceKey CONSTANT)
|
Q_PROPERTY(QString deviceKey READ deviceKey CONSTANT)
|
||||||
Q_PROPERTY(QString encryptionKey READ encryptionKey CONSTANT)
|
Q_PROPERTY(QString encryptionKey READ encryptionKey CONSTANT)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The total number of notifications for all direct chats.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(qsizetype directChatNotifications READ directChatNotifications NOTIFY directChatNotificationsChanged)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether there is at least one invite to a direct chat.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(bool directChatInvites READ directChatInvites NOTIFY directChatInvitesChanged)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether NeoChat is currently able to connect to the server.
|
* @brief Whether NeoChat is currently able to connect to the server.
|
||||||
*/
|
*/
|
||||||
@@ -79,6 +89,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
Q_INVOKABLE void createSpace(const QString &name, const QString &topic, const QString &parent = {}, bool setChildParent = false);
|
Q_INVOKABLE void createSpace(const QString &name, const QString &topic, const QString &parent = {}, bool setChildParent = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether a direct chat with the user exists.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE bool directChatExists(Quotient::User *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Join a direct chat with the given user.
|
* @brief Join a direct chat with the given user.
|
||||||
*
|
*
|
||||||
@@ -86,6 +101,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
|
Q_INVOKABLE void openOrCreateDirectChat(Quotient::User *user);
|
||||||
|
|
||||||
|
qsizetype directChatNotifications() const;
|
||||||
|
bool directChatInvites() const;
|
||||||
|
|
||||||
// note: this is intentionally a copied QString because
|
// note: this is intentionally a copied QString because
|
||||||
// the reference could be destroyed before the task is finished
|
// the reference could be destroyed before the task is finished
|
||||||
QCoro::Task<void> setupPushNotifications(QString endpoint);
|
QCoro::Task<void> setupPushNotifications(QString endpoint);
|
||||||
@@ -97,6 +115,8 @@ public:
|
|||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void labelChanged();
|
void labelChanged();
|
||||||
|
void directChatNotificationsChanged();
|
||||||
|
void directChatInvitesChanged();
|
||||||
void isOnlineChanged();
|
void isOnlineChanged();
|
||||||
void passwordStatus(NeoChatConnection::PasswordStatus status);
|
void passwordStatus(NeoChatConnection::PasswordStatus status);
|
||||||
void userConsentRequired(QUrl url);
|
void userConsentRequired(QUrl url);
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ Kirigami.Page {
|
|||||||
listView.currentIndex = sortFilterRoomListModel.mapFromSource(itemSelection.currentIndex).row
|
listView.currentIndex = sortFilterRoomListModel.mapFromSource(itemSelection.currentIndex).row
|
||||||
}
|
}
|
||||||
activeSpaceId: spaceDrawer.selectedSpaceId
|
activeSpaceId: spaceDrawer.selectedSpaceId
|
||||||
|
mode: spaceDrawer.showDirectChats ? SortFilterRoomListModel.DirectChats : SortFilterRoomListModel.Rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ QQC2.Control {
|
|||||||
|
|
||||||
property string selectedSpaceId
|
property string selectedSpaceId
|
||||||
|
|
||||||
|
property bool showDirectChats: false
|
||||||
|
|
||||||
contentItem: Loader {
|
contentItem: Loader {
|
||||||
id: sidebarColumn
|
id: sidebarColumn
|
||||||
z: 0
|
z: 0
|
||||||
@@ -86,8 +88,56 @@ QQC2.Control {
|
|||||||
source: "globe"
|
source: "globe"
|
||||||
}
|
}
|
||||||
|
|
||||||
checked: root.selectedSpaceId === ""
|
checked: root.selectedSpaceId === "" && root.showDirectChats === false
|
||||||
onClicked: root.selectedSpaceId = ""
|
onClicked: {
|
||||||
|
root.showDirectChats = false
|
||||||
|
root.selectedSpaceId = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AvatarTabButton {
|
||||||
|
id: directChatButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width - Kirigami.Units.smallSpacing
|
||||||
|
Layout.maximumHeight: width - Kirigami.Units.smallSpacing
|
||||||
|
Layout.topMargin: Kirigami.Units.smallSpacing / 2
|
||||||
|
|
||||||
|
text: i18nc("@button View all one-on-one chats with your friends.", "Friends")
|
||||||
|
contentItem: Kirigami.Icon {
|
||||||
|
source: "system-users"
|
||||||
|
}
|
||||||
|
|
||||||
|
checked: root.showDirectChats === true
|
||||||
|
onClicked: {
|
||||||
|
root.showDirectChats = true
|
||||||
|
root.selectedSpaceId = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Label {
|
||||||
|
id: notificationCountLabel
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Kirigami.Units.smallSpacing / 2
|
||||||
|
z: 1
|
||||||
|
width: Math.max(notificationCountTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 2, height)
|
||||||
|
height: Kirigami.Units.iconSizes.smallMedium
|
||||||
|
|
||||||
|
text: root.connection.directChatNotifications > 0 ? root.connection.directChatNotifications : ""
|
||||||
|
visible: root.connection.directChatNotifications > 0 || root.connection.directChatInvites
|
||||||
|
color: Kirigami.Theme.textColor
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
background: Rectangle {
|
||||||
|
visible: true
|
||||||
|
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||||
|
color: Kirigami.Theme.positiveTextColor
|
||||||
|
radius: height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: notificationCountTextMetrics
|
||||||
|
text: notificationCountLabel.text
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
@@ -117,7 +167,10 @@ QQC2.Control {
|
|||||||
text: displayName
|
text: displayName
|
||||||
source: avatar ? ("image://mxc/" + avatar) : ""
|
source: avatar ? ("image://mxc/" + avatar) : ""
|
||||||
|
|
||||||
onSelected: root.selectedSpaceId = roomId
|
onSelected: {
|
||||||
|
root.showDirectChats = false
|
||||||
|
root.selectedSpaceId = roomId
|
||||||
|
}
|
||||||
checked: root.selectedSpaceId === roomId
|
checked: root.selectedSpaceId === roomId
|
||||||
onContextMenuRequested: root.createContextMenu(currentRoom)
|
onContextMenuRequested: root.createContextMenu(currentRoom)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ Kirigami.Dialog {
|
|||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
visible: !root.user.isLocalUser
|
visible: !root.user.isLocalUser
|
||||||
action: Kirigami.Action {
|
action: Kirigami.Action {
|
||||||
text: i18n("Open a private chat")
|
text: root.room.connection.directChatExists(root.user.object) ? i18nc("%1 is the name of the user.", "Chat with %1", root.user.displayName) : i18n("Invite to private chat")
|
||||||
icon.name: "document-send"
|
icon.name: "document-send"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.room.connection.openOrCreateDirectChat(root.user.object)
|
root.room.connection.openOrCreateDirectChat(root.user.object)
|
||||||
|
|||||||
Reference in New Issue
Block a user