mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 09:30: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;
|
||||
}
|
||||
|
||||
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) {
|
||||
let p = topBar.mapToItem(roomTopicC, eventPoint.position.x, eventPoint.position.y);
|
||||
let link = roomTopicC.linkAt(p.x, p.y);
|
||||
|
@ -80,11 +87,46 @@ Pane {
|
|||
columnSpacing: 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 {
|
||||
id: backToRoomsButton
|
||||
|
||||
Layout.column: 0
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
Layout.rowSpan: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
|
||||
|
@ -98,7 +140,7 @@ Pane {
|
|||
|
||||
Avatar {
|
||||
Layout.column: 1
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
Layout.rowSpan: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
width: Nheko.avatarSize
|
||||
|
@ -113,9 +155,10 @@ Pane {
|
|||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.column: 2
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
color: Nheko.colors.text
|
||||
font.pointSize: fontMetrics.font.pointSize * 1.1
|
||||
font.bold: true
|
||||
text: roomName
|
||||
maximumLineCount: 1
|
||||
elide: Text.ElideRight
|
||||
|
@ -126,7 +169,7 @@ Pane {
|
|||
id: roomTopicC
|
||||
Layout.fillWidth: true
|
||||
Layout.column: 2
|
||||
Layout.row: 1
|
||||
Layout.row: 2
|
||||
Layout.maximumHeight: fontMetrics.lineSpacing * 2 // show 2 lines
|
||||
selectByMouse: false
|
||||
enabled: false
|
||||
|
@ -136,7 +179,7 @@ Pane {
|
|||
|
||||
AbstractButton {
|
||||
Layout.column: 3
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
Layout.rowSpan: 2
|
||||
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
|
||||
Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium
|
||||
|
@ -179,7 +222,7 @@ Pane {
|
|||
|
||||
visible: !!room && room.pinnedMessages.length > 0
|
||||
Layout.column: 4
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
Layout.rowSpan: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
|
||||
|
@ -207,7 +250,7 @@ Pane {
|
|||
|
||||
visible: !!room
|
||||
Layout.column: 5
|
||||
Layout.row: 0
|
||||
Layout.row: 1
|
||||
Layout.rowSpan: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium
|
||||
|
@ -248,7 +291,7 @@ Pane {
|
|||
ScrollView {
|
||||
id: pinnedMessages
|
||||
|
||||
Layout.row: 2
|
||||
Layout.row: 3
|
||||
Layout.column: 2
|
||||
Layout.columnSpan: 3
|
||||
|
||||
|
@ -329,7 +372,7 @@ Pane {
|
|||
ScrollView {
|
||||
id: widgets
|
||||
|
||||
Layout.row: 3
|
||||
Layout.row: 4
|
||||
Layout.column: 2
|
||||
Layout.columnSpan: 1
|
||||
|
||||
|
|
|
@ -122,7 +122,6 @@ ApplicationWindow {
|
|||
|
||||
placeholderText: qsTr("Enter additional rooms not in the list yet...")
|
||||
|
||||
//font.pixelSize: Math.ceil(quickSwitcher.textHeight * 0.6)
|
||||
color: Nheko.colors.text
|
||||
onTextEdited: {
|
||||
roomCompleter.completer.searchString = text;
|
||||
|
|
|
@ -605,6 +605,20 @@ CommunitiesModel::setCurrentTagId(const QString &tagId)
|
|||
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
|
||||
CommunitiesModel::toggleTagId(QString tagId)
|
||||
{
|
||||
|
|
|
@ -179,6 +179,7 @@ public slots:
|
|||
void clear();
|
||||
QString currentTagId() const { return currentTagId_; }
|
||||
void setCurrentTagId(const QString &tagId);
|
||||
bool trySwitchToSpace(const QString &spaceId);
|
||||
void resetCurrentTagId()
|
||||
{
|
||||
currentTagId_.clear();
|
||||
|
|
|
@ -915,6 +915,9 @@ TimelineModel::syncState(const mtx::responses::State &s)
|
|||
} else if (std::holds_alternative<StateEvent<state::Encryption>>(e)) {
|
||||
this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString());
|
||||
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)) {
|
||||
this->isEncrypted_ = cache::isRoomEncrypted(room_id_.toStdString());
|
||||
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
|
||||
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 "Permissions.h"
|
||||
#include "ReadReceiptsModel.h"
|
||||
#include "ui/RoomSummary.h"
|
||||
|
||||
namespace mtx::http {
|
||||
using RequestErr = const std::optional<mtx::http::ClientError> &;
|
||||
|
@ -197,6 +198,7 @@ class TimelineModel : public QAbstractListModel
|
|||
QString directChatOtherUserId READ directChatOtherUserId NOTIFY directChatOtherUserIdChanged)
|
||||
Q_PROPERTY(InputBar *input READ input CONSTANT)
|
||||
Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged)
|
||||
Q_PROPERTY(RoomSummary *parentSpace READ parentSpace NOTIFY parentSpaceChanged)
|
||||
|
||||
public:
|
||||
explicit TimelineModel(TimelineViewManager *manager,
|
||||
|
@ -397,6 +399,7 @@ public slots:
|
|||
Permissions *permissions() { return &permissions_; }
|
||||
QString roomAvatarUrl() const;
|
||||
QString roomId() const { return room_id_; }
|
||||
RoomSummary *parentSpace();
|
||||
|
||||
bool hasMentions() const { return highlight_count > 0; }
|
||||
int notificationCount() const { return notification_count; }
|
||||
|
@ -431,6 +434,7 @@ signals:
|
|||
void addPendingMessageToStore(mtx::events::collections::TimelineEvents event);
|
||||
void updateFlowEventId(std::string event_id);
|
||||
|
||||
void parentSpaceChanged();
|
||||
void encryptionChanged();
|
||||
void fullyReadEventIdChanged();
|
||||
void trustlevelChanged();
|
||||
|
@ -488,6 +492,9 @@ private:
|
|||
bool isEncrypted_ = false;
|
||||
std::string last_event_id;
|
||||
std::string fullyReadEventId_;
|
||||
|
||||
std::unique_ptr<RoomSummary> parentSummary = nullptr;
|
||||
bool parentChecked = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <QMetaType>
|
||||
|
||||
#include "Cache.h"
|
||||
#include "ChatPage.h"
|
||||
#include "MatrixClient.h"
|
||||
|
||||
|
@ -18,6 +19,38 @@ RoomSummary::RoomSummary(std::string roomIdOrAlias_,
|
|||
, vias(std::move(vias_))
|
||||
, 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>();
|
||||
|
||||
connect(ctx.get(), &RoomSummaryProxy::failed, this, [this]() {
|
||||
|
@ -52,3 +85,13 @@ RoomSummary::join()
|
|||
else
|
||||
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_; }
|
||||
|
||||
Q_INVOKABLE void join();
|
||||
Q_INVOKABLE void promptJoin();
|
||||
|
||||
signals:
|
||||
void loaded();
|
||||
|
|
Loading…
Reference in a new issue