Skip to content

Commit 9d8d6b4

Browse files
committed
Show a room preview in the join confirmation dialog
Requires MSC3266 Fixes #1129
1 parent 213a28e commit 9d8d6b4

13 files changed

Lines changed: 355 additions & 27 deletions

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ set(SRC_FILES
388388
src/ui/NhekoGlobalObject.h
389389
src/ui/RoomSettings.cpp
390390
src/ui/RoomSettings.h
391+
src/ui/RoomSummary.cpp
392+
src/ui/RoomSummary.h
391393
src/ui/Theme.cpp
392394
src/ui/Theme.h
393395
src/ui/ThemeManager.cpp
@@ -581,7 +583,7 @@ if(USE_BUNDLED_MTXCLIENT)
581583
FetchContent_Declare(
582584
MatrixClient
583585
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
584-
GIT_TAG v0.8.0
586+
GIT_TAG b706492de042455630063c847574bbc5ed5d4641
585587
)
586588
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
587589
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

io.github.NhekoReborn.Nheko.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ modules:
203203
buildsystem: cmake-ninja
204204
name: mtxclient
205205
sources:
206-
- commit: 2a1cf15cbda4d3deb7986c9f3b38e6c7aabb0d6f
207-
tag: v0.8.0
206+
- commit: b706492de042455630063c847574bbc5ed5d4641
207+
#tag: v0.8.0
208208
type: git
209209
url: https://github.com/Nheko-Reborn/mtxclient.git
210210
- config-opts:

resources/qml/Root.qml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ Pane {
174174

175175
}
176176

177+
Component {
178+
id: confirmJoinRoomDialog
179+
180+
ConfirmJoinRoomDialog {
181+
}
182+
183+
}
184+
177185
Component {
178186
id: leaveRoomComponent
179187

@@ -241,6 +249,12 @@ Pane {
241249
destroyOnClose(dialog);
242250
}
243251

252+
function onShowRoomJoinPrompt(summary) {
253+
var dialog = confirmJoinRoomDialog.createObject(timelineRoot, {"summary": summary});
254+
dialog.show();
255+
destroyOnClose(dialog);
256+
}
257+
244258
target: Nheko
245259
}
246260

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// SPDX-FileCopyrightText: 2021 Nheko Contributors
2+
// SPDX-FileCopyrightText: 2022 Nheko Contributors
3+
//
4+
// SPDX-License-Identifier: GPL-3.0-or-later
5+
6+
import ".."
7+
import "../ui"
8+
import Qt.labs.platform 1.1 as Platform
9+
import QtQuick 2.15
10+
import QtQuick.Controls 2.3
11+
import QtQuick.Layouts 1.2
12+
import QtQuick.Window 2.13
13+
import im.nheko 1.0
14+
15+
ApplicationWindow {
16+
id: joinRoomRoot
17+
18+
required property RoomSummary summary
19+
20+
title: qsTr("Confirm room join")
21+
modality: Qt.WindowModal
22+
flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
23+
palette: Nheko.colors
24+
color: Nheko.colors.window
25+
width: 350
26+
height: content.implicitHeight + Nheko.paddingLarge + footer.implicitHeight
27+
28+
Shortcut {
29+
sequence: StandardKey.Cancel
30+
onActivated: dbb.rejected()
31+
}
32+
33+
ColumnLayout {
34+
id: content
35+
spacing: Nheko.paddingMedium
36+
anchors.margins: Nheko.paddingMedium
37+
anchors.fill: parent
38+
39+
Avatar {
40+
Layout.topMargin: Nheko.paddingMedium
41+
url: summary.roomAvatarUrl.replace("mxc://", "image://MxcImage/")
42+
roomid: summary.roomid
43+
displayName: summary.roomName
44+
height: 130
45+
width: 130
46+
Layout.alignment: Qt.AlignHCenter
47+
}
48+
49+
Spinner {
50+
Layout.alignment: Qt.AlignHCenter
51+
visible: !summary.isLoaded
52+
foreground: Nheko.colors.mid
53+
running: !summary.isLoaded
54+
}
55+
56+
TextEdit {
57+
readOnly: true
58+
textFormat: TextEdit.RichText
59+
text: summary.roomName
60+
font.pixelSize: fontMetrics.font.pixelSize * 2
61+
color: Nheko.colors.text
62+
63+
Layout.alignment: Qt.AlignHCenter
64+
Layout.fillWidth: true
65+
horizontalAlignment: TextEdit.AlignHCenter
66+
wrapMode: TextEdit.Wrap
67+
selectByMouse: true
68+
}
69+
TextEdit {
70+
readOnly: true
71+
textFormat: TextEdit.RichText
72+
text: summary.roomid
73+
font.pixelSize: fontMetrics.font.pixelSize * 0.8
74+
color: Nheko.colors.text
75+
76+
Layout.alignment: Qt.AlignHCenter
77+
Layout.fillWidth: true
78+
horizontalAlignment: TextEdit.AlignHCenter
79+
wrapMode: TextEdit.Wrap
80+
selectByMouse: true
81+
}
82+
RowLayout {
83+
spacing: Nheko.paddingMedium
84+
Layout.alignment: Qt.AlignHCenter
85+
86+
MatrixText {
87+
text: qsTr("%n member(s)", "", summary.memberCount)
88+
}
89+
90+
ImageButton {
91+
image: ":/icons/icons/ui/people.svg"
92+
enabled: false
93+
}
94+
95+
}
96+
TextEdit {
97+
readOnly: true
98+
textFormat: TextEdit.RichText
99+
text: summary.roomTopic
100+
color: Nheko.colors.text
101+
102+
Layout.alignment: Qt.AlignHCenter
103+
Layout.fillWidth: true
104+
horizontalAlignment: TextEdit.AlignHCenter
105+
wrapMode: TextEdit.Wrap
106+
selectByMouse: true
107+
}
108+
109+
Label {
110+
id: promptLabel
111+
112+
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:")
113+
color: Nheko.colors.text
114+
Layout.fillWidth: true
115+
horizontalAlignment: Text.AlignHCenter
116+
wrapMode: Text.Wrap
117+
font.bold: true
118+
}
119+
120+
MatrixTextField {
121+
id: reason
122+
123+
focus: true
124+
Layout.fillWidth: true
125+
text: joinRoomRoot.summary.reason
126+
}
127+
128+
}
129+
130+
footer: DialogButtonBox {
131+
id: dbb
132+
133+
standardButtons: DialogButtonBox.Cancel
134+
onAccepted: {
135+
summary.reason = reason.text;
136+
summary.join();
137+
joinRoomRoot.close();
138+
}
139+
onRejected: {
140+
joinRoomRoot.close();
141+
}
142+
143+
Button {
144+
text: summary.isKnockOnly ? qsTr("Knock") : qsTr("Join")
145+
enabled: input.text.match("#.+?:.{3,}")
146+
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
147+
}
148+
149+
}
150+
151+
}

resources/qml/dialogs/JoinRoomDialog.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ ApplicationWindow {
6464
}
6565

6666
Button {
67-
text: "Join"
67+
text: qsTr("Join")
6868
enabled: input.text.match("#.+?:.{3,}")
6969
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
7070
}

resources/res.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
<file>qml/device-verification/Success.qml</file>
151151
<file>qml/device-verification/Waiting.qml</file>
152152
<file>qml/dialogs/AliasEditor.qml</file>
153+
<file>qml/dialogs/ConfirmJoinRoomDialog.qml</file>
153154
<file>qml/dialogs/CreateDirect.qml</file>
154155
<file>qml/dialogs/CreateRoom.qml</file>
155156
<file>qml/dialogs/HiddenEventsDialog.qml</file>

src/ChatPage.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Utils.h"
2323
#include "encryption/DeviceVerificationFlow.h"
2424
#include "encryption/Olm.h"
25+
#include "ui/RoomSummary.h"
2526
#include "ui/Theme.h"
2627
#include "ui/UserProfile.h"
2728
#include "voip/CallManager.h"
@@ -130,7 +131,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
130131
connect(this,
131132
&ChatPage::internalKnock,
132133
this,
133-
qOverload<const QString &, const std::vector<std::string> &, QString, bool>(
134+
qOverload<const QString &, const std::vector<std::string> &, QString, bool, bool>(
134135
&ChatPage::knockRoom),
135136
Qt::QueuedConnection);
136137
connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom);
@@ -697,23 +698,26 @@ void
697698
ChatPage::knockRoom(const QString &room,
698699
const std::vector<std::string> &via,
699700
QString reason,
700-
bool failedJoin)
701+
bool failedJoin,
702+
bool promptForConfirmation)
701703
{
702704
const auto room_id = room.toStdString();
703705
bool confirmed = false;
704-
reason = QInputDialog::getText(
705-
nullptr,
706-
tr("Knock on room"),
707-
// clang-format off
706+
if (promptForConfirmation) {
707+
reason = QInputDialog::getText(
708+
nullptr,
709+
tr("Knock on room"),
710+
// clang-format off
708711
failedJoin
709712
? tr("You failed to join %1. You can try to knock, so that others can invite you in. Do you want to do so?\nYou may optionally provide a reason for others to accept your knock:").arg(room)
710713
: tr("Do you really want to knock on %1? You may optionally provide a reason for others to accept your knock:").arg(room),
711-
// clang-format on
712-
QLineEdit::Normal,
713-
reason,
714-
&confirmed);
715-
if (!confirmed) {
716-
return;
714+
// clang-format on
715+
QLineEdit::Normal,
716+
reason,
717+
&confirmed);
718+
if (!confirmed) {
719+
return;
720+
}
717721
}
718722

719723
http::client()->knock_room(
@@ -742,21 +746,20 @@ ChatPage::joinRoomVia(const std::string &room_id,
742746
bool promptForConfirmation,
743747
const QString &reason)
744748
{
745-
if (promptForConfirmation &&
746-
QMessageBox::Yes !=
747-
QMessageBox::question(
748-
nullptr,
749-
tr("Confirm join"),
750-
tr("Do you really want to join %1?").arg(QString::fromStdString(room_id))))
749+
if (promptForConfirmation) {
750+
auto prompt = new RoomSummary(room_id, via, reason);
751+
QQmlEngine::setObjectOwnership(prompt, QQmlEngine::JavaScriptOwnership);
752+
emit showRoomJoinPrompt(prompt);
751753
return;
754+
}
752755

753756
http::client()->join_room(
754757
room_id,
755758
via,
756759
[this, room_id, reason, via](const mtx::responses::RoomId &, mtx::http::RequestErr err) {
757760
if (err) {
758761
if (err->matrix_error.errcode == mtx::errors::ErrorCode::M_FORBIDDEN)
759-
emit internalKnock(QString::fromStdString(room_id), via, reason, true);
762+
emit internalKnock(QString::fromStdString(room_id), via, reason, true, true);
760763
else
761764
emit showNotification(tr("Failed to join room: %1")
762765
.arg(QString::fromStdString(err->matrix_error.error)));

src/ChatPage.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "CacheCryptoStructs.h"
2626
#include "CacheStructs.h"
27+
#include "ui/RoomSummary.h"
2728

2829
class TimelineViewManager;
2930
class UserSettings;
@@ -84,8 +85,9 @@ public slots:
8485
void knockRoom(const QString &room, QString reason = "") { knockRoom(room, {}, reason, false); }
8586
void knockRoom(const QString &room,
8687
const std::vector<std::string> &via,
87-
QString reason = "",
88-
bool failedJoin = false);
88+
QString reason = "",
89+
bool failedJoin = false,
90+
bool promptForConfirmation = true);
8991
void joinRoomVia(const std::string &room_id,
9092
const std::vector<std::string> &via,
9193
bool promptForConfirmation = true,
@@ -163,10 +165,12 @@ public slots:
163165
void downloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
164166
const SecretsToDecrypt &secrets);
165167

168+
void showRoomJoinPrompt(RoomSummary *);
166169
void internalKnock(const QString &room,
167170
const std::vector<std::string> &via,
168-
QString reason = "",
169-
bool failedJoin = false);
171+
QString reason = "",
172+
bool failedJoin = false,
173+
bool promptForConfirmation = true);
170174

171175
private slots:
172176
void logout();

src/MainWindow.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "ui/NhekoDropArea.h"
5555
#include "ui/NhekoEventObserver.h"
5656
#include "ui/NhekoGlobalObject.h"
57+
#include "ui/RoomSummary.h"
5758
#include "ui/UIA.h"
5859
#include "voip/CallManager.h"
5960
#include "voip/WebRTCSession.h"
@@ -65,6 +66,7 @@
6566
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
6667
Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
6768
Q_DECLARE_METATYPE(std::vector<mtx::responses::PublicRoomsChunk>)
69+
Q_DECLARE_METATYPE(mtx::responses::PublicRoom)
6870

6971
MainWindow *MainWindow::instance_ = nullptr;
7072

@@ -142,6 +144,7 @@ MainWindow::registerQmlTypes()
142144
qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
143145
qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
144146
qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
147+
qRegisterMetaType<mtx::responses::PublicRoom>();
145148
qRegisterMetaType<CombinedImagePackModel *>();
146149
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
147150
qRegisterMetaType<std::vector<DeviceInfo>>();
@@ -180,6 +183,12 @@ MainWindow::registerQmlTypes()
180183
qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login");
181184
qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration");
182185
qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents");
186+
qmlRegisterUncreatableType<RoomSummary>(
187+
"im.nheko",
188+
1,
189+
0,
190+
"RoomSummary",
191+
QStringLiteral("Please use joinRoom to create a room summary."));
183192
qmlRegisterUncreatableType<AliasEditingModel>(
184193
"im.nheko",
185194
1,

src/ui/NhekoGlobalObject.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Nheko::Nheko()
2222
connect(
2323
UserSettings::instance().get(), &UserSettings::themeChanged, this, &Nheko::colorsChanged);
2424
connect(ChatPage::instance(), &ChatPage::contentLoaded, this, &Nheko::updateUserProfile);
25+
connect(ChatPage::instance(), &ChatPage::showRoomJoinPrompt, this, &Nheko::showRoomJoinPrompt);
2526
connect(this, &Nheko::joinRoom, ChatPage::instance(), &ChatPage::joinRoom);
2627
}
2728

0 commit comments

Comments
 (0)