diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-05-19 23:06:14 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-05-20 00:57:51 +0200 |
commit | 7fab9a1d73e628ca2371d2215b0198806aa85e94 (patch) | |
tree | 4c4e529617cae41a5d3c4ab0574f5cecf0c12f80 /src | |
parent | Fix adding duplicate stickers and strip file extension (diff) | |
download | nheko-7fab9a1d73e628ca2371d2215b0198806aa85e94.tar.xz |
Prevent new packs from overwriting the default pack by accident
Diffstat (limited to 'src')
-rw-r--r-- | src/ImagePackListModel.cpp | 4 | ||||
-rw-r--r-- | src/SingleImagePackModel.cpp | 42 | ||||
-rw-r--r-- | src/SingleImagePackModel.h | 2 |
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(); |