user details dialog fixes
This commit is contained in:
@@ -114,8 +114,8 @@ Kirigami.ApplicationWindow {
|
||||
}).open();
|
||||
}
|
||||
|
||||
function onShowUserDetail(user) {
|
||||
root.showUserDetail(user);
|
||||
function onShowUserDetail(user, room) {
|
||||
root.showUserDetail(user, room);
|
||||
}
|
||||
|
||||
function goToEvent(event) {
|
||||
@@ -351,9 +351,9 @@ Kirigami.ApplicationWindow {
|
||||
dialog.closeDialog()
|
||||
})
|
||||
}
|
||||
function showUserDetail(user) {
|
||||
function showUserDetail(user, room) {
|
||||
Qt.createComponent("org.kde.neochat", "UserDetailDialog").createObject(root.QQC2.ApplicationWindow.window, {
|
||||
room: RoomManager.currentRoom ? RoomManager.currentRoom : null,
|
||||
room: room,
|
||||
user: user,
|
||||
connection: root.connection
|
||||
}).open();
|
||||
|
||||
@@ -19,21 +19,8 @@ Kirigami.Dialog {
|
||||
// This dialog is sometimes used outside the context of a room, e.g., when scanning a user's QR code.
|
||||
// Make sure that code is prepared to deal with this property being null
|
||||
property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The user's profile object.
|
||||
*
|
||||
* Required to interact with the profile and perform action like ignoring.
|
||||
*/
|
||||
property var user
|
||||
|
||||
/**
|
||||
* @brief The RoomMember object for the user in the current room.
|
||||
*
|
||||
* Required to visualise the user.
|
||||
*/
|
||||
property var member: root.room.member(user.id)
|
||||
|
||||
property NeoChatConnection connection
|
||||
|
||||
leftPadding: 0
|
||||
@@ -61,9 +48,9 @@ Kirigami.Dialog {
|
||||
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
||||
|
||||
name: root.member.displayName
|
||||
source: root.member.avatarUrl
|
||||
color: root.member.color
|
||||
name: root.room ? root.room.member(root.user.id).displayName : root.user.displayName
|
||||
source: root.room ? root.room.member(root.user.id).avatarUrl : root.user.avatarUrl
|
||||
color: root.room ? root.room.member(root.user.id).color : QmlUtils.getUserColor(root.user.hueF)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
@@ -76,13 +63,13 @@ Kirigami.Dialog {
|
||||
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
text: root.user.displayName
|
||||
text: root.room ? root.room.member(root.user.id).displayName : root.user.displayName
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Kirigami.SelectableLabel {
|
||||
textFormat: TextEdit.PlainText
|
||||
text: root.member.id
|
||||
text: root.user.id
|
||||
}
|
||||
}
|
||||
QQC2.AbstractButton {
|
||||
@@ -91,16 +78,16 @@ Kirigami.Dialog {
|
||||
contentItem: Barcode {
|
||||
id: barcode
|
||||
barcodeType: Barcode.QRCode
|
||||
content: "https://matrix.to/#/" + root.member.id
|
||||
content: "https://matrix.to/#/" + root.user.id
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
let map = qrMaximizeComponent.createObject(parent, {
|
||||
text: barcode.content,
|
||||
title: root.member.displayName,
|
||||
subtitle: root.member.id,
|
||||
avatarColor: root.member.color,
|
||||
avatarSource: root.member.avatarUrl,
|
||||
title: root.room ? root.room.member(root.user.id).displayName : root.user.displayName,
|
||||
subtitle: root.user.id,
|
||||
avatarColor: root.room?.member(root.user.id).color,
|
||||
avatarSource: root.room? root.room.member(root.user.id).avatarUrl : root.user.avatarUrl
|
||||
});
|
||||
root.close();
|
||||
map.open();
|
||||
@@ -117,46 +104,46 @@ Kirigami.Dialog {
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: !root.member.isLocalMember
|
||||
visible: root.user.id !== root.connection.localUserId && !!root.user
|
||||
action: Kirigami.Action {
|
||||
text: !!root.user && root.connection.isIgnored(root.user) ? i18n("Unignore this user") : i18n("Ignore this user")
|
||||
text: !!root.user && root.connection.isIgnored(root.user.id) ? i18n("Unignore this user") : i18n("Ignore this user")
|
||||
icon.name: "im-invisible-user"
|
||||
onTriggered: {
|
||||
root.close();
|
||||
root.connection.isIgnored(root.user) ? root.connection.removeFromIgnoredUsers(root.user) : root.connection.addToIgnoredUsers(root.user);
|
||||
root.connection.isIgnored(root.user.id) ? root.connection.removeFromIgnoredUsers(root.user.id) : root.connection.addToIgnoredUsers(root.user.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: root.room && !root.member.isLocalMember && room.canSendState("kick") && room.containsUser(root.member.id) && room.getUserPowerLevel(root.member.id) < room.getUserPowerLevel(root.room.localMember.id)
|
||||
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("kick") && room.containsUser(root.user.id) && room.getUserPowerLevel(root.user.id) < room.getUserPowerLevel(root.connection.localUserId)
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Kick this user")
|
||||
icon.name: "im-kick-user"
|
||||
onTriggered: {
|
||||
root.room.kickMember(root.member.id);
|
||||
root.room.kickMember(root.user.id);
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: root.room && !root.member.isLocalMember && room.canSendState("invite") && !room.containsUser(root.member.id)
|
||||
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("invite") && !room.containsUser(root.user.id)
|
||||
|
||||
action: Kirigami.Action {
|
||||
enabled: root.room && !root.room.isUserBanned(root.member.id)
|
||||
enabled: root.room && !root.room.isUserBanned(root.user.id)
|
||||
text: i18n("Invite this user")
|
||||
icon.name: "list-add-user"
|
||||
onTriggered: {
|
||||
root.room.inviteToRoom(root.member.id);
|
||||
root.room.inviteToRoom(root.user.id);
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: root.room && !root.member.isLocalMember && room.canSendState("ban") && !room.isUserBanned(root.member.id) && room.getUserPowerLevel(root.member.id) < room.getUserPowerLevel(root.room.localMember.id)
|
||||
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("ban") && !room.isUserBanned(root.user.id) && room.getUserPowerLevel(root.user.id) < room.getUserPowerLevel(root.connection.localUserId)
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Ban this user")
|
||||
@@ -165,7 +152,7 @@ Kirigami.Dialog {
|
||||
onTriggered: {
|
||||
(root.QQC2.ApplicationWindow.window as Kirigami.ApplicationWindow).pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'BanSheet'), {
|
||||
room: root.room,
|
||||
userId: root.member.id
|
||||
userId: root.user.id
|
||||
}, {
|
||||
title: i18nc("@title", "Ban User"),
|
||||
width: Kirigami.Units.gridUnit * 25
|
||||
@@ -176,14 +163,14 @@ Kirigami.Dialog {
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: root.room && !root.member.isLocalMember && room.canSendState("ban") && room.isUserBanned(root.member.id)
|
||||
visible: root.room && root.user.id !== root.connection.localUserId && room.canSendState("ban") && room.isUserBanned(root.user.id)
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Unban this user")
|
||||
icon.name: "im-irc"
|
||||
icon.color: Kirigami.Theme.negativeTextColor
|
||||
onTriggered: {
|
||||
root.room.unban(root.member.id);
|
||||
root.room.unban(root.user.id);
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
@@ -197,8 +184,8 @@ Kirigami.Dialog {
|
||||
onTriggered: {
|
||||
let dialog = powerLevelDialog.createObject(this, {
|
||||
room: root.room,
|
||||
userId: root.member.id,
|
||||
powerLevel: root.room.getUserPowerLevel(root.member.id)
|
||||
userId: root.user.id,
|
||||
powerLevel: root.room.getUserPowerLevel(root.user.id)
|
||||
});
|
||||
dialog.open();
|
||||
root.close();
|
||||
@@ -214,7 +201,7 @@ Kirigami.Dialog {
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: root.room && (root.member.isLocalUser || room.canSendState("redact"))
|
||||
visible: root.room && (root.user.id === root.connection.localUserId || room.canSendState("redact"))
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Remove recent messages by this user")
|
||||
@@ -223,7 +210,7 @@ Kirigami.Dialog {
|
||||
onTriggered: {
|
||||
applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'RemoveSheet'), {
|
||||
room: root.room,
|
||||
userId: root.member.id
|
||||
userId: root.user.id
|
||||
}, {
|
||||
title: i18nc("@title", "Remove Messages"),
|
||||
width: Kirigami.Units.gridUnit * 25
|
||||
@@ -234,12 +221,12 @@ Kirigami.Dialog {
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
visible: !root.member.isLocalMember
|
||||
visible: root.user.id !== root.connection.localUserId
|
||||
action: Kirigami.Action {
|
||||
text: root.connection.directChatExists(root.user.object) ? i18nc("%1 is the name of the user.", "Chat with %1", root.user.escapedDisplayName) : i18n("Invite to private chat")
|
||||
text: root.connection.directChatExists(root.user) ? i18nc("%1 is the name of the user.", "Chat with %1", root.room ? root.room.member(root.user.id).htmlSafeDisplayName : QmlUtils.escapeString(root.user.displayName)) : i18n("Invite to private chat")
|
||||
icon.name: "document-send"
|
||||
onTriggered: {
|
||||
root.room.connection.openOrCreateDirectChat(root.user);
|
||||
root.connection.openOrCreateDirectChat(root.user.id);
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
@@ -250,7 +237,7 @@ Kirigami.Dialog {
|
||||
text: i18n("Copy link")
|
||||
icon.name: "username-copy"
|
||||
onTriggered: {
|
||||
Clipboard.saveText("https://matrix.to/#/" + root.member.id);
|
||||
Clipboard.saveText("https://matrix.to/#/" + root.user.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,8 +146,10 @@ void RoomManager::resolveResource(const QString &idOrUri, const QString &action)
|
||||
if ((uri.type() == Uri::RoomAlias || uri.type() == Uri::RoomId) && action != "no_join"_ls) {
|
||||
Q_EMIT askJoinRoom(uri.primaryId());
|
||||
}
|
||||
} else { // Invalid cases should have been eliminated earlier
|
||||
Q_ASSERT(result == Quotient::UriResolved);
|
||||
} else {
|
||||
if (result != Quotient::UriResolved) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uri.type() == Uri::RoomAlias || uri.type() == Uri::RoomId) {
|
||||
connect(
|
||||
@@ -255,9 +257,9 @@ void RoomManager::openRoomForActiveConnection()
|
||||
|
||||
UriResolveResult RoomManager::visitUser(User *user, const QString &action)
|
||||
{
|
||||
if (action == "mention"_ls || action.isEmpty()) {
|
||||
if (action == "mention"_ls || action == "qr"_ls || action.isEmpty()) {
|
||||
user->load();
|
||||
Q_EMIT showUserDetail(user);
|
||||
Q_EMIT showUserDetail(user, action == "qr"_ls ? nullptr : currentRoom());
|
||||
} else if (action == "_interactive"_ls) {
|
||||
user->requestDirectChat();
|
||||
} else if (action == "chat"_ls) {
|
||||
|
||||
@@ -261,7 +261,7 @@ Q_SIGNALS:
|
||||
* Ask current room to open the user's details for the give user.
|
||||
* This assumes the user is loaded.
|
||||
*/
|
||||
void showUserDetail(const Quotient::User *user);
|
||||
void showUserDetail(const Quotient::User *user, const NeoChatRoom *room);
|
||||
|
||||
/**
|
||||
* @brief Request a media item is shown maximized.
|
||||
|
||||
@@ -7,9 +7,23 @@
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
bool QmlUtils::isValidJson(const QByteArray &json)
|
||||
{
|
||||
return !QJsonDocument::fromJson(json).isNull();
|
||||
}
|
||||
|
||||
QString QmlUtils::escapeString(const QString &string)
|
||||
{
|
||||
return string.toHtmlEscaped();
|
||||
}
|
||||
|
||||
QColor QmlUtils::getUserColor(qreal hueF)
|
||||
{
|
||||
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
|
||||
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
|
||||
return QColor::fromHslF(hueF, 1, -0.7 * lightness + 0.9, 1);
|
||||
}
|
||||
|
||||
#include "moc_utils.cpp"
|
||||
|
||||
24
src/utils.h
24
src/utils.h
@@ -3,9 +3,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColor>
|
||||
#include <QGuiApplication>
|
||||
#include <QPalette>
|
||||
#include <QQmlEngine>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <Quotient/user.h>
|
||||
|
||||
class QmlUtils : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -26,11 +31,30 @@ public:
|
||||
}
|
||||
|
||||
Q_INVOKABLE bool isValidJson(const QByteArray &json);
|
||||
Q_INVOKABLE QString escapeString(const QString &string);
|
||||
Q_INVOKABLE QColor getUserColor(qreal hueF);
|
||||
|
||||
private:
|
||||
QmlUtils() = default;
|
||||
};
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Get a color for a user from a hueF value.
|
||||
*
|
||||
* The lightness of the color will be modified depending on the current palette in
|
||||
* order to maintain contrast.
|
||||
*/
|
||||
inline QColor getUserColor(qreal hueF)
|
||||
{
|
||||
const auto lightness = static_cast<QGuiApplication *>(QGuiApplication::instance())->palette().color(QPalette::Active, QPalette::Window).lightnessF();
|
||||
// https://github.com/quotient-im/libQuotient/wiki/User-color-coding-standard-draft-proposal
|
||||
return QColor::fromHslF(hueF, 1, -0.7 * lightness + 0.9, 1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace TextRegex
|
||||
{
|
||||
static const QRegularExpression endTagType{QStringLiteral("(>| )")};
|
||||
|
||||
Reference in New Issue
Block a user