Allow accepting knocks in the timeline
As well as selecting more join rules.
This commit is contained in:
parent
56b24f8d93
commit
5b460861b1
|
@ -49,7 +49,7 @@ Rectangle {
|
||||||
smooth: true
|
smooth: true
|
||||||
sourceSize.width: avatar.width
|
sourceSize.width: avatar.width
|
||||||
sourceSize.height: avatar.height
|
sourceSize.height: avatar.height
|
||||||
source: avatar.url ? (avatar.url + "?radius=" + (Settings.avatarCircles ? 100.0 : 25.0) + ((avatar.crop) ? "" : "&scale")) : ""
|
source: avatar.url ? (avatar.url + "?radius=" + (Settings.avatarCircles ? 100 : 25) + ((avatar.crop) ? "" : "&scale")) : ""
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
|
@ -16,12 +16,13 @@ Page {
|
||||||
property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3)
|
property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3)
|
||||||
property bool collapsed: false
|
property bool collapsed: false
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: roomDirectoryComponent
|
id: roomDirectoryComponent
|
||||||
|
|
||||||
RoomDirectory {
|
RoomDirectory {
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: roomlist
|
id: roomlist
|
||||||
|
@ -570,10 +571,10 @@ Component {
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: qsTr("Room directory")
|
ToolTip.text: qsTr("Room directory")
|
||||||
Layout.margins: Nheko.paddingMedium
|
Layout.margins: Nheko.paddingMedium
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var win = roomDirectoryComponent.createObject(timelineRoot);
|
var win = roomDirectoryComponent.createObject(timelineRoot);
|
||||||
win.show();
|
win.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButton {
|
ImageButton {
|
||||||
|
|
|
@ -186,7 +186,16 @@ ApplicationWindow {
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
enabled: roomSettings.canChangeJoinRules
|
enabled: roomSettings.canChangeJoinRules
|
||||||
model: [qsTr("Anyone and guests"), qsTr("Anyone"), qsTr("Invited users")]
|
model: {
|
||||||
|
let opts = [qsTr("Anyone and guests"), qsTr("Anyone"), qsTr("Invited users")];
|
||||||
|
if (roomSettings.supportsKnocking)
|
||||||
|
opts.push(qsTr("By knocking"));
|
||||||
|
|
||||||
|
if (roomSettings.supportsRestricted)
|
||||||
|
opts.push(qsTr("Restricted by membership in other rooms"));
|
||||||
|
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
currentIndex: roomSettings.accessJoinRules
|
currentIndex: roomSettings.accessJoinRules
|
||||||
onActivated: {
|
onActivated: {
|
||||||
roomSettings.changeAccessRules(index);
|
roomSettings.changeAccessRules(index);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
import im.nheko 1.0
|
import im.nheko 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@ -357,11 +359,23 @@ Item {
|
||||||
DelegateChoice {
|
DelegateChoice {
|
||||||
roleValue: MtxEvent.Member
|
roleValue: MtxEvent.Member
|
||||||
|
|
||||||
NoticeMessage {
|
ColumnLayout {
|
||||||
body: formatted
|
width: parent ? parent.width : undefined
|
||||||
isOnlyEmoji: false
|
|
||||||
isReply: d.isReply
|
NoticeMessage {
|
||||||
formatted: d.relatedEventCacheBuster, room.formatMemberEvent(d.eventId)
|
body: formatted
|
||||||
|
isOnlyEmoji: false
|
||||||
|
isReply: d.isReply
|
||||||
|
formatted: d.relatedEventCacheBuster, room.formatMemberEvent(d.eventId)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
visible: d.relatedEventCacheBuster, room.showAcceptKnockButton(d.eventId)
|
||||||
|
palette: Nheko.colors
|
||||||
|
text: qsTr("Allow them in")
|
||||||
|
onClicked: room.acceptKnock(eventId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1689,6 +1689,19 @@ TimelineModel::formatJoinRuleEvent(QString id)
|
||||||
return tr("%1 opened the room to the public.").arg(name);
|
return tr("%1 opened the room to the public.").arg(name);
|
||||||
case mtx::events::state::JoinRule::Invite:
|
case mtx::events::state::JoinRule::Invite:
|
||||||
return tr("%1 made this room require and invitation to join.").arg(name);
|
return tr("%1 made this room require and invitation to join.").arg(name);
|
||||||
|
case mtx::events::state::JoinRule::Knock:
|
||||||
|
return tr("%1 allowed to join this room by knocking.").arg(name);
|
||||||
|
case mtx::events::state::JoinRule::Restricted: {
|
||||||
|
QStringList rooms;
|
||||||
|
for (const auto &r : event->content.allow) {
|
||||||
|
if (r.type == mtx::events::state::JoinAllowanceType::RoomMembership)
|
||||||
|
rooms.push_back(QString::fromStdString(r.room_id));
|
||||||
|
}
|
||||||
|
return tr("%1 allowed members of the following rooms to automatically join this "
|
||||||
|
"room: %2")
|
||||||
|
.arg(name)
|
||||||
|
.arg(rooms.join(", "));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Currently, knock and private are reserved keywords and not implemented in Matrix.
|
// Currently, knock and private are reserved keywords and not implemented in Matrix.
|
||||||
return "";
|
return "";
|
||||||
|
@ -1771,6 +1784,51 @@ TimelineModel::formatPowerLevelEvent(QString id)
|
||||||
return tr("%1 has changed the room's permissions.").arg(name);
|
return tr("%1 has changed the room's permissions.").arg(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineModel::acceptKnock(QString id)
|
||||||
|
{
|
||||||
|
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
|
||||||
|
if (!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::Member>>(e);
|
||||||
|
if (!event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!permissions_.canInvite())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cache::isRoomMember(event->state_key, room_id_.toStdString()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
using namespace mtx::events::state;
|
||||||
|
if (event->content.membership != Membership::Knock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ChatPage::instance()->inviteUser(QString::fromStdString(event->state_key), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TimelineModel::showAcceptKnockButton(QString id)
|
||||||
|
{
|
||||||
|
mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), "");
|
||||||
|
if (!e)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto event = std::get_if<mtx::events::StateEvent<mtx::events::state::Member>>(e);
|
||||||
|
if (!event)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!permissions_.canInvite())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (cache::isRoomMember(event->state_key, room_id_.toStdString()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
using namespace mtx::events::state;
|
||||||
|
return event->content.membership == Membership::Knock;
|
||||||
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TimelineModel::formatMemberEvent(QString id)
|
TimelineModel::formatMemberEvent(QString id)
|
||||||
{
|
{
|
||||||
|
@ -1826,7 +1884,13 @@ TimelineModel::formatMemberEvent(QString id)
|
||||||
// the case of nothing changed but join follows join shouldn't happen, so
|
// the case of nothing changed but join follows join shouldn't happen, so
|
||||||
// just show it as join
|
// just show it as join
|
||||||
} else {
|
} else {
|
||||||
rendered = tr("%1 joined.").arg(name);
|
if (event->content.join_authorised_via_users_server.empty())
|
||||||
|
rendered = tr("%1 joined.").arg(name);
|
||||||
|
else
|
||||||
|
rendered = tr("%1 joined via authorisation from %2's server.")
|
||||||
|
.arg(name)
|
||||||
|
.arg(QString::fromStdString(
|
||||||
|
event->content.join_authorised_via_users_server));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Membership::Leave:
|
case Membership::Leave:
|
||||||
|
|
|
@ -238,6 +238,8 @@ public:
|
||||||
Q_INVOKABLE QString avatarUrl(QString id) const;
|
Q_INVOKABLE QString avatarUrl(QString id) const;
|
||||||
Q_INVOKABLE QString formatDateSeparator(QDate date) const;
|
Q_INVOKABLE QString formatDateSeparator(QDate date) const;
|
||||||
Q_INVOKABLE QString formatTypingUsers(const std::vector<QString> &users, QColor bg);
|
Q_INVOKABLE QString formatTypingUsers(const std::vector<QString> &users, QColor bg);
|
||||||
|
Q_INVOKABLE bool showAcceptKnockButton(QString id);
|
||||||
|
Q_INVOKABLE void acceptKnock(QString id);
|
||||||
Q_INVOKABLE QString formatMemberEvent(QString id);
|
Q_INVOKABLE QString formatMemberEvent(QString id);
|
||||||
Q_INVOKABLE QString formatJoinRuleEvent(QString id);
|
Q_INVOKABLE QString formatJoinRuleEvent(QString id);
|
||||||
Q_INVOKABLE QString formatHistoryVisibilityEvent(QString id);
|
Q_INVOKABLE QString formatHistoryVisibilityEvent(QString id);
|
||||||
|
|
|
@ -218,8 +218,12 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
|
||||||
} else {
|
} else {
|
||||||
accessRules_ = 1;
|
accessRules_ = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (info_.join_rule == state::JoinRule::Invite) {
|
||||||
accessRules_ = 2;
|
accessRules_ = 2;
|
||||||
|
} else if (info_.join_rule == state::JoinRule::Knock) {
|
||||||
|
accessRules_ = 3;
|
||||||
|
} else if (info_.join_rule == state::JoinRule::Restricted) {
|
||||||
|
accessRules_ = 4;
|
||||||
}
|
}
|
||||||
emit accessJoinRulesChanged();
|
emit accessJoinRulesChanged();
|
||||||
}
|
}
|
||||||
|
@ -368,6 +372,21 @@ RoomSettings::isEncryptionEnabled() const
|
||||||
return usesEncryption_;
|
return usesEncryption_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RoomSettings::supportsKnocking() const
|
||||||
|
{
|
||||||
|
return info_.version != "" && info_.version != "1" && info_.version != "2" &&
|
||||||
|
info_.version != "3" && info_.version != "4" && info_.version != "5" &&
|
||||||
|
info_.version != "6";
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
RoomSettings::supportsRestricted() const
|
||||||
|
{
|
||||||
|
return info_.version != "" && info_.version != "1" && info_.version != "2" &&
|
||||||
|
info_.version != "3" && info_.version != "4" && info_.version != "5" &&
|
||||||
|
info_.version != "6" && info_.version != "7";
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RoomSettings::openEditModal()
|
RoomSettings::openEditModal()
|
||||||
{
|
{
|
||||||
|
@ -464,6 +483,15 @@ RoomSettings::changeAccessRules(int index)
|
||||||
case 1:
|
case 1:
|
||||||
event.join_rule = state::JoinRule::Public;
|
event.join_rule = state::JoinRule::Public;
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
event.join_rule = state::JoinRule::Invite;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
event.join_rule = state::JoinRule::Knock;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
event.join_rule = state::JoinRule::Restricted;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
event.join_rule = state::JoinRule::Invite;
|
event.join_rule = state::JoinRule::Invite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ class RoomSettings : public QObject
|
||||||
Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT)
|
Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT)
|
||||||
Q_PROPERTY(bool canChangeNameAndTopic READ canChangeNameAndTopic CONSTANT)
|
Q_PROPERTY(bool canChangeNameAndTopic READ canChangeNameAndTopic CONSTANT)
|
||||||
Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged)
|
Q_PROPERTY(bool isEncryptionEnabled READ isEncryptionEnabled NOTIFY encryptionChanged)
|
||||||
|
Q_PROPERTY(bool supportsKnocking READ supportsKnocking CONSTANT)
|
||||||
|
Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RoomSettings(QString roomid, QObject *parent = nullptr);
|
RoomSettings(QString roomid, QObject *parent = nullptr);
|
||||||
|
@ -98,6 +100,8 @@ public:
|
||||||
//! Whether the user has enough power level to send m.room.avatar event.
|
//! Whether the user has enough power level to send m.room.avatar event.
|
||||||
bool canChangeAvatar() const;
|
bool canChangeAvatar() const;
|
||||||
bool isEncryptionEnabled() const;
|
bool isEncryptionEnabled() const;
|
||||||
|
bool supportsKnocking() const;
|
||||||
|
bool supportsRestricted() const;
|
||||||
|
|
||||||
Q_INVOKABLE void enableEncryption();
|
Q_INVOKABLE void enableEncryption();
|
||||||
Q_INVOKABLE void updateAvatar();
|
Q_INVOKABLE void updateAvatar();
|
||||||
|
|
Loading…
Reference in New Issue