mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-26 04:58:49 +03:00
Show widgets as links
This commit is contained in:
parent
00116e8128
commit
7b00411dc4
8 changed files with 132 additions and 11 deletions
|
@ -402,7 +402,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
MatrixClient
|
MatrixClient
|
||||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
GIT_TAG dc55f64862aeaf02d75383fbdadcbf64ea585506
|
GIT_TAG 29b46c872576d88797178d3c147e8b12b1ac8693
|
||||||
)
|
)
|
||||||
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
||||||
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
||||||
|
|
|
@ -191,7 +191,7 @@ modules:
|
||||||
buildsystem: cmake-ninja
|
buildsystem: cmake-ninja
|
||||||
name: mtxclient
|
name: mtxclient
|
||||||
sources:
|
sources:
|
||||||
- commit: dc55f64862aeaf02d75383fbdadcbf64ea585506
|
- commit: 29b46c872576d88797178d3c147e8b12b1ac8693
|
||||||
#tag: v0.6.1
|
#tag: v0.6.1
|
||||||
type: git
|
type: git
|
||||||
url: https://github.com/Nheko-Reborn/mtxclient.git
|
url: https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
|
|
|
@ -36,7 +36,7 @@ Pane {
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
onSingleTapped: {
|
onSingleTapped: {
|
||||||
if (eventPoint.position.y > topBar.height - (pinnedMessages.visible ? pinnedMessages.height : 0)) {
|
if (eventPoint.position.y > topBar.height - (pinnedMessages.visible ? pinnedMessages.height : 0) - (widgets.visible ? widgets.height : 0)) {
|
||||||
eventPoint.accepted = true
|
eventPoint.accepted = true
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -300,6 +300,42 @@ Pane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScrollHelper {
|
||||||
|
flickable: parent
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: !Settings.mobileMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: widgets
|
||||||
|
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 2
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 1.5)
|
||||||
|
|
||||||
|
visible: !!room && room.widgetLinks.length > 0 && !Settings.hiddenWidgets.includes(roomId)
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
palette: Nheko.colors
|
||||||
|
ScrollBar.horizontal.visible: false
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
|
||||||
|
spacing: Nheko.paddingSmall
|
||||||
|
model: room ? room.widgetLinks : undefined
|
||||||
|
delegate: MatrixText {
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
color: Nheko.colors.text
|
||||||
|
text: modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ScrollHelper {
|
ScrollHelper {
|
||||||
flickable: parent
|
flickable: parent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -311,7 +347,7 @@ Pane {
|
||||||
|
|
||||||
CursorShape {
|
CursorShape {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.bottomMargin: pinnedMessages.visible ? pinnedMessages.height : 0
|
anchors.bottomMargin: (pinnedMessages.visible ? pinnedMessages.height : 0) + (widgets.visible ? widgets.height : 0)
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,10 +96,12 @@ public:
|
||||||
return getStateEvent<T>(txn, room_id, state_key);
|
return getStateEvent<T>(txn, room_id, state_key);
|
||||||
}
|
}
|
||||||
template<typename T>
|
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);
|
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
|
//! retrieve a specific event from account data
|
||||||
|
@ -494,13 +496,11 @@ private:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<mtx::events::StateEvent<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())
|
if (room_id.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ UserSettings::load(std::optional<QString> profile)
|
||||||
deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
|
deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
|
||||||
hiddenTags_ = settings.value(prefix + "user/hidden_tags", QStringList{}).toStringList();
|
hiddenTags_ = settings.value(prefix + "user/hidden_tags", QStringList{}).toStringList();
|
||||||
hiddenPins_ = settings.value(prefix + "user/hidden_pins", QStringList{}).toStringList();
|
hiddenPins_ = settings.value(prefix + "user/hidden_pins", QStringList{}).toStringList();
|
||||||
|
hiddenWidgets_ = settings.value(prefix + "user/hidden_widgets", QStringList{}).toStringList();
|
||||||
recentReactions_ =
|
recentReactions_ =
|
||||||
settings.value(prefix + "user/recent_reactions", QStringList{}).toStringList();
|
settings.value(prefix + "user/recent_reactions", QStringList{}).toStringList();
|
||||||
|
|
||||||
|
@ -217,6 +218,14 @@ UserSettings::setHiddenPins(QStringList hiddenTags)
|
||||||
emit hiddenPinsChanged();
|
emit hiddenPinsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserSettings::setHiddenWidgets(QStringList hiddenTags)
|
||||||
|
{
|
||||||
|
hiddenWidgets_ = hiddenTags;
|
||||||
|
save();
|
||||||
|
emit hiddenWidgetsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UserSettings::setRecentReactions(QStringList recent)
|
UserSettings::setRecentReactions(QStringList recent)
|
||||||
{
|
{
|
||||||
|
@ -735,6 +744,7 @@ UserSettings::save()
|
||||||
settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_);
|
settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_);
|
||||||
settings.setValue(prefix + "user/hidden_tags", hiddenTags_);
|
settings.setValue(prefix + "user/hidden_tags", hiddenTags_);
|
||||||
settings.setValue(prefix + "user/hidden_pins", hiddenPins_);
|
settings.setValue(prefix + "user/hidden_pins", hiddenPins_);
|
||||||
|
settings.setValue(prefix + "user/hidden_widgets", hiddenWidgets_);
|
||||||
settings.setValue(prefix + "user/recent_reactions", recentReactions_);
|
settings.setValue(prefix + "user/recent_reactions", recentReactions_);
|
||||||
|
|
||||||
QVariantList v;
|
QVariantList v;
|
||||||
|
|
|
@ -107,6 +107,8 @@ class UserSettings : public QObject
|
||||||
Q_PROPERTY(QStringList hiddenPins READ hiddenPins WRITE setHiddenPins NOTIFY hiddenPinsChanged)
|
Q_PROPERTY(QStringList hiddenPins READ hiddenPins WRITE setHiddenPins NOTIFY hiddenPinsChanged)
|
||||||
Q_PROPERTY(QStringList recentReactions READ recentReactions WRITE setRecentReactions NOTIFY
|
Q_PROPERTY(QStringList recentReactions READ recentReactions WRITE setRecentReactions NOTIFY
|
||||||
recentReactionsChanged)
|
recentReactionsChanged)
|
||||||
|
Q_PROPERTY(QStringList hiddenWidgets READ hiddenWidgets WRITE setHiddenWidgets NOTIFY
|
||||||
|
hiddenWidgetsChanged)
|
||||||
|
|
||||||
UserSettings();
|
UserSettings();
|
||||||
|
|
||||||
|
@ -175,6 +177,7 @@ public:
|
||||||
void setDisableCertificateValidation(bool disabled);
|
void setDisableCertificateValidation(bool disabled);
|
||||||
void setHiddenTags(QStringList hiddenTags);
|
void setHiddenTags(QStringList hiddenTags);
|
||||||
void setHiddenPins(QStringList hiddenTags);
|
void setHiddenPins(QStringList hiddenTags);
|
||||||
|
void setHiddenWidgets(QStringList hiddenTags);
|
||||||
void setRecentReactions(QStringList recent);
|
void setRecentReactions(QStringList recent);
|
||||||
void setUseIdenticon(bool state);
|
void setUseIdenticon(bool state);
|
||||||
void setCollapsedSpaces(QList<QStringList> spaces);
|
void setCollapsedSpaces(QList<QStringList> spaces);
|
||||||
|
@ -234,6 +237,7 @@ public:
|
||||||
bool disableCertificateValidation() const { return disableCertificateValidation_; }
|
bool disableCertificateValidation() const { return disableCertificateValidation_; }
|
||||||
QStringList hiddenTags() const { return hiddenTags_; }
|
QStringList hiddenTags() const { return hiddenTags_; }
|
||||||
QStringList hiddenPins() const { return hiddenPins_; }
|
QStringList hiddenPins() const { return hiddenPins_; }
|
||||||
|
QStringList hiddenWidgets() const { return hiddenWidgets_; }
|
||||||
QStringList recentReactions() const { return recentReactions_; }
|
QStringList recentReactions() const { return recentReactions_; }
|
||||||
bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); }
|
bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); }
|
||||||
QList<QStringList> collapsedSpaces() const { return collapsedSpaces_; }
|
QList<QStringList> collapsedSpaces() const { return collapsedSpaces_; }
|
||||||
|
@ -286,6 +290,7 @@ signals:
|
||||||
void disableCertificateValidationChanged(bool disabled);
|
void disableCertificateValidationChanged(bool disabled);
|
||||||
void useIdenticonChanged(bool state);
|
void useIdenticonChanged(bool state);
|
||||||
void hiddenPinsChanged();
|
void hiddenPinsChanged();
|
||||||
|
void hiddenWidgetsChanged();
|
||||||
void recentReactionsChanged();
|
void recentReactionsChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -342,6 +347,7 @@ private:
|
||||||
QString homeserver_;
|
QString homeserver_;
|
||||||
QStringList hiddenTags_;
|
QStringList hiddenTags_;
|
||||||
QStringList hiddenPins_;
|
QStringList hiddenPins_;
|
||||||
|
QStringList hiddenWidgets_;
|
||||||
QStringList recentReactions_;
|
QStringList recentReactions_;
|
||||||
QList<QStringList> collapsedSpaces_;
|
QList<QStringList> collapsedSpaces_;
|
||||||
bool useIdenticon_;
|
bool useIdenticon_;
|
||||||
|
|
|
@ -285,6 +285,9 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t)
|
||||||
/// m.room.pinned_events
|
/// m.room.pinned_events
|
||||||
case qml_mtx_events::PinnedEvents:
|
case qml_mtx_events::PinnedEvents:
|
||||||
return mtx::events::EventType::RoomPinnedEvents;
|
return mtx::events::EventType::RoomPinnedEvents;
|
||||||
|
/// m.widget
|
||||||
|
case qml_mtx_events::Widget:
|
||||||
|
return mtx::events::EventType::Widget;
|
||||||
// m.sticker
|
// m.sticker
|
||||||
case qml_mtx_events::Sticker:
|
case qml_mtx_events::Sticker:
|
||||||
return mtx::events::EventType::Sticker;
|
return mtx::events::EventType::Sticker;
|
||||||
|
@ -852,6 +855,8 @@ TimelineModel::syncState(const mtx::responses::State &s)
|
||||||
emit roomTopicChanged();
|
emit roomTopicChanged();
|
||||||
else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e))
|
else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e))
|
||||||
emit pinnedMessagesChanged();
|
emit pinnedMessagesChanged();
|
||||||
|
else if (std::holds_alternative<StateEvent<state::Widget>>(e))
|
||||||
|
emit widgetLinksChanged();
|
||||||
else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) {
|
else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) {
|
||||||
permissions_.invalidate();
|
permissions_.invalidate();
|
||||||
emit permissionsChanged();
|
emit permissionsChanged();
|
||||||
|
@ -916,6 +921,8 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
|
||||||
emit roomTopicChanged();
|
emit roomTopicChanged();
|
||||||
else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e))
|
else if (std::holds_alternative<StateEvent<state::PinnedEvents>>(e))
|
||||||
emit pinnedMessagesChanged();
|
emit pinnedMessagesChanged();
|
||||||
|
else if (std::holds_alternative<StateEvent<state::Widget>>(e))
|
||||||
|
emit widgetLinksChanged();
|
||||||
else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) {
|
else if (std::holds_alternative<StateEvent<state::PowerLevels>>(e)) {
|
||||||
permissions_.invalidate();
|
permissions_.invalidate();
|
||||||
emit permissionsChanged();
|
emit permissionsChanged();
|
||||||
|
@ -2225,6 +2232,63 @@ TimelineModel::pinnedMessages() const
|
||||||
return list;
|
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
|
crypto::Trust
|
||||||
TimelineModel::trustlevel() const
|
TimelineModel::trustlevel() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,6 +91,8 @@ enum EventType
|
||||||
Sticker,
|
Sticker,
|
||||||
// m.tag
|
// m.tag
|
||||||
Tag,
|
Tag,
|
||||||
|
// m.widget
|
||||||
|
Widget,
|
||||||
/// m.room.message
|
/// m.room.message
|
||||||
AudioMessage,
|
AudioMessage,
|
||||||
EmoteMessage,
|
EmoteMessage,
|
||||||
|
@ -178,6 +180,7 @@ class TimelineModel : public QAbstractListModel
|
||||||
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged)
|
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged)
|
||||||
Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged)
|
Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged)
|
||||||
Q_PROPERTY(QStringList pinnedMessages READ pinnedMessages NOTIFY pinnedMessagesChanged)
|
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(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged)
|
||||||
Q_PROPERTY(bool isEncrypted READ isEncrypted NOTIFY encryptionChanged)
|
Q_PROPERTY(bool isEncrypted READ isEncrypted NOTIFY encryptionChanged)
|
||||||
Q_PROPERTY(bool isSpace READ isSpace CONSTANT)
|
Q_PROPERTY(bool isSpace READ isSpace CONSTANT)
|
||||||
|
@ -365,6 +368,7 @@ public slots:
|
||||||
QString plainRoomName() const;
|
QString plainRoomName() const;
|
||||||
QString roomTopic() const;
|
QString roomTopic() const;
|
||||||
QStringList pinnedMessages() const;
|
QStringList pinnedMessages() const;
|
||||||
|
QStringList widgetLinks() const;
|
||||||
InputBar *input() { return &input_; }
|
InputBar *input() { return &input_; }
|
||||||
Permissions *permissions() { return &permissions_; }
|
Permissions *permissions() { return &permissions_; }
|
||||||
QString roomAvatarUrl() const;
|
QString roomAvatarUrl() const;
|
||||||
|
@ -407,6 +411,7 @@ signals:
|
||||||
void plainRoomNameChanged();
|
void plainRoomNameChanged();
|
||||||
void roomTopicChanged();
|
void roomTopicChanged();
|
||||||
void pinnedMessagesChanged();
|
void pinnedMessagesChanged();
|
||||||
|
void widgetLinksChanged();
|
||||||
void roomAvatarUrlChanged();
|
void roomAvatarUrlChanged();
|
||||||
void roomMemberCountChanged();
|
void roomMemberCountChanged();
|
||||||
void isDirectChanged();
|
void isDirectChanged();
|
||||||
|
|
Loading…
Reference in a new issue