Page MenuHomePhorge

D170.1726794216.diff
No OneTemporary

D170.1726794216.diff

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

Mime Type
text/plain
Expires
Thu, Sep 19, 6:03 PM (8 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16011
Default Alt Text
D170.1726794216.diff (14 KB)

Event Timeline