Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F111980
D170.1732245708.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
14 KB
Referenced Files
None
Subscribers
None
D170.1732245708.diff
View Options
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -213,6 +213,8 @@
room-settings/RoomTagHandler.qml
room-settings/RoomMemberListPage.qml
room-settings/RoomInvitePage.qml
+ room-settings/RoomStickerPacksPage.qml
+ room-settings/RoomStickerPackItemDelegate.qml
device-mgmt/Device.qml
device-mgmt/DeviceList.qml
diff --git a/src/contents/ui/Main.qml b/src/contents/ui/Main.qml
--- a/src/contents/ui/Main.qml
+++ b/src/contents/ui/Main.qml
@@ -233,6 +233,12 @@
});
}
+ function activateRoomStickerPacksPage(room) {
+ pageStack.push(Qt.resolvedUrl("room-settings/RoomStickerPacksPage.qml"), {
+ room
+ });
+ }
+
function activateUserPage(user, room, userId) {
pageStack.push(Qt.resolvedUrl("UserPage.qml"), {
userId: userId || user.userId,
diff --git a/src/contents/ui/room-settings/RoomSettingsPage.qml b/src/contents/ui/room-settings/RoomSettingsPage.qml
--- a/src/contents/ui/room-settings/RoomSettingsPage.qml
+++ b/src/contents/ui/room-settings/RoomSettingsPage.qml
@@ -282,6 +282,16 @@
}
}
+ Button {
+ objectName: 'stickerPacksButton'
+ text: l10n.get('room-sticker-packs-action')
+ icon.name: 'smiley'
+ Layout.fillWidth: true
+ onClicked: {
+ activateRoomStickerPacksPage(roomSettingsPage.room);
+ }
+ }
+
Button {
text: l10n.get('room-invite-action')
icon.name: 'list-add-user'
diff --git a/src/contents/ui/room-settings/RoomStickerPackItemDelegate.qml b/src/contents/ui/room-settings/RoomStickerPackItemDelegate.qml
new file mode 100644
--- /dev/null
+++ b/src/contents/ui/room-settings/RoomStickerPackItemDelegate.qml
@@ -0,0 +1,21 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2024 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import org.kde.kirigami as Kirigami
+import moe.kazv.mxc.kazv as MK
+import '..' as Kazv
+import '.' as RoomSettings
+
+Kirigami.SwipeListItem {
+ property var stickerPack
+
+ contentItem: Label {
+ text: stickerPack.packName || stickerPack.stateKey
+ }
+}
diff --git a/src/contents/ui/room-settings/RoomStickerPacksPage.qml b/src/contents/ui/room-settings/RoomStickerPacksPage.qml
new file mode 100644
--- /dev/null
+++ b/src/contents/ui/room-settings/RoomStickerPacksPage.qml
@@ -0,0 +1,35 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2024 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import org.kde.kirigami as Kirigami
+import moe.kazv.mxc.kazv as MK
+import '..' as Kazv
+import '.' as RoomSettings
+
+Kazv.ClosableScrollablePage {
+ id: roomStickerPacksPage
+
+ property var room
+ property var stickerPackList: room.stickerPackList()
+ property var roomNameProvider: Kazv.RoomNameProvider {
+ room: roomStickerPacksPage.room
+ }
+
+ title: l10n.get('room-sticker-packs-page-title', {
+ room: roomNameProvider.name,
+ })
+
+ ListView {
+ model: roomStickerPacksPage.stickerPackList
+ delegate: RoomSettings.RoomStickerPackItemDelegate {
+ required property int index
+ stickerPack: stickerPackList.at(index)
+ }
+ }
+}
diff --git a/src/l10n/cmn-Hans/100-ui.ftl b/src/l10n/cmn-Hans/100-ui.ftl
--- a/src/l10n/cmn-Hans/100-ui.ftl
+++ b/src/l10n/cmn-Hans/100-ui.ftl
@@ -111,6 +111,8 @@
room-settings-save-topic-action = 保存话题
room-settings-discard-topic-action = 放弃话题
room-settings-set-topic-failed-prompt = 不能设置话题。错误代码:{ $errorCode }。错误讯息:{ $errorMsg }。
+room-sticker-packs-action = 贴纸包...
+room-sticker-packs-page-title = { $room } 中的贴纸包
room-member-list-page-title = { $room } 的成员
diff --git a/src/l10n/en/100-ui.ftl b/src/l10n/en/100-ui.ftl
--- a/src/l10n/en/100-ui.ftl
+++ b/src/l10n/en/100-ui.ftl
@@ -115,6 +115,8 @@
room-settings-save-topic-action = Save topic
room-settings-discard-topic-action = Discard topic
room-settings-set-topic-failed-prompt = Cannot set topic. Error code: { $errorCode }. Error message: { $errorMsg }.
+room-sticker-packs-action = Sticker packs...
+room-sticker-packs-page-title = Sticker packs in { $room }
room-member-list-page-title = Members of { $room }
diff --git a/src/matrix-room.hpp b/src/matrix-room.hpp
--- a/src/matrix-room.hpp
+++ b/src/matrix-room.hpp
@@ -17,6 +17,7 @@
#include <client/room/room.hpp>
Q_MOC_INCLUDE("matrix-room-timeline.hpp")
Q_MOC_INCLUDE("matrix-room-pinned-events-timeline.hpp")
+Q_MOC_INCLUDE("matrix-sticker-pack-list.hpp")
class MatrixRoomTimeline;
class MatrixRoomPinnedEventsTimeline;
@@ -24,6 +25,7 @@
class MatrixPromise;
class MatrixRoomMemberListModel;
class MatrixEvent;
+class MatrixStickerPackList;
nlohmann::json makeTextMessageJson(const QString &text, const QString &relType, const QString &relatedTo, Kazv::Event replyToEvent);
@@ -152,6 +154,13 @@
Q_INVOKABLE MatrixPromise *setTopic(const QString &newTopic) const;
+ /**
+ * Get the sticker pack list defined in this room.
+ *
+ * @return A list of sticker packs defined in this room.
+ */
+ Q_INVOKABLE MatrixStickerPackList *stickerPackList() const;
+
Q_SIGNALS:
void powerLevelsChanged();
diff --git a/src/matrix-room.cpp b/src/matrix-room.cpp
--- a/src/matrix-room.cpp
+++ b/src/matrix-room.cpp
@@ -21,6 +21,7 @@
#include "matrix-room-member-list-model.hpp"
#include "matrix-promise.hpp"
#include "matrix-event.hpp"
+#include "matrix-sticker-pack-list.hpp"
#include "kazv-markdown.hpp"
#include "qt-json.hpp"
#include "qfunctionutils.hpp"
@@ -562,3 +563,8 @@
{
return new MatrixPromise(m_room.setTopic(newTopic.toStdString()));
}
+
+MatrixStickerPackList *MatrixRoom::stickerPackList() const
+{
+ return new MatrixStickerPackList(m_room);
+}
diff --git a/src/matrix-sticker-pack-list.hpp b/src/matrix-sticker-pack-list.hpp
--- a/src/matrix-sticker-pack-list.hpp
+++ b/src/matrix-sticker-pack-list.hpp
@@ -29,11 +29,13 @@
QML_ELEMENT
QML_UNCREATABLE("")
- Kazv::Client m_client;
lager::reader<immer::flex_vector<MatrixStickerPackSource>> m_events;
public:
+ /// gets a list of sticker packs available by user settings
explicit MatrixStickerPackList(Kazv::Client client, QObject *parent = 0);
+ /// gets a list of sticker packs defined in a room
+ explicit MatrixStickerPackList(Kazv::Room room, QObject *parent = 0);
~MatrixStickerPackList() override;
Q_INVOKABLE MatrixStickerPack *at(int index) const;
diff --git a/src/matrix-sticker-pack-list.cpp b/src/matrix-sticker-pack-list.cpp
--- a/src/matrix-sticker-pack-list.cpp
+++ b/src/matrix-sticker-pack-list.cpp
@@ -35,7 +35,7 @@
const immer::map<std::string, RoomModel> &rooms) {
// This transformation function takes O(|room sticker packs specified in account data|).
auto res = immer::flex_vector<MatrixStickerPackSource>{
- {MatrixStickerPackSource::AccountData, accountDataEventType, userEmotes}
+ {MatrixStickerPackSource::AccountData, accountDataEventType, userEmotes, "", ""}
}.transient();
for (const auto &[roomId, stateKeyMap] : emoteRooms) {
@@ -43,7 +43,9 @@
res.push_back(MatrixStickerPackSource{
MatrixStickerPackSource::RoomState,
roomStateEventType,
- rooms[roomId].stateEvents[KeyOfState{roomStateEventType, stateKey}]
+ rooms[roomId].stateEvents[KeyOfState{roomStateEventType, stateKey}],
+ roomId,
+ stateKey,
});
}
}
@@ -52,10 +54,41 @@
}).make();
}
+lager::reader<immer::flex_vector<MatrixStickerPackSource>> getEventsFromRoom(Room room)
+{
+ return lager::with(room.roomId(), room.stateEvents())
+ .map([](const auto &roomId, const auto &state) {
+ return intoImmer(
+ immer::flex_vector<MatrixStickerPackSource>{},
+ zug::filter([](const auto &pair) {
+ return pair.first.type == roomStateEventType;
+ })
+ | zug::map([roomId](const auto &pair) {
+ return MatrixStickerPackSource{
+ MatrixStickerPackSource::RoomState,
+ roomStateEventType,
+ pair.second,
+ roomId,
+ pair.first.stateKey,
+ };
+ }),
+ state
+ );
+ });
+}
+
MatrixStickerPackList::MatrixStickerPackList(Client client, QObject *parent)
: KazvAbstractListModel(parent)
- , m_client(client)
- , m_events(getEventsFromClient(m_client))
+ , m_events(getEventsFromClient(client))
+{
+ initCountCursor(m_events.map([](const auto &events) {
+ return static_cast<int>(events.size());
+ }));
+}
+
+MatrixStickerPackList::MatrixStickerPackList(Room room, QObject *parent)
+ : KazvAbstractListModel(parent)
+ , m_events(getEventsFromRoom(room))
{
initCountCursor(m_events.map([](const auto &events) {
return static_cast<int>(events.size());
@@ -74,6 +107,8 @@
MatrixStickerPackSource::AccountData,
accountDataEventType,
Event(),
+ "",
+ "",
};
}
}));
diff --git a/src/matrix-sticker-pack-source.hpp b/src/matrix-sticker-pack-source.hpp
--- a/src/matrix-sticker-pack-source.hpp
+++ b/src/matrix-sticker-pack-source.hpp
@@ -20,6 +20,10 @@
Source source;
std::string eventType;
Kazv::Event event;
+ /// the room id, only applicable when source is RoomState
+ std::string roomId;
+ /// the state key, only applicable when source is RoomState
+ std::string stateKey;
};
bool operator==(const MatrixStickerPackSource &a, const MatrixStickerPackSource &b);
diff --git a/src/matrix-sticker-pack.hpp b/src/matrix-sticker-pack.hpp
--- a/src/matrix-sticker-pack.hpp
+++ b/src/matrix-sticker-pack.hpp
@@ -40,6 +40,10 @@
Q_INVOKABLE MatrixSticker *at(int index) const;
LAGER_QT_READER(QString, packName);
+ LAGER_QT_READER(bool, isAccountData);
+ LAGER_QT_READER(bool, isState);
+ LAGER_QT_READER(QString, roomId);
+ LAGER_QT_READER(QString, stateKey);
Q_INVOKABLE bool hasShortCode(const QString &shortCode) const;
diff --git a/src/matrix-sticker-pack.cpp b/src/matrix-sticker-pack.cpp
--- a/src/matrix-sticker-pack.cpp
+++ b/src/matrix-sticker-pack.cpp
@@ -39,6 +39,14 @@
}
})))
, LAGER_QT(packName)(m_event.xform(eventContent | jsonAtOr("/pack/display_name"_json_pointer, std::string()) | strToQt))
+ , LAGER_QT(isAccountData)(m_source.map([](const auto &source) {
+ return source.source == MatrixStickerPackSource::AccountData;
+ }))
+ , LAGER_QT(isState)(m_source.map([](const auto &source) {
+ return source.source == MatrixStickerPackSource::RoomState;
+ }))
+ , LAGER_QT(roomId)(m_source[&MatrixStickerPackSource::roomId].xform(strToQt))
+ , LAGER_QT(stateKey)(m_source[&MatrixStickerPackSource::stateKey].xform(strToQt))
{
initCountCursor(m_images.map([](const JsonWrap &images) -> int {
return images.get().size();
diff --git a/src/tests/matrix-sticker-pack-test.cpp b/src/tests/matrix-sticker-pack-test.cpp
--- a/src/tests/matrix-sticker-pack-test.cpp
+++ b/src/tests/matrix-sticker-pack-test.cpp
@@ -23,6 +23,8 @@
#include "matrix-sticker.hpp"
#include "matrix-event.hpp"
#include "matrix-sdk.hpp"
+#include "matrix-room-list.hpp"
+#include "matrix-room.hpp"
using namespace Qt::Literals::StringLiterals;
using namespace Kazv;
@@ -35,6 +37,7 @@
private Q_SLOTS:
void testStickerPack();
void testStickerPackList();
+ void testStickerPackListInRoom();
void testAddToPack();
};
@@ -105,12 +108,22 @@
return Event(j);
}
+template<class Range>
+static bool hasPack(const Range &packs, const QString &name)
+{
+ return std::any_of(packs.begin(), packs.end(), [&name](const auto &pack) {
+ return pack->packName() == name;
+ });
+}
+
void MatrixStickerPackTest::testStickerPack()
{
auto sourceCursor = lager::make_state(MatrixStickerPackSource{
MatrixStickerPackSource::AccountData,
"im.ponies.user_emotes",
stickerPackEvent,
+ "",
+ ""
}, lager::automatic_tag{});
auto stickerPack = toUniquePtr(new MatrixStickerPack(sourceCursor));
@@ -178,16 +191,36 @@
toUniquePtr(stickerPackList->at(3)),
};
- auto hasPack = [&packs](const QString &name) {
- return std::any_of(packs.begin(), packs.end(), [&name](const auto &pack) {
- return pack->packName() == name;
- });
+ QVERIFY(hasPack(packs, u"Awesome Pack"_s));
+ QVERIFY(hasPack(packs, u"Pack 1"_s));
+ QVERIFY(hasPack(packs, u"Pack 2"_s));
+ QVERIFY(hasPack(packs, u"Pack 3"_s));
+}
+
+void MatrixStickerPackTest::testStickerPackListInRoom()
+{
+ auto model = makeClient(
+ withRoom(makeRoom(
+ withRoomId("!someroom:example.org")
+ | withRoomState({
+ getRoomStickersEvent("", "Pack 1"),
+ getRoomStickersEvent("de.sorunome.mx-puppet-bridge.discord", "Pack 2"),
+ })
+ ))
+ );
+ std::unique_ptr<MatrixSdk> sdk{makeTestSdk(SdkModel{model})};
+ auto roomList = toUniquePtr(sdk->roomList());
+ auto room = toUniquePtr(roomList->room(u"!someroom:example.org"_s));
+ auto stickerPackList = toUniquePtr(room->stickerPackList());
+ QCOMPARE(stickerPackList->count(), 2);
+
+ auto packs = std::array<std::unique_ptr<MatrixStickerPack>, 2>{
+ toUniquePtr(stickerPackList->at(0)),
+ toUniquePtr(stickerPackList->at(1)),
};
- QVERIFY(hasPack(u"Awesome Pack"_s));
- QVERIFY(hasPack(u"Pack 1"_s));
- QVERIFY(hasPack(u"Pack 2"_s));
- QVERIFY(hasPack(u"Pack 3"_s));
+ QVERIFY(hasPack(packs, u"Pack 1"_s));
+ QVERIFY(hasPack(packs, u"Pack 2"_s));
}
void MatrixStickerPackTest::testAddToPack()
@@ -198,6 +231,8 @@
MatrixStickerPackSource::AccountData,
"im.ponies.user_emotes",
stickerPackEvent,
+ "",
+ "",
}, lager::automatic_tag{});
auto stickerPack = toUniquePtr(new MatrixStickerPack(sourceCursor));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 21, 7:21 PM (16 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38701
Default Alt Text
D170.1732245708.diff (14 KB)
Attached To
Mode
D170: Display list of sticker packs in a room
Attached
Detach File
Event Timeline
Log In to Comment