Show the community of a room

pull/1191/head
Nicolas Werner 2 years ago
parent 7088c9bd9b
commit 421b15c05c
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 61
      resources/qml/TopBar.qml
  2. 1
      resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
  3. 14
      src/timeline/CommunitiesModel.cpp
  4. 1
      src/timeline/CommunitiesModel.h
  5. 25
      src/timeline/TimelineModel.cpp
  6. 7
      src/timeline/TimelineModel.h
  7. 43
      src/ui/RoomSummary.cpp
  8. 1
      src/ui/RoomSummary.h

@ -49,6 +49,13 @@ Pane {
return; return;
} }
if (communityLabel.visible && eventPoint.position.y < communityAvatar.height + Nheko.paddingMedium + Nheko.paddingSmall/2) {
if (!Communities.trySwitchToSpace(room.parentSpace.roomid))
room.parentSpace.promptJoin();
eventPoint.accepted = true
return;
}
if (room) { if (room) {
let p = topBar.mapToItem(roomTopicC, eventPoint.position.x, eventPoint.position.y); let p = topBar.mapToItem(roomTopicC, eventPoint.position.x, eventPoint.position.y);
let link = roomTopicC.linkAt(p.x, p.y); let link = roomTopicC.linkAt(p.x, p.y);
@ -80,11 +87,46 @@ Pane {
columnSpacing: Nheko.paddingSmall columnSpacing: Nheko.paddingSmall
rowSpacing: Nheko.paddingSmall rowSpacing: Nheko.paddingSmall
Avatar {
id: communityAvatar
visible: roomid && room.parentSpace.isLoaded && ("space:"+room.parentSpace.roomid != Communities.currentTagId)
property string avatarUrl: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomAvatarUrl) || ""
property string communityId: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomid) || ""
property string communityName: (Settings.groupView && room && room.parentSpace && room.parentSpace.roomName) || ""
Layout.column: 1
Layout.row: 0
Layout.alignment: Qt.AlignRight
width: fontMetrics.lineSpacing
height: fontMetrics.lineSpacing
url: avatarUrl.replace("mxc://", "image://MxcImage/")
roomid: communityId
displayName: communityName
enabled: false
}
Label {
id: communityLabel
visible: communityAvatar.visible
Layout.column: 2
Layout.row: 0
Layout.fillWidth: true
color: Nheko.colors.text
text: qsTr("In %1").arg(communityAvatar.displayName)
maximumLineCount: 1
elide: Text.ElideRight
textFormat: Text.RichText
}
ImageButton { ImageButton {
id: backToRoomsButton id: backToRoomsButton
Layout.column: 0 Layout.column: 0
Layout.row: 0 Layout.row: 1
Layout.rowSpan: 2 Layout.rowSpan: 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
@ -98,7 +140,7 @@ Pane {
Avatar { Avatar {
Layout.column: 1 Layout.column: 1
Layout.row: 0 Layout.row: 1
Layout.rowSpan: 2 Layout.rowSpan: 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
width: Nheko.avatarSize width: Nheko.avatarSize
@ -113,9 +155,10 @@ Pane {
Label { Label {
Layout.fillWidth: true Layout.fillWidth: true
Layout.column: 2 Layout.column: 2
Layout.row: 0 Layout.row: 1
color: Nheko.colors.text color: Nheko.colors.text
font.pointSize: fontMetrics.font.pointSize * 1.1 font.pointSize: fontMetrics.font.pointSize * 1.1
font.bold: true
text: roomName text: roomName
maximumLineCount: 1 maximumLineCount: 1
elide: Text.ElideRight elide: Text.ElideRight
@ -126,7 +169,7 @@ Pane {
id: roomTopicC id: roomTopicC
Layout.fillWidth: true Layout.fillWidth: true
Layout.column: 2 Layout.column: 2
Layout.row: 1 Layout.row: 2
Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines
selectByMouse: false selectByMouse: false
enabled: false enabled: false
@ -136,7 +179,7 @@ Pane {
AbstractButton { AbstractButton {
Layout.column: 3 Layout.column: 3
Layout.row: 0 Layout.row: 1
Layout.rowSpan: 2 Layout.rowSpan: 2
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
@ -179,7 +222,7 @@ Pane {
visible: !!room && room.pinnedMessages.length > 0 visible: !!room && room.pinnedMessages.length > 0
Layout.column: 4 Layout.column: 4
Layout.row: 0 Layout.row: 1
Layout.rowSpan: 2 Layout.rowSpan: 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
@ -207,7 +250,7 @@ Pane {
visible: !!room visible: !!room
Layout.column: 5 Layout.column: 5
Layout.row: 0 Layout.row: 1
Layout.rowSpan: 2 Layout.rowSpan: 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
@ -248,7 +291,7 @@ Pane {
ScrollView { ScrollView {
id: pinnedMessages id: pinnedMessages
Layout.row: 2 Layout.row: 3
Layout.column: 2 Layout.column: 2
Layout.columnSpan: 3 Layout.columnSpan: 3
@ -329,7 +372,7 @@ Pane {
ScrollView { ScrollView {
id: widgets id: widgets
Layout.row: 3 Layout.row: 4
Layout.column: 2 Layout.column: 2
Layout.columnSpan: 1 Layout.columnSpan: 1

@ -122,7 +122,6 @@ ApplicationWindow {
placeholderText: qsTr("Enter additional rooms not in the list yet...") placeholderText: qsTr("Enter additional rooms not in the list yet...")
//font.pixelSize: Math.ceil(quickSwitcher.textHeight * 0.6)
color: Nheko.colors.text color: Nheko.colors.text
onTextEdited: { onTextEdited: {
roomCompleter.completer.searchString = text; roomCompleter.completer.searchString = text;

@ -605,6 +605,20 @@ CommunitiesModel::setCurrentTagId(const QString &tagId)
emit currentTagIdChanged(currentTagId_); emit currentTagIdChanged(currentTagId_);
} }
bool
CommunitiesModel::trySwitchToSpace(const QString &tag)
{
for (const auto &t : spaceOrder_.tree) {
if (t.id == tag) {
this->currentTagId_ = "space:" + tag;
emit currentTagIdChanged(currentTagId_);
return true;
}
}
return false;
}
void void
CommunitiesModel::toggleTagId(QString tagId) CommunitiesModel::toggleTagId(QString tagId)
{ {

@ -179,6 +179,7 @@ public slots:
void clear(); void clear();
QString currentTagId() const { return currentTagId_; } QString currentTagId() const { return currentTagId_; }
void setCurrentTagId(const QString &tagId); void setCurrentTagId(const QString &tagId);
bool trySwitchToSpace(const QString &spaceId);
void resetCurrentTagId() void resetCurrentTagId()
{ {
currentTagId_.clear(); currentTagId_.clear();

@ -915,6 +915,9 @@ TimelineModel::syncState(const mtx::responses::State &s)
} else if (std::holds_alternative<StateEvent<state::Encryption>>(e)) { } else if (std::holds_alternative<StateEvent<state::Encryption>>(e)) {
this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString());
emit encryptionChanged(); emit encryptionChanged();
} else if (std::holds_alternative<StateEvent<state::space::Parent>>(e)) {
this->parentChecked = false;
emit parentSpaceChanged();
} }
} }
} }
@ -976,6 +979,9 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
} else if (std::holds_alternative<StateEvent<state::Encryption>>(e)) { } else if (std::holds_alternative<StateEvent<state::Encryption>>(e)) {
this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString()); this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString());
emit encryptionChanged(); emit encryptionChanged();
} else if (std::holds_alternative<StateEvent<state::space::Parent>>(e)) {
this->parentChecked = false;
emit parentSpaceChanged();
} }
} }
@ -2904,3 +2910,22 @@ TimelineModel::directChatOtherUserId() const
} else } else
return {}; return {};
} }
RoomSummary *
TimelineModel::parentSpace()
{
if (!parentChecked) {
auto parents = cache::client()->getStateEventsWithType<mtx::events::state::space::Parent>(
this->room_id_.toStdString());
for (const auto &p : parents) {
if (p.content.canonical and p.content.via and not p.content.via->empty()) {
parentSummary.reset(new RoomSummary(p.state_key, *p.content.via, ""));
QQmlEngine::setObjectOwnership(parentSummary.get(), QQmlEngine::CppOwnership);
break;
}
}
}
return parentSummary.get();
}

@ -22,6 +22,7 @@
#include "MemberList.h" #include "MemberList.h"
#include "Permissions.h" #include "Permissions.h"
#include "ReadReceiptsModel.h" #include "ReadReceiptsModel.h"
#include "ui/RoomSummary.h"
namespace mtx::http { namespace mtx::http {
using RequestErr = const std::optional<mtx::http::ClientError> &; using RequestErr = const std::optional<mtx::http::ClientError> &;
@ -197,6 +198,7 @@ class TimelineModel : public QAbstractListModel
QString directChatOtherUserId READ directChatOtherUserId NOTIFY directChatOtherUserIdChanged) QString directChatOtherUserId READ directChatOtherUserId NOTIFY directChatOtherUserIdChanged)
Q_PROPERTY(InputBar *input READ input CONSTANT) Q_PROPERTY(InputBar *input READ input CONSTANT)
Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged) Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged)
Q_PROPERTY(RoomSummary *parentSpace READ parentSpace NOTIFY parentSpaceChanged)
public: public:
explicit TimelineModel(TimelineViewManager *manager, explicit TimelineModel(TimelineViewManager *manager,
@ -397,6 +399,7 @@ public slots:
Permissions *permissions() { return &permissions_; } Permissions *permissions() { return &permissions_; }
QString roomAvatarUrl() const; QString roomAvatarUrl() const;
QString roomId() const { return room_id_; } QString roomId() const { return room_id_; }
RoomSummary *parentSpace();
bool hasMentions() const { return highlight_count > 0; } bool hasMentions() const { return highlight_count > 0; }
int notificationCount() const { return notification_count; } int notificationCount() const { return notification_count; }
@ -431,6 +434,7 @@ signals:
void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void addPendingMessageToStore(mtx::events::collections::TimelineEvents event);
void updateFlowEventId(std::string event_id); void updateFlowEventId(std::string event_id);
void parentSpaceChanged();
void encryptionChanged(); void encryptionChanged();
void fullyReadEventIdChanged(); void fullyReadEventIdChanged();
void trustlevelChanged(); void trustlevelChanged();
@ -488,6 +492,9 @@ private:
bool isEncrypted_ = false; bool isEncrypted_ = false;
std::string last_event_id; std::string last_event_id;
std::string fullyReadEventId_; std::string fullyReadEventId_;
std::unique_ptr<RoomSummary> parentSummary = nullptr;
bool parentChecked = false;
}; };
template<class T> template<class T>

@ -6,6 +6,7 @@
#include <QMetaType> #include <QMetaType>
#include "Cache.h"
#include "ChatPage.h" #include "ChatPage.h"
#include "MatrixClient.h" #include "MatrixClient.h"
@ -18,6 +19,38 @@ RoomSummary::RoomSummary(std::string roomIdOrAlias_,
, vias(std::move(vias_)) , vias(std::move(vias_))
, reason_(std::move(r_)) , reason_(std::move(r_))
{ {
if (roomIdOrAlias.empty())
return;
if (roomIdOrAlias[0] == '!') {
auto temp = cache::singleRoomInfo(roomIdOrAlias);
if (temp.member_count) {
mtx::responses::PublicRoom newInfo{};
// newInfo.aliases;
// newInfo.canonical_alias = "";
newInfo.name = temp.name;
newInfo.room_id = roomIdOrAlias;
newInfo.topic = temp.topic;
newInfo.num_joined_members = temp.member_count;
// newInfo.world_readable;
newInfo.guest_can_join = temp.guest_access;
newInfo.avatar_url = temp.avatar_url;
newInfo.join_rule = temp.join_rule;
newInfo.room_type = temp.is_space ? mtx::events::state::room_type::space : "";
newInfo.room_version = temp.version;
newInfo.membership = mtx::events::state::Membership::Join;
// newInfo.encryption;
this->room = std::move(newInfo);
loaded_ = true;
return;
}
// newInfo.encryption;
}
auto ctx = std::make_shared<RoomSummaryProxy>(); auto ctx = std::make_shared<RoomSummaryProxy>();
connect(ctx.get(), &RoomSummaryProxy::failed, this, [this]() { connect(ctx.get(), &RoomSummaryProxy::failed, this, [this]() {
@ -52,3 +85,13 @@ RoomSummary::join()
else else
ChatPage::instance()->joinRoomVia(roomIdOrAlias, vias, false, reason_); ChatPage::instance()->joinRoomVia(roomIdOrAlias, vias, false, reason_);
} }
void
RoomSummary::promptJoin()
{
if (isKnockOnly())
ChatPage::instance()->knockRoom(
QString::fromStdString(roomIdOrAlias), vias, reason_, false, true);
else
ChatPage::instance()->joinRoomVia(roomIdOrAlias, vias, true, reason_);
}

@ -69,6 +69,7 @@ public:
bool isLoaded() const { return room.has_value() || loaded_; } bool isLoaded() const { return room.has_value() || loaded_; }
Q_INVOKABLE void join(); Q_INVOKABLE void join();
Q_INVOKABLE void promptJoin();
signals: signals:
void loaded(); void loaded();

Loading…
Cancel
Save