mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Show a room preview in the join confirmation dialog
Requires MSC3266 Fixes #1129
This commit is contained in:
parent
213a28eee3
commit
9d8d6b4bca
13 changed files with 355 additions and 27 deletions
|
@ -388,6 +388,8 @@ set(SRC_FILES
|
||||||
src/ui/NhekoGlobalObject.h
|
src/ui/NhekoGlobalObject.h
|
||||||
src/ui/RoomSettings.cpp
|
src/ui/RoomSettings.cpp
|
||||||
src/ui/RoomSettings.h
|
src/ui/RoomSettings.h
|
||||||
|
src/ui/RoomSummary.cpp
|
||||||
|
src/ui/RoomSummary.h
|
||||||
src/ui/Theme.cpp
|
src/ui/Theme.cpp
|
||||||
src/ui/Theme.h
|
src/ui/Theme.h
|
||||||
src/ui/ThemeManager.cpp
|
src/ui/ThemeManager.cpp
|
||||||
|
@ -581,7 +583,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
MatrixClient
|
MatrixClient
|
||||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
GIT_TAG v0.8.0
|
GIT_TAG b706492de042455630063c847574bbc5ed5d4641
|
||||||
)
|
)
|
||||||
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
||||||
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
||||||
|
|
|
@ -203,8 +203,8 @@ modules:
|
||||||
buildsystem: cmake-ninja
|
buildsystem: cmake-ninja
|
||||||
name: mtxclient
|
name: mtxclient
|
||||||
sources:
|
sources:
|
||||||
- commit: 2a1cf15cbda4d3deb7986c9f3b38e6c7aabb0d6f
|
- commit: b706492de042455630063c847574bbc5ed5d4641
|
||||||
tag: v0.8.0
|
#tag: v0.8.0
|
||||||
type: git
|
type: git
|
||||||
url: https://github.com/Nheko-Reborn/mtxclient.git
|
url: https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
- config-opts:
|
- config-opts:
|
||||||
|
|
|
@ -174,6 +174,14 @@ Pane {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: confirmJoinRoomDialog
|
||||||
|
|
||||||
|
ConfirmJoinRoomDialog {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: leaveRoomComponent
|
id: leaveRoomComponent
|
||||||
|
|
||||||
|
@ -241,6 +249,12 @@ Pane {
|
||||||
destroyOnClose(dialog);
|
destroyOnClose(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onShowRoomJoinPrompt(summary) {
|
||||||
|
var dialog = confirmJoinRoomDialog.createObject(timelineRoot, {"summary": summary});
|
||||||
|
dialog.show();
|
||||||
|
destroyOnClose(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
target: Nheko
|
target: Nheko
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
151
resources/qml/dialogs/ConfirmJoinRoomDialog.qml
Normal file
151
resources/qml/dialogs/ConfirmJoinRoomDialog.qml
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import ".."
|
||||||
|
import "../ui"
|
||||||
|
import Qt.labs.platform 1.1 as Platform
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Window 2.13
|
||||||
|
import im.nheko 1.0
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: joinRoomRoot
|
||||||
|
|
||||||
|
required property RoomSummary summary
|
||||||
|
|
||||||
|
title: qsTr("Confirm room join")
|
||||||
|
modality: Qt.WindowModal
|
||||||
|
flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||||
|
palette: Nheko.colors
|
||||||
|
color: Nheko.colors.window
|
||||||
|
width: 350
|
||||||
|
height: content.implicitHeight + Nheko.paddingLarge + footer.implicitHeight
|
||||||
|
|
||||||
|
Shortcut {
|
||||||
|
sequence: StandardKey.Cancel
|
||||||
|
onActivated: dbb.rejected()
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
spacing: Nheko.paddingMedium
|
||||||
|
anchors.margins: Nheko.paddingMedium
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Avatar {
|
||||||
|
Layout.topMargin: Nheko.paddingMedium
|
||||||
|
url: summary.roomAvatarUrl.replace("mxc://", "image://MxcImage/")
|
||||||
|
roomid: summary.roomid
|
||||||
|
displayName: summary.roomName
|
||||||
|
height: 130
|
||||||
|
width: 130
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Spinner {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
visible: !summary.isLoaded
|
||||||
|
foreground: Nheko.colors.mid
|
||||||
|
running: !summary.isLoaded
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
readOnly: true
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
text: summary.roomName
|
||||||
|
font.pixelSize: fontMetrics.font.pixelSize * 2
|
||||||
|
color: Nheko.colors.text
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: TextEdit.AlignHCenter
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
TextEdit {
|
||||||
|
readOnly: true
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
text: summary.roomid
|
||||||
|
font.pixelSize: fontMetrics.font.pixelSize * 0.8
|
||||||
|
color: Nheko.colors.text
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: TextEdit.AlignHCenter
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
spacing: Nheko.paddingMedium
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
MatrixText {
|
||||||
|
text: qsTr("%n member(s)", "", summary.memberCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageButton {
|
||||||
|
image: ":/icons/icons/ui/people.svg"
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
TextEdit {
|
||||||
|
readOnly: true
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
text: summary.roomTopic
|
||||||
|
color: Nheko.colors.text
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: TextEdit.AlignHCenter
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: promptLabel
|
||||||
|
|
||||||
|
text: summary.isKnockOnly ? qsTr("This room can't be joined directly. You can however knock on the room and room members can accept or decline this join request. You can additionally provide a reason for them to let you in below:") : qsTr("Do you want to join this room? You can optionally add a reason below:")
|
||||||
|
color: Nheko.colors.text
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixTextField {
|
||||||
|
id: reason
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: joinRoomRoot.summary.reason
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: DialogButtonBox {
|
||||||
|
id: dbb
|
||||||
|
|
||||||
|
standardButtons: DialogButtonBox.Cancel
|
||||||
|
onAccepted: {
|
||||||
|
summary.reason = reason.text;
|
||||||
|
summary.join();
|
||||||
|
joinRoomRoot.close();
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
joinRoomRoot.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: summary.isKnockOnly ? qsTr("Knock") : qsTr("Join")
|
||||||
|
enabled: input.text.match("#.+?:.{3,}")
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "Join"
|
text: qsTr("Join")
|
||||||
enabled: input.text.match("#.+?:.{3,}")
|
enabled: input.text.match("#.+?:.{3,}")
|
||||||
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
<file>qml/device-verification/Success.qml</file>
|
<file>qml/device-verification/Success.qml</file>
|
||||||
<file>qml/device-verification/Waiting.qml</file>
|
<file>qml/device-verification/Waiting.qml</file>
|
||||||
<file>qml/dialogs/AliasEditor.qml</file>
|
<file>qml/dialogs/AliasEditor.qml</file>
|
||||||
|
<file>qml/dialogs/ConfirmJoinRoomDialog.qml</file>
|
||||||
<file>qml/dialogs/CreateDirect.qml</file>
|
<file>qml/dialogs/CreateDirect.qml</file>
|
||||||
<file>qml/dialogs/CreateRoom.qml</file>
|
<file>qml/dialogs/CreateRoom.qml</file>
|
||||||
<file>qml/dialogs/HiddenEventsDialog.qml</file>
|
<file>qml/dialogs/HiddenEventsDialog.qml</file>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "encryption/DeviceVerificationFlow.h"
|
#include "encryption/DeviceVerificationFlow.h"
|
||||||
#include "encryption/Olm.h"
|
#include "encryption/Olm.h"
|
||||||
|
#include "ui/RoomSummary.h"
|
||||||
#include "ui/Theme.h"
|
#include "ui/Theme.h"
|
||||||
#include "ui/UserProfile.h"
|
#include "ui/UserProfile.h"
|
||||||
#include "voip/CallManager.h"
|
#include "voip/CallManager.h"
|
||||||
|
@ -130,7 +131,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
|
||||||
connect(this,
|
connect(this,
|
||||||
&ChatPage::internalKnock,
|
&ChatPage::internalKnock,
|
||||||
this,
|
this,
|
||||||
qOverload<const QString &, const std::vector<std::string> &, QString, bool>(
|
qOverload<const QString &, const std::vector<std::string> &, QString, bool, bool>(
|
||||||
&ChatPage::knockRoom),
|
&ChatPage::knockRoom),
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom);
|
connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom);
|
||||||
|
@ -697,10 +698,12 @@ void
|
||||||
ChatPage::knockRoom(const QString &room,
|
ChatPage::knockRoom(const QString &room,
|
||||||
const std::vector<std::string> &via,
|
const std::vector<std::string> &via,
|
||||||
QString reason,
|
QString reason,
|
||||||
bool failedJoin)
|
bool failedJoin,
|
||||||
|
bool promptForConfirmation)
|
||||||
{
|
{
|
||||||
const auto room_id = room.toStdString();
|
const auto room_id = room.toStdString();
|
||||||
bool confirmed = false;
|
bool confirmed = false;
|
||||||
|
if (promptForConfirmation) {
|
||||||
reason = QInputDialog::getText(
|
reason = QInputDialog::getText(
|
||||||
nullptr,
|
nullptr,
|
||||||
tr("Knock on room"),
|
tr("Knock on room"),
|
||||||
|
@ -715,6 +718,7 @@ ChatPage::knockRoom(const QString &room,
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
http::client()->knock_room(
|
http::client()->knock_room(
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -742,13 +746,12 @@ ChatPage::joinRoomVia(const std::string &room_id,
|
||||||
bool promptForConfirmation,
|
bool promptForConfirmation,
|
||||||
const QString &reason)
|
const QString &reason)
|
||||||
{
|
{
|
||||||
if (promptForConfirmation &&
|
if (promptForConfirmation) {
|
||||||
QMessageBox::Yes !=
|
auto prompt = new RoomSummary(room_id, via, reason);
|
||||||
QMessageBox::question(
|
QQmlEngine::setObjectOwnership(prompt, QQmlEngine::JavaScriptOwnership);
|
||||||
nullptr,
|
emit showRoomJoinPrompt(prompt);
|
||||||
tr("Confirm join"),
|
|
||||||
tr("Do you really want to join %1?").arg(QString::fromStdString(room_id))))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
http::client()->join_room(
|
http::client()->join_room(
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -756,7 +759,7 @@ ChatPage::joinRoomVia(const std::string &room_id,
|
||||||
[this, room_id, reason, via](const mtx::responses::RoomId &, mtx::http::RequestErr err) {
|
[this, room_id, reason, via](const mtx::responses::RoomId &, mtx::http::RequestErr err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err->matrix_error.errcode == mtx::errors::ErrorCode::M_FORBIDDEN)
|
if (err->matrix_error.errcode == mtx::errors::ErrorCode::M_FORBIDDEN)
|
||||||
emit internalKnock(QString::fromStdString(room_id), via, reason, true);
|
emit internalKnock(QString::fromStdString(room_id), via, reason, true, true);
|
||||||
else
|
else
|
||||||
emit showNotification(tr("Failed to join room: %1")
|
emit showNotification(tr("Failed to join room: %1")
|
||||||
.arg(QString::fromStdString(err->matrix_error.error)));
|
.arg(QString::fromStdString(err->matrix_error.error)));
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "CacheCryptoStructs.h"
|
#include "CacheCryptoStructs.h"
|
||||||
#include "CacheStructs.h"
|
#include "CacheStructs.h"
|
||||||
|
#include "ui/RoomSummary.h"
|
||||||
|
|
||||||
class TimelineViewManager;
|
class TimelineViewManager;
|
||||||
class UserSettings;
|
class UserSettings;
|
||||||
|
@ -85,7 +86,8 @@ public slots:
|
||||||
void knockRoom(const QString &room,
|
void knockRoom(const QString &room,
|
||||||
const std::vector<std::string> &via,
|
const std::vector<std::string> &via,
|
||||||
QString reason = "",
|
QString reason = "",
|
||||||
bool failedJoin = false);
|
bool failedJoin = false,
|
||||||
|
bool promptForConfirmation = true);
|
||||||
void joinRoomVia(const std::string &room_id,
|
void joinRoomVia(const std::string &room_id,
|
||||||
const std::vector<std::string> &via,
|
const std::vector<std::string> &via,
|
||||||
bool promptForConfirmation = true,
|
bool promptForConfirmation = true,
|
||||||
|
@ -163,10 +165,12 @@ signals:
|
||||||
void downloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
|
void downloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
|
||||||
const SecretsToDecrypt &secrets);
|
const SecretsToDecrypt &secrets);
|
||||||
|
|
||||||
|
void showRoomJoinPrompt(RoomSummary *);
|
||||||
void internalKnock(const QString &room,
|
void internalKnock(const QString &room,
|
||||||
const std::vector<std::string> &via,
|
const std::vector<std::string> &via,
|
||||||
QString reason = "",
|
QString reason = "",
|
||||||
bool failedJoin = false);
|
bool failedJoin = false,
|
||||||
|
bool promptForConfirmation = true);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void logout();
|
void logout();
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "ui/NhekoDropArea.h"
|
#include "ui/NhekoDropArea.h"
|
||||||
#include "ui/NhekoEventObserver.h"
|
#include "ui/NhekoEventObserver.h"
|
||||||
#include "ui/NhekoGlobalObject.h"
|
#include "ui/NhekoGlobalObject.h"
|
||||||
|
#include "ui/RoomSummary.h"
|
||||||
#include "ui/UIA.h"
|
#include "ui/UIA.h"
|
||||||
#include "voip/CallManager.h"
|
#include "voip/CallManager.h"
|
||||||
#include "voip/WebRTCSession.h"
|
#include "voip/WebRTCSession.h"
|
||||||
|
@ -65,6 +66,7 @@
|
||||||
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
|
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
|
||||||
Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
|
Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
|
||||||
Q_DECLARE_METATYPE(std::vector<mtx::responses::PublicRoomsChunk>)
|
Q_DECLARE_METATYPE(std::vector<mtx::responses::PublicRoomsChunk>)
|
||||||
|
Q_DECLARE_METATYPE(mtx::responses::PublicRoom)
|
||||||
|
|
||||||
MainWindow *MainWindow::instance_ = nullptr;
|
MainWindow *MainWindow::instance_ = nullptr;
|
||||||
|
|
||||||
|
@ -142,6 +144,7 @@ MainWindow::registerQmlTypes()
|
||||||
qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
|
qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
|
||||||
qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
|
qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
|
||||||
qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
|
qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
|
||||||
|
qRegisterMetaType<mtx::responses::PublicRoom>();
|
||||||
qRegisterMetaType<CombinedImagePackModel *>();
|
qRegisterMetaType<CombinedImagePackModel *>();
|
||||||
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
||||||
qRegisterMetaType<std::vector<DeviceInfo>>();
|
qRegisterMetaType<std::vector<DeviceInfo>>();
|
||||||
|
@ -180,6 +183,12 @@ MainWindow::registerQmlTypes()
|
||||||
qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login");
|
qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login");
|
||||||
qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration");
|
qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration");
|
||||||
qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents");
|
qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents");
|
||||||
|
qmlRegisterUncreatableType<RoomSummary>(
|
||||||
|
"im.nheko",
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
"RoomSummary",
|
||||||
|
QStringLiteral("Please use joinRoom to create a room summary."));
|
||||||
qmlRegisterUncreatableType<AliasEditingModel>(
|
qmlRegisterUncreatableType<AliasEditingModel>(
|
||||||
"im.nheko",
|
"im.nheko",
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -22,6 +22,7 @@ Nheko::Nheko()
|
||||||
connect(
|
connect(
|
||||||
UserSettings::instance().get(), &UserSettings::themeChanged, this, &Nheko::colorsChanged);
|
UserSettings::instance().get(), &UserSettings::themeChanged, this, &Nheko::colorsChanged);
|
||||||
connect(ChatPage::instance(), &ChatPage::contentLoaded, this, &Nheko::updateUserProfile);
|
connect(ChatPage::instance(), &ChatPage::contentLoaded, this, &Nheko::updateUserProfile);
|
||||||
|
connect(ChatPage::instance(), &ChatPage::showRoomJoinPrompt, this, &Nheko::showRoomJoinPrompt);
|
||||||
connect(this, &Nheko::joinRoom, ChatPage::instance(), &ChatPage::joinRoom);
|
connect(this, &Nheko::joinRoom, ChatPage::instance(), &ChatPage::joinRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "AliasEditModel.h"
|
#include "AliasEditModel.h"
|
||||||
#include "PowerlevelsEditModels.h"
|
#include "PowerlevelsEditModels.h"
|
||||||
|
#include "RoomSummary.h"
|
||||||
#include "Theme.h"
|
#include "Theme.h"
|
||||||
#include "UserProfile.h"
|
#include "UserProfile.h"
|
||||||
|
|
||||||
|
@ -76,6 +77,8 @@ signals:
|
||||||
void openJoinRoomDialog();
|
void openJoinRoomDialog();
|
||||||
void joinRoom(QString roomId, QString reason = "");
|
void joinRoom(QString roomId, QString reason = "");
|
||||||
|
|
||||||
|
void showRoomJoinPrompt(RoomSummary *summary);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<UserProfile> currentUser_;
|
QScopedPointer<UserProfile> currentUser_;
|
||||||
};
|
};
|
||||||
|
|
54
src/ui/RoomSummary.cpp
Normal file
54
src/ui/RoomSummary.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "RoomSummary.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
#include "ChatPage.h"
|
||||||
|
#include "MatrixClient.h"
|
||||||
|
|
||||||
|
RoomSummary::RoomSummary(std::string roomIdOrAlias_,
|
||||||
|
std::vector<std::string> vias_,
|
||||||
|
QString r_,
|
||||||
|
QObject *p)
|
||||||
|
: QObject(p)
|
||||||
|
, roomIdOrAlias(std::move(roomIdOrAlias_))
|
||||||
|
, vias(std::move(vias_))
|
||||||
|
, reason_(std::move(r_))
|
||||||
|
{
|
||||||
|
auto ctx = std::make_shared<RoomSummaryProxy>();
|
||||||
|
|
||||||
|
connect(ctx.get(), &RoomSummaryProxy::failed, this, [this]() {
|
||||||
|
loaded_ = true;
|
||||||
|
emit loaded();
|
||||||
|
});
|
||||||
|
connect(
|
||||||
|
ctx.get(), &RoomSummaryProxy::loaded, this, [this](const mtx::responses::PublicRoom &resp) {
|
||||||
|
loaded_ = true;
|
||||||
|
room = resp;
|
||||||
|
emit loaded();
|
||||||
|
});
|
||||||
|
|
||||||
|
http::client()->get_summary(
|
||||||
|
roomIdOrAlias,
|
||||||
|
[proxy = std::move(ctx)](const mtx::responses::PublicRoom &room, mtx::http::RequestErr e) {
|
||||||
|
if (e) {
|
||||||
|
emit proxy->failed();
|
||||||
|
} else {
|
||||||
|
emit proxy->loaded(room);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vias);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RoomSummary::join()
|
||||||
|
{
|
||||||
|
if (isKnockOnly())
|
||||||
|
ChatPage::instance()->knockRoom(
|
||||||
|
QString::fromStdString(roomIdOrAlias), vias, reason_, false, false);
|
||||||
|
else
|
||||||
|
ChatPage::instance()->joinRoomVia(roomIdOrAlias, vias, false, reason_);
|
||||||
|
}
|
86
src/ui/RoomSummary.h
Normal file
86
src/ui/RoomSummary.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <mtx/responses/public_rooms.hpp>
|
||||||
|
|
||||||
|
class RoomSummaryProxy : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RoomSummaryProxy() {}
|
||||||
|
signals:
|
||||||
|
void loaded(mtx::responses::PublicRoom room);
|
||||||
|
void failed();
|
||||||
|
};
|
||||||
|
|
||||||
|
class RoomSummary : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString reason READ reason WRITE setReason NOTIFY reasonChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QString roomid READ roomid NOTIFY loaded)
|
||||||
|
Q_PROPERTY(QString roomName READ roomName NOTIFY loaded)
|
||||||
|
Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY loaded)
|
||||||
|
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY loaded)
|
||||||
|
Q_PROPERTY(bool isInvite READ isInvite NOTIFY loaded)
|
||||||
|
Q_PROPERTY(bool isSpace READ isInvite NOTIFY loaded)
|
||||||
|
Q_PROPERTY(bool isKnockOnly READ isKnockOnly NOTIFY loaded)
|
||||||
|
Q_PROPERTY(bool isLoaded READ isLoaded NOTIFY loaded)
|
||||||
|
Q_PROPERTY(int memberCount READ memberCount NOTIFY loaded)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RoomSummary(std::string roomIdOrAlias_,
|
||||||
|
std::vector<std::string> vias_,
|
||||||
|
QString reason_,
|
||||||
|
QObject *p = nullptr);
|
||||||
|
|
||||||
|
void setReason(const QString &r)
|
||||||
|
{
|
||||||
|
reason_ = r;
|
||||||
|
emit reasonChanged();
|
||||||
|
}
|
||||||
|
QString reason() const { return reason_; }
|
||||||
|
|
||||||
|
QString roomid() const { return room ? QString::fromStdString(room->room_id) : ""; }
|
||||||
|
QString roomName() const
|
||||||
|
{
|
||||||
|
return QString::fromStdString(room ? room->room_id : roomIdOrAlias);
|
||||||
|
}
|
||||||
|
QString roomTopic() const { return room ? QString::fromStdString(room->topic) : ""; }
|
||||||
|
QString roomAvatarUrl() const { return room ? QString::fromStdString(room->avatar_url) : ""; }
|
||||||
|
bool isInvite() const
|
||||||
|
{
|
||||||
|
return room && room->membership == mtx::events::state::Membership::Invite;
|
||||||
|
}
|
||||||
|
bool isSpace() const { return room && room->room_type == mtx::events::state::room_type::space; }
|
||||||
|
int memberCount() const { return room ? room->num_joined_members : 0; }
|
||||||
|
bool isKnockOnly() const
|
||||||
|
{
|
||||||
|
return room && (room->join_rule == mtx::events::state::JoinRule::Knock ||
|
||||||
|
room->join_rule == mtx::events::state::JoinRule::KnockRestricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLoaded() const { return room.has_value() || loaded_; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void join();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void loaded();
|
||||||
|
void reasonChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string roomIdOrAlias;
|
||||||
|
std::vector<std::string> vias;
|
||||||
|
std::optional<mtx::responses::PublicRoom> room;
|
||||||
|
QString reason_;
|
||||||
|
bool loaded_ = false;
|
||||||
|
};
|
Loading…
Reference in a new issue