summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2023-05-19 23:06:14 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2023-05-20 00:57:51 +0200
commit7fab9a1d73e628ca2371d2215b0198806aa85e94 (patch)
tree4c4e529617cae41a5d3c4ab0574f5cecf0c12f80
parent4bf725379af5b98e4403769abe608ea17dcd5bdb (diff)
Prevent new packs from overwriting the default pack by accident
-rw-r--r--src/ImagePackListModel.cpp4
-rw-r--r--src/SingleImagePackModel.cpp42
-rw-r--r--src/SingleImagePackModel.h2
3 files changed, 47 insertions, 1 deletions
diff --git a/src/ImagePackListModel.cpp b/src/ImagePackListModel.cpp
index 368acd8c..4cf807a9 100644
--- a/src/ImagePackListModel.cpp
+++ b/src/ImagePackListModel.cpp
@@ -82,8 +82,10 @@ SingleImagePackModel *
ImagePackListModel::newPack(bool inRoom)
{
ImagePackInfo info{};
- if (inRoom)
+ if (inRoom) {
info.source_room = room_id;
+ info.state_key = SingleImagePackModel::unconflictingStatekey(room_id, "");
+ }
return new SingleImagePackModel(info);
}
diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp
index b26396ba..99338f2e 100644
--- a/src/SingleImagePackModel.cpp
+++ b/src/SingleImagePackModel.cpp
@@ -8,6 +8,8 @@
#include <QFileInfo>
#include <QMimeDatabase>
+#include <unordered_set>
+
#include <mtx/responses/media.hpp>
#include "Cache_p.h"
@@ -237,6 +239,12 @@ SingleImagePackModel::setStatekey(QString val)
auto val_ = val.toStdString();
if (val_ != statekey_) {
statekey_ = val_;
+
+ // prevent deleting current pack
+ if (!roomid_.empty() && statekey_ != old_statekey_) {
+ statekey_ = unconflictingStatekey(roomid_, statekey_);
+ }
+
emit statekeyChanged();
}
}
@@ -290,6 +298,7 @@ SingleImagePackModel::save()
tr("Failed to delete old image pack: %1")
.arg(QString::fromStdString(e->matrix_error.error)));
});
+ old_statekey_ = statekey_;
}
http::client()->send_state_event(
@@ -398,6 +407,7 @@ std::string
SingleImagePackModel::unconflictingShortcode(const std::string &shortcode)
{
if (pack.images.count(shortcode)) {
+ // more images won't fit in an event anyway
for (int i = 0; i < 64'000; i++) {
auto tempCode = shortcode + std::to_string(i);
if (!pack.images.count(tempCode)) {
@@ -408,6 +418,38 @@ SingleImagePackModel::unconflictingShortcode(const std::string &shortcode)
return shortcode;
}
+std::string
+SingleImagePackModel::unconflictingStatekey(const std::string &roomid, const std::string &key)
+{
+ if (roomid.empty())
+ return key;
+
+ std::unordered_set<std::string> statekeys;
+ auto currentPacks =
+ cache::client()->getStateEventsWithType<mtx::events::msc2545::ImagePack>(roomid);
+ for (const auto &pack : currentPacks) {
+ if (!pack.content.images.empty())
+ statekeys.insert(pack.state_key);
+ }
+ auto defaultPack = cache::client()->getStateEvent<mtx::events::msc2545::ImagePack>(roomid);
+ if (defaultPack && defaultPack->content.images.size()) {
+ statekeys.insert(defaultPack->state_key);
+ }
+
+ if (statekeys.count(key)) {
+ // arbitrary count. More than 64k image packs in a room are unlikely and if you have that,
+ // you probably know what you are doing :)
+ for (int i = 0; i < 64'000; i++) {
+ auto tempCode = key + std::to_string(i);
+ if (!statekeys.count(tempCode)) {
+ return tempCode;
+ }
+ }
+ }
+
+ return key;
+}
+
void
SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info)
{
diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h
index 65a27bcf..595f5a78 100644
--- a/src/SingleImagePackModel.h
+++ b/src/SingleImagePackModel.h
@@ -71,6 +71,8 @@ public:
Q_INVOKABLE void remove(int index);
Q_INVOKABLE void setAvatar(QUrl file);
+ static std::string unconflictingStatekey(const std::string &roomid, const std::string &key);
+
signals:
void globallyEnabledChanged();
void statekeyChanged();