Page MenuHomePhorge

D166.1726848981.diff
No OneTemporary

D166.1726848981.diff

diff --git a/src/contents/ui/StickerPicker.qml b/src/contents/ui/StickerPicker.qml
--- a/src/contents/ui/StickerPicker.qml
+++ b/src/contents/ui/StickerPicker.qml
@@ -17,35 +17,29 @@
id: stickerPicker
property var stickerPackList
spacing: 0
+ property var currentIndex: 0
signal sendMessageRequested(var eventJson)
- ScrollView {
- id: packListScrollView
+ TabBar {
+ id: packListView
Layout.fillWidth: true
Layout.minimumHeight: Kirigami.Units.gridUnit * 2
- Layout.preferredHeight: packListView.height
-
- ListView {
- id: packListView
- orientation: ListView.Horizontal
- height: contentHeight
- anchors.fill: parent
- currentIndex: 0
+ Repeater {
model: stickerPackList
- delegate: ToolButton {
+ delegate: TabButton {
objectName: `stickerPack${index}`
property var pack: stickerPackList.at(index)
icon.name: 'smiley'
- text: l10n.get('sticker-picker-user-stickers')
- checked: ListView.currentIndex === index
- onClicked: ListView.currentIndex = index
+ text: pack.packName ? pack.packName : l10n.get('sticker-picker-user-stickers')
+ checked: stickerPicker.currentIndex === index
+ onClicked: stickerPicker.currentIndex = index
}
}
}
- property var currentPack: packListView.currentItem && packListView.currentItem.pack
+ property var currentPack: stickerPackList.at(currentIndex)
property var stickerSize: Kirigami.Units.iconSizes.enormous
property var stickerMargin: Kirigami.Units.smallSpacing
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
@@ -15,15 +15,41 @@
using namespace Kazv;
static const std::string accountDataEventType = "im.ponies.user_emotes";
+static const std::string roomStateEventType = "im.ponies.room_emotes";
+static const std::string imagePackRoomsEventType = "im.ponies.emote_rooms";
+
+using ImagePackRoomMap = immer::map<std::string/* room id */, immer::map<std::string/* */, json>>;
lager::reader<immer::flex_vector<MatrixStickerPackSource>> getEventsFromClient(Client client)
{
lager::reader<Event> userEmotes = client.accountData()[accountDataEventType][lager::lenses::or_default];
- return userEmotes.map([](Event e) {
- return immer::flex_vector<MatrixStickerPackSource>{
- {MatrixStickerPackSource::AccountData, accountDataEventType, e},
- };
- });
+ return lager::with(
+ userEmotes,
+ client.accountData()[imagePackRoomsEventType][lager::lenses::or_default]
+ // The following jsonAtOr performs the validation for us:
+ // if the content does not conform to the string-to-string-to-anything map, return an empty one
+ .xform(eventContent | jsonAtOr("rooms", ImagePackRoomMap{})),
+ client.rooms()).map([](
+ const Event &userEmotes,
+ const ImagePackRoomMap &emoteRooms,
+ 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}
+ }.transient();
+
+ for (const auto &[roomId, stateKeyMap] : emoteRooms) {
+ for (const auto &[stateKey, _] : stateKeyMap) {
+ res.push_back(MatrixStickerPackSource{
+ MatrixStickerPackSource::RoomState,
+ roomStateEventType,
+ rooms[roomId].stateEvents[KeyOfState{roomStateEventType, stateKey}]
+ });
+ }
+ }
+
+ return res.persistent();
+ }).make();
}
MatrixStickerPackList::MatrixStickerPackList(Client client, QObject *parent)
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
@@ -39,6 +39,8 @@
Q_INVOKABLE MatrixSticker *at(int index) const;
+ LAGER_QT_READER(QString, packName);
+
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
@@ -7,7 +7,7 @@
#include <kazv-defs.hpp>
#include <cursorutil.hpp>
-
+#include "helper.hpp"
#include "matrix-sticker.hpp"
#include "matrix-event.hpp"
#include "matrix-sticker-pack.hpp"
@@ -38,6 +38,7 @@
return json::array();
}
})))
+ , LAGER_QT(packName)(m_event.xform(eventContent | jsonAtOr("/pack/display_name"_json_pointer, std::string()) | 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
@@ -62,6 +62,49 @@
"type": "im.ponies.user_emotes"
})"_json};
+static const auto imagePackRoomsEvent = Event(R"({
+ "content": {
+ "rooms": {
+ "!someroom:example.org": {
+ "": {},
+ "de.sorunome.mx-puppet-bridge.discord": {}
+ },
+ "!someotherroom:example.org": {
+ "": {}
+ }
+ }
+ },
+ "type": "im.ponies.emote_rooms"
+})"_json);
+
+static Event getRoomStickersEvent(std::string stateKey, std::string name)
+{
+ auto j = R"({
+ "content": {
+ "images": {
+ "myemote": {
+ "url": "mxc://example.org/blah"
+ },
+ "mysticker": {
+ "body": "my sticker",
+ "url": "mxc://example.org/sticker",
+ "usage": ["sticker"],
+ "info": {
+ "mimetype": "image/png"
+ }
+ }
+ },
+ "pack": {
+ "usage": ["emoticon"]
+ }
+ },
+ "type": "im.ponies.room_emotes"
+})"_json;
+ j["state_key"] = stateKey;
+ j["content"]["pack"]["display_name"] = name;
+ return Event(j);
+}
+
void MatrixStickerPackTest::testStickerPack()
{
auto sourceCursor = lager::make_state(MatrixStickerPackSource{
@@ -108,15 +151,43 @@
void MatrixStickerPackTest::testStickerPackList()
{
- auto model = makeClient(withAccountData({stickerPackEvent}));
+ auto model = makeClient(
+ withAccountData({stickerPackEvent, imagePackRoomsEvent})
+ | withRoom(makeRoom(
+ withRoomId("!someroom:example.org")
+ | withRoomState({
+ getRoomStickersEvent("", "Pack 1"),
+ getRoomStickersEvent("de.sorunome.mx-puppet-bridge.discord", "Pack 2"),
+ })
+ ))
+ | withRoom(makeRoom(
+ withRoomId("!someotherroom:example.org")
+ | withRoomState({getRoomStickersEvent("", "Pack 3")})
+ ))
+ );
std::unique_ptr<MatrixSdk> sdk{makeTestSdk(SdkModel{model})};
auto stickerPackList = toUniquePtr(sdk->stickerPackList());
- QCOMPARE(stickerPackList->rowCount(QModelIndex()), 1);
- QCOMPARE(stickerPackList->count(), 1);
+ QCOMPARE(stickerPackList->rowCount(QModelIndex()), 4);
+ QCOMPARE(stickerPackList->count(), 4);
- auto stickerPack = toUniquePtr(stickerPackList->at(0));
- QCOMPARE(stickerPack->count(), 2);
+ auto packs = std::array<std::unique_ptr<MatrixStickerPack>, 4>{
+ toUniquePtr(stickerPackList->at(0)),
+ toUniquePtr(stickerPackList->at(1)),
+ toUniquePtr(stickerPackList->at(2)),
+ 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(u"Awesome Pack"_s));
+ QVERIFY(hasPack(u"Pack 1"_s));
+ QVERIFY(hasPack(u"Pack 2"_s));
+ QVERIFY(hasPack(u"Pack 3"_s));
}
void MatrixStickerPackTest::testAddToPack()
diff --git a/src/tests/quick-tests/tst_StickerPicker.qml b/src/tests/quick-tests/tst_StickerPicker.qml
--- a/src/tests/quick-tests/tst_StickerPicker.qml
+++ b/src/tests/quick-tests/tst_StickerPicker.qml
@@ -54,6 +54,26 @@
function at(index) {
return stickerPack0.get(index);
}
+ },
+ ListModel {
+ id: stickerPack1
+ ListElement {
+ shortCode: 'some2'
+ body: 'some2'
+ mxcUri: 'mxc://example.org/some2'
+ makeEventJson: () => makeSticker(stickerPack1.get(0))
+ }
+
+ ListElement {
+ shortCode: 'some3'
+ body: 'some3'
+ mxcUri: 'mxc://example.org/some3'
+ makeEventJson: () => makeSticker(stickerPack1.get(1))
+ }
+
+ function at(index) {
+ return stickerPack1.get(index);
+ }
}
]
@@ -68,6 +88,8 @@
id: stickerPackListModel
ListElement {
}
+ ListElement {
+ }
function at(index) {
return stickerPacks[index];
}
@@ -86,12 +108,19 @@
function test_stickerPicker() {
verify(findChild(stickerPicker, 'stickerPack0'));
+ verify(findChild(stickerPicker, 'stickerPack1'));
verify(findChild(stickerPicker, 'sticker0'));
verify(findChild(stickerPicker, 'sticker1'));
const stickerButton = findChild(stickerPicker, 'sticker1');
mouseClick(stickerButton);
- tryVerify(() => sendMessageRequestedSpy.count, 1000);
+ tryVerify(() => sendMessageRequestedSpy.count === 1, 1000);
verify(Helpers.deepEqual(sendMessageRequestedSpy.signalArguments[0][0], makeSticker(stickerPack0.get(1))));
+
+ mouseClick(findChild(stickerPicker, 'stickerPack1'));
+ tryVerify(() => findChild(stickerPicker, 'sticker0').sticker.mxcUri === 'mxc://example.org/some2');
+ mouseClick(findChild(stickerPicker, 'sticker0'));
+ tryVerify(() => sendMessageRequestedSpy.count === 2, 1000);
+ verify(Helpers.deepEqual(sendMessageRequestedSpy.signalArguments[1][0], makeSticker(stickerPack1.get(0))));
}
}
}

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 20, 9:16 AM (18 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15950
Default Alt Text
D166.1726848981.diff (9 KB)

Event Timeline