summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2022-02-04 18:47:17 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2022-02-04 20:48:14 +0100
commit7b00411dc44d188ec1deab302fbcdb0bd2a399e7 (patch)
tree32934f5fc2c32fc4b4b0f5b6f4134baa78e1a265 /src
parentMerge pull request #906 from LorenDB/offlineIndicator (diff)
downloadnheko-7b00411dc44d188ec1deab302fbcdb0bd2a399e7.tar.xz
Show widgets as links
Diffstat (limited to 'src')
-rw-r--r--src/Cache_p.h14
-rw-r--r--src/UserSettingsPage.cpp10
-rw-r--r--src/UserSettingsPage.h6
-rw-r--r--src/timeline/TimelineModel.cpp64
-rw-r--r--src/timeline/TimelineModel.h5
5 files changed, 92 insertions, 7 deletions
diff --git a/src/Cache_p.h b/src/Cache_p.h

index b30e8f47..160ba626 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h
@@ -96,10 +96,12 @@ public: return getStateEvent<T>(txn, room_id, state_key); } template<typename T> - std::vector<mtx::events::StateEvent<T>> getStateEventsWithType(const std::string &room_id) + std::vector<mtx::events::StateEvent<T>> + getStateEventsWithType(const std::string &room_id, + mtx::events::EventType type = mtx::events::state_content_to_type<T>) { auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); - return getStateEventsWithType<T>(txn, room_id); + return getStateEventsWithType<T>(txn, room_id, type); } //! retrieve a specific event from account data @@ -494,13 +496,11 @@ private: template<typename T> std::vector<mtx::events::StateEvent<T>> - getStateEventsWithType(lmdb::txn &txn, const std::string &room_id) + getStateEventsWithType(lmdb::txn &txn, + const std::string &room_id, + mtx::events::EventType type = mtx::events::state_content_to_type<T>) { - constexpr auto type = mtx::events::state_content_to_type<T>; - static_assert(type != mtx::events::EventType::Unsupported, - "Not a supported type in state events."); - if (room_id.empty()) return {}; diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index a0aa8f84..bb7edbb5 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp
@@ -124,6 +124,7 @@ UserSettings::load(std::optional<QString> profile) 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(); + hiddenWidgets_ = settings.value(prefix + "user/hidden_widgets", QStringList{}).toStringList(); recentReactions_ = settings.value(prefix + "user/recent_reactions", QStringList{}).toStringList(); @@ -218,6 +219,14 @@ UserSettings::setHiddenPins(QStringList hiddenTags) } void +UserSettings::setHiddenWidgets(QStringList hiddenTags) +{ + hiddenWidgets_ = hiddenTags; + save(); + emit hiddenWidgetsChanged(); +} + +void UserSettings::setRecentReactions(QStringList recent) { recentReactions_ = recent; @@ -735,6 +744,7 @@ UserSettings::save() settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_); settings.setValue(prefix + "user/hidden_tags", hiddenTags_); settings.setValue(prefix + "user/hidden_pins", hiddenPins_); + settings.setValue(prefix + "user/hidden_widgets", hiddenWidgets_); settings.setValue(prefix + "user/recent_reactions", recentReactions_); QVariantList v; diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index e9b8763d..ebe46672 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h
@@ -107,6 +107,8 @@ class UserSettings : public QObject Q_PROPERTY(QStringList hiddenPins READ hiddenPins WRITE setHiddenPins NOTIFY hiddenPinsChanged) Q_PROPERTY(QStringList recentReactions READ recentReactions WRITE setRecentReactions NOTIFY recentReactionsChanged) + Q_PROPERTY(QStringList hiddenWidgets READ hiddenWidgets WRITE setHiddenWidgets NOTIFY + hiddenWidgetsChanged) UserSettings(); @@ -175,6 +177,7 @@ public: void setDisableCertificateValidation(bool disabled); void setHiddenTags(QStringList hiddenTags); void setHiddenPins(QStringList hiddenTags); + void setHiddenWidgets(QStringList hiddenTags); void setRecentReactions(QStringList recent); void setUseIdenticon(bool state); void setCollapsedSpaces(QList<QStringList> spaces); @@ -234,6 +237,7 @@ public: bool disableCertificateValidation() const { return disableCertificateValidation_; } QStringList hiddenTags() const { return hiddenTags_; } QStringList hiddenPins() const { return hiddenPins_; } + QStringList hiddenWidgets() const { return hiddenWidgets_; } QStringList recentReactions() const { return recentReactions_; } bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); } QList<QStringList> collapsedSpaces() const { return collapsedSpaces_; } @@ -286,6 +290,7 @@ signals: void disableCertificateValidationChanged(bool disabled); void useIdenticonChanged(bool state); void hiddenPinsChanged(); + void hiddenWidgetsChanged(); void recentReactionsChanged(); private: @@ -342,6 +347,7 @@ private: QString homeserver_; QStringList hiddenTags_; QStringList hiddenPins_; + QStringList hiddenWidgets_; QStringList recentReactions_; QList<QStringList> collapsedSpaces_; bool useIdenticon_; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 6b380f79..d1613d5b 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -285,6 +285,9 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t) /// m.room.pinned_events case qml_mtx_events::PinnedEvents: return mtx::events::EventType::RoomPinnedEvents; + /// m.widget + case qml_mtx_events::Widget: + return mtx::events::EventType::Widget; // m.sticker case qml_mtx_events::Sticker: return mtx::events::EventType::Sticker; @@ -852,6 +855,8 @@ TimelineModel::syncState(const mtx::responses::State &s) emit roomTopicChanged(); else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e)) emit pinnedMessagesChanged(); + else if (std::holds_alternative<StateEvent<state::Widget>>(e)) + emit widgetLinksChanged(); else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) { permissions_.invalidate(); emit permissionsChanged(); @@ -916,6 +921,8 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) emit roomTopicChanged(); else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e)) emit pinnedMessagesChanged(); + else if (std::holds_alternative<StateEvent<state::Widget>>(e)) + emit widgetLinksChanged(); else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) { permissions_.invalidate(); emit permissionsChanged(); @@ -2225,6 +2232,63 @@ TimelineModel::pinnedMessages() const return list; } +QStringList +TimelineModel::widgetLinks() const +{ + auto evs = + cache::client()->getStateEventsWithType<mtx::events::state::Widget>(room_id_.toStdString()); + auto evs2 = cache::client()->getStateEventsWithType<mtx::events::state::Widget>( + room_id_.toStdString(), mtx::events::EventType::Widget); + evs.insert( + evs.end(), std::make_move_iterator(evs2.begin()), std::make_move_iterator(evs2.end())); + + if (evs.empty()) + return {}; + + QStringList list; + + auto user = utils::localUser(); + auto av = QUrl::toPercentEncoding(avatarUrl(user)); + auto disp = QUrl::toPercentEncoding(displayName(user)); + auto theme = UserSettings::instance()->theme(); + if (theme == QStringLiteral("system")) + theme.clear(); + user = QUrl::toPercentEncoding(user); + + list.reserve(evs.size()); + for (const auto &p : evs) { + auto url = QString::fromStdString(p.content.url); + for (const auto &[k, v] : p.content.data) + url.replace("$" + QString::fromStdString(k), + QUrl::toPercentEncoding(QString::fromStdString(v))); + + url.replace("$matrix_user_id", user); + url.replace("$matrix_room_id", QUrl::toPercentEncoding(room_id_)); + url.replace("$matrix_display_name", disp); + url.replace("$matrix_avatar_url", av); + + url.replace("$matrix_widget_id", + QUrl::toPercentEncoding(QString::fromStdString(p.content.id))); + + // url.replace("$matrix_client_theme", theme); + url.replace("$org.matrix.msc2873.client_theme", theme); + url.replace("$org.matrix.msc2873.client_id", "im.nheko"); + + // compat with some widgets, i.e. FOSDEM + url.replace("$theme", theme); + + url = QUrl::toPercentEncoding(url, "/:?&@=%"); + + list.push_back( + QLatin1String("<a href='%1'>%2</a>") + .arg(url, + QString::fromStdString(p.content.name.empty() ? p.state_key : p.content.name) + .toHtmlEscaped())); + } + + return list; +} + crypto::Trust TimelineModel::trustlevel() const { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 556f9f54..b4267e8d 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h
@@ -91,6 +91,8 @@ enum EventType Sticker, // m.tag Tag, + // m.widget + Widget, /// m.room.message AudioMessage, EmoteMessage, @@ -178,6 +180,7 @@ class TimelineModel : public QAbstractListModel 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(QStringList widgetLinks READ widgetLinks NOTIFY widgetLinksChanged) Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) Q_PROPERTY(bool isEncrypted READ isEncrypted NOTIFY encryptionChanged) Q_PROPERTY(bool isSpace READ isSpace CONSTANT) @@ -365,6 +368,7 @@ public slots: QString plainRoomName() const; QString roomTopic() const; QStringList pinnedMessages() const; + QStringList widgetLinks() const; InputBar *input() { return &input_; } Permissions *permissions() { return &permissions_; } QString roomAvatarUrl() const; @@ -407,6 +411,7 @@ signals: void plainRoomNameChanged(); void roomTopicChanged(); void pinnedMessagesChanged(); + void widgetLinksChanged(); void roomAvatarUrlChanged(); void roomMemberCountChanged(); void isDirectChanged();