mirror of https://github.com/Nheko-Reborn/nheko
parent
213a28eee3
commit
9d8d6b4bca
@ -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 |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -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_); |
||||
} |
@ -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 new issue