summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-12-11 06:10:41 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2021-12-11 06:10:41 +0100
commit75b112f0c830dd3a87d1c428a8ad5a8449b8e924 (patch)
treea04f054b0965e62cefb0527d0368aabb7a879e15 /src
parentFix escaped html showing up in playable media message labels (diff)
downloadnheko-75b112f0c830dd3a87d1c428a8ad5a8449b8e924.tar.xz
Support pinned messages
fixes #519
Diffstat (limited to 'src')
-rw-r--r--src/UserSettingsPage.cpp10
-rw-r--r--src/UserSettingsPage.h6
-rw-r--r--src/timeline/TimelineModel.cpp87
-rw-r--r--src/timeline/TimelineModel.h9
4 files changed, 111 insertions, 1 deletions
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp

index 5ba1dcdc..eae31b71 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp
@@ -117,6 +117,7 @@ UserSettings::load(std::optional<QString> profile) userId_ = settings.value(prefix + "auth/user_id", "").toString(); deviceId_ = settings.value(prefix + "auth/device_id", "").toString(); hiddenTags_ = settings.value(prefix + "user/hidden_tags", QStringList{}).toStringList(); + hiddenPins_ = settings.value(prefix + "user/hidden_pins", QStringList{}).toStringList(); collapsedSpaces_.clear(); for (const auto &e : @@ -201,6 +202,14 @@ UserSettings::setHiddenTags(QStringList hiddenTags) } void +UserSettings::setHiddenPins(QStringList hiddenTags) +{ + hiddenPins_ = hiddenTags; + save(); + emit hiddenPinsChanged(); +} + +void UserSettings::setCollapsedSpaces(QList<QStringList> spaces) { collapsedSpaces_ = spaces; @@ -707,6 +716,7 @@ UserSettings::save() onlyShareKeysWithVerifiedUsers_); settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_); settings.setValue(prefix + "user/hidden_tags", hiddenTags_); + settings.setValue(prefix + "user/hidden_pins", hiddenPins_); QVariantList v; for (const auto &e : collapsedSpaces_) diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index c47844cb..ab73414e 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h
@@ -105,6 +105,8 @@ class UserSettings : public QObject setDisableCertificateValidation NOTIFY disableCertificateValidationChanged) Q_PROPERTY(bool useIdenticon READ useIdenticon WRITE setUseIdenticon NOTIFY useIdenticonChanged) + Q_PROPERTY(QStringList hiddenPins READ hiddenPins WRITE setHiddenPins NOTIFY hiddenPinsChanged) + UserSettings(); public: @@ -171,6 +173,7 @@ public: void setHomeserver(QString homeserver); void setDisableCertificateValidation(bool disabled); void setHiddenTags(QStringList hiddenTags); + void setHiddenPins(QStringList hiddenTags); void setUseIdenticon(bool state); void setCollapsedSpaces(QList<QStringList> spaces); @@ -228,6 +231,7 @@ public: QString homeserver() const { return homeserver_; } bool disableCertificateValidation() const { return disableCertificateValidation_; } QStringList hiddenTags() const { return hiddenTags_; } + QStringList hiddenPins() const { return hiddenPins_; } bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); } QList<QStringList> collapsedSpaces() const { return collapsedSpaces_; } @@ -278,6 +282,7 @@ signals: void homeserverChanged(QString homeserver); void disableCertificateValidationChanged(bool disabled); void useIdenticonChanged(bool state); + void hiddenPinsChanged(); private: // Default to system theme if QT_QPA_PLATFORMTHEME var is set. @@ -331,6 +336,7 @@ private: QString deviceId_; QString homeserver_; QStringList hiddenTags_; + QStringList hiddenPins_; QList<QStringList> collapsedSpaces_; bool useIdenticon_; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 5a5f4850..b9941dfa 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -93,6 +93,10 @@ struct RoomEventType return qml_mtx_events::EventType::Sticker; case EventType::Tag: return qml_mtx_events::EventType::Tag; + case EventType::SpaceParent: + return qml_mtx_events::EventType::SpaceParent; + case EventType::SpaceChild: + return qml_mtx_events::EventType::SpaceChild; case EventType::Unsupported: return qml_mtx_events::EventType::Unsupported; default: @@ -286,6 +290,12 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t) // m.tag case qml_mtx_events::Tag: return mtx::events::EventType::Tag; + // m.space.parent + case qml_mtx_events::SpaceParent: + return mtx::events::EventType::SpaceParent; + // m.space.child + case qml_mtx_events::SpaceChild: + return mtx::events::EventType::SpaceChild; /// m.room.message case qml_mtx_events::AudioMessage: case qml_mtx_events::EmoteMessage: @@ -808,7 +818,9 @@ TimelineModel::syncState(const mtx::responses::State &s) emit roomNameChanged(); else if (std::holds_alternative<StateEvent<state::Topic>>(e)) emit roomTopicChanged(); - else if (std::holds_alternative<StateEvent<state::Topic>>(e)) { + else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e)) + emit pinnedMessagesChanged(); + else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) { permissions_.invalidate(); emit permissionsChanged(); } else if (std::holds_alternative<StateEvent<state::Member>>(e)) { @@ -870,6 +882,8 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) emit roomNameChanged(); else if (std::holds_alternative<StateEvent<state::Topic>>(e)) emit roomTopicChanged(); + else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e)) + emit pinnedMessagesChanged(); else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) { permissions_.invalidate(); emit permissionsChanged(); @@ -1085,6 +1099,60 @@ TimelineModel::replyAction(QString id) } void +TimelineModel::unpin(QString id) +{ + auto pinned = + cache::client()->getStateEvent<mtx::events::state::PinnedEvents>(room_id_.toStdString()); + + mtx::events::state::PinnedEvents content{}; + if (pinned) + content = pinned->content; + + auto idStr = id.toStdString(); + + for (auto it = content.pinned.begin(); it != content.pinned.end(); ++it) { + if (*it == idStr) { + content.pinned.erase(it); + break; + } + } + + http::client()->send_state_event( + room_id_.toStdString(), + content, + [idStr](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) + nhlog::net()->error("Failed to unpin {}: {}", idStr, *err); + else + nhlog::net()->debug("Unpinned {}", idStr); + }); +} + +void +TimelineModel::pin(QString id) +{ + auto pinned = + cache::client()->getStateEvent<mtx::events::state::PinnedEvents>(room_id_.toStdString()); + + mtx::events::state::PinnedEvents content{}; + if (pinned) + content = pinned->content; + + auto idStr = id.toStdString(); + content.pinned.push_back(idStr); + + http::client()->send_state_event( + room_id_.toStdString(), + content, + [idStr](const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) + nhlog::net()->error("Failed to pin {}: {}", idStr, *err); + else + nhlog::net()->debug("Pinned {}", idStr); + }); +} + +void TimelineModel::editAction(QString id) { setEdit(id); @@ -2108,6 +2176,23 @@ TimelineModel::roomTopic() const utils::linkifyMessage(QString::fromStdString(info[room_id_].topic).toHtmlEscaped())); } +QStringList +TimelineModel::pinnedMessages() const +{ + auto pinned = + cache::client()->getStateEvent<mtx::events::state::PinnedEvents>(room_id_.toStdString()); + + if (!pinned || pinned->content.pinned.empty()) + return {}; + + QStringList list; + list.reserve(pinned->content.pinned.size()); + for (const auto &p : pinned->content.pinned) + list.push_back(QString::fromStdString(p)); + + return list; +} + crypto::Trust TimelineModel::trustlevel() const { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index fe09af75..a06d4063 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -115,6 +115,10 @@ enum EventType ImagePackInAccountData, //! m.image_pack.rooms, currently im.ponies.emote_rooms ImagePackRooms, + // m.space.parent + SpaceParent, + // m.space.child + SpaceChild, }; Q_ENUM_NS(EventType) mtx::events::EventType fromRoomEventType(qml_mtx_events::EventType); @@ -172,6 +176,7 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString plainRoomName READ plainRoomName NOTIFY plainRoomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) + Q_PROPERTY(QStringList pinnedMessages READ pinnedMessages NOTIFY pinnedMessagesChanged) Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) Q_PROPERTY(bool isEncrypted READ isEncrypted NOTIFY encryptionChanged) Q_PROPERTY(bool isSpace READ isSpace CONSTANT) @@ -256,6 +261,8 @@ public: Q_INVOKABLE void openUserProfile(QString userid); Q_INVOKABLE void editAction(QString id); Q_INVOKABLE void replyAction(QString id); + Q_INVOKABLE void unpin(QString id); + Q_INVOKABLE void pin(QString id); Q_INVOKABLE void showReadReceipts(QString id); Q_INVOKABLE void redactEvent(QString id); Q_INVOKABLE int idToIndex(QString id) const; @@ -354,6 +361,7 @@ public slots: QString roomName() const; QString plainRoomName() const; QString roomTopic() const; + QStringList pinnedMessages() const; InputBar *input() { return &input_; } Permissions *permissions() { return &permissions_; } QString roomAvatarUrl() const; @@ -395,6 +403,7 @@ signals: void roomNameChanged(); void plainRoomNameChanged(); void roomTopicChanged(); + void pinnedMessagesChanged(); void roomAvatarUrlChanged(); void roomMemberCountChanged(); void isDirectChanged();