mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 17:40:47 +03:00
Show the community of a room
This commit is contained in:
parent
7088c9bd9b
commit
421b15c05c
8 changed files with 143 additions and 10 deletions
|
@ -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…
Reference in a new issue