summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Cache.cpp43
-rw-r--r--src/CacheStructs.h1
-rw-r--r--src/ImagePackListModel.cpp3
-rw-r--r--src/ImagePackListModel.h1
-rw-r--r--src/SingleImagePackModel.cpp1
-rw-r--r--src/SingleImagePackModel.h4
6 files changed, 43 insertions, 10 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index ede2e4e5..bf485325 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -8,6 +8,7 @@
 #include "Cache_p.h"
 
 #include <stdexcept>
+#include <unordered_set>
 #include <variant>
 
 #include <QCoreApplication>
@@ -3911,7 +3912,8 @@ Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers)
 
     auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack,
                                       const std::string &source_room,
-                                      const std::string &state_key) {
+                                      const std::string &state_key,
+                                      bool from_space) {
         bool pack_is_sticker = pack.pack ? pack.pack->is_sticker() : true;
         bool pack_is_emoji   = pack.pack ? pack.pack->is_emoji() : true;
         bool pack_matches =
@@ -3921,6 +3923,7 @@ Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers)
         info.source_room = source_room;
         info.state_key   = state_key;
         info.pack.pack   = pack.pack;
+        info.from_space  = from_space;
 
         for (const auto &img : pack.images) {
             if (stickers.has_value() &&
@@ -3942,7 +3945,7 @@ Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers)
         auto tmp =
           std::get_if<mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePack>>(&*accountpack);
         if (tmp)
-            addPack(tmp->content, "", "");
+            addPack(tmp->content, "", "", false);
     }
 
     // packs from rooms, that were enabled globally
@@ -3959,19 +3962,39 @@ Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers)
                     (void)d;
                     if (auto pack =
                           getStateEvent<mtx::events::msc2545::ImagePack>(txn, room_id2, state_id))
-                        addPack(pack->content, room_id2, state_id);
+                        addPack(pack->content, room_id2, state_id, false);
                 }
             }
         }
     }
 
-    // packs from current room
-    if (auto pack = getStateEvent<mtx::events::msc2545::ImagePack>(txn, room_id)) {
-        addPack(pack->content, room_id, "");
-    }
-    for (const auto &pack : getStateEventsWithType<mtx::events::msc2545::ImagePack>(txn, room_id)) {
-        addPack(pack.content, room_id, pack.state_key);
-    }
+    std::function<void(const std::string &room_id)> addRoomAndCanonicalParents;
+    std::unordered_set<std::string> visitedRooms;
+    addRoomAndCanonicalParents =
+      [this, &addRoomAndCanonicalParents, &addPack, &visitedRooms, &txn, &room_id](
+        const std::string &current_room) {
+          if (visitedRooms.count(current_room))
+              return;
+          else
+              visitedRooms.insert(current_room);
+
+          if (auto pack = getStateEvent<mtx::events::msc2545::ImagePack>(txn, current_room)) {
+              addPack(pack->content, current_room, "", current_room != room_id);
+          }
+          for (const auto &pack :
+               getStateEventsWithType<mtx::events::msc2545::ImagePack>(txn, current_room)) {
+              addPack(pack.content, current_room, pack.state_key, current_room != room_id);
+          }
+
+          for (const auto &parent :
+               getStateEventsWithType<mtx::events::state::space::Parent>(txn, current_room)) {
+              if (parent.content.canonical && parent.content.via && !parent.content.via->empty())
+                  addRoomAndCanonicalParents(parent.state_key);
+          }
+      };
+
+    // packs from current room and then iterate canonical space parents
+    addRoomAndCanonicalParents(room_id);
 
     return infos;
 }
diff --git a/src/CacheStructs.h b/src/CacheStructs.h
index 43055145..459ced5a 100644
--- a/src/CacheStructs.h
+++ b/src/CacheStructs.h
@@ -126,4 +126,5 @@ struct ImagePackInfo
     mtx::events::msc2545::ImagePack pack;
     std::string source_room;
     std::string state_key;
+    bool from_space = false;
 };
diff --git a/src/ImagePackListModel.cpp b/src/ImagePackListModel.cpp
index 6ce6306e..fac8f10f 100644
--- a/src/ImagePackListModel.cpp
+++ b/src/ImagePackListModel.cpp
@@ -36,6 +36,7 @@ ImagePackListModel::roleNames() const
       {Roles::AvatarUrl, "avatarUrl"},
       {Roles::FromAccountData, "fromAccountData"},
       {Roles::FromCurrentRoom, "fromCurrentRoom"},
+      {Roles::FromSpace, "fromSpace"},
       {Roles::StateKey, "statekey"},
       {Roles::RoomId, "roomid"},
     };
@@ -55,6 +56,8 @@ ImagePackListModel::data(const QModelIndex &index, int role) const
             return pack->roomid().isEmpty();
         case Roles::FromCurrentRoom:
             return pack->roomid().toStdString() == this->room_id;
+        case Roles::FromSpace:
+            return pack->fromSpace();
         case Roles::StateKey:
             return pack->statekey();
         case Roles::RoomId:
diff --git a/src/ImagePackListModel.h b/src/ImagePackListModel.h
index 43fbcdfb..2e288094 100644
--- a/src/ImagePackListModel.h
+++ b/src/ImagePackListModel.h
@@ -21,6 +21,7 @@ public:
         AvatarUrl,
         FromAccountData,
         FromCurrentRoom,
+        FromSpace,
         StateKey,
         RoomId,
     };
diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp
index c7f01fad..02c9a3ce 100644
--- a/src/SingleImagePackModel.cpp
+++ b/src/SingleImagePackModel.cpp
@@ -26,6 +26,7 @@ SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
   , statekey_(std::move(pack_.state_key))
   , old_statekey_(statekey_)
   , pack(std::move(pack_.pack))
+  , fromSpace_(pack_.from_space)
 {
     [[maybe_unused]] static auto imageInfoType = qRegisterMetaType<mtx::common::ImageInfo>();
 
diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h
index b732dcac..de2e4dea 100644
--- a/src/SingleImagePackModel.h
+++ b/src/SingleImagePackModel.h
@@ -18,6 +18,7 @@ class SingleImagePackModel : public QAbstractListModel
     Q_OBJECT
 
     Q_PROPERTY(QString roomid READ roomid CONSTANT)
+    Q_PROPERTY(bool fromSpace READ fromSpace CONSTANT)
     Q_PROPERTY(QString statekey READ statekey WRITE setStatekey NOTIFY statekeyChanged)
     Q_PROPERTY(QString attribution READ attribution WRITE setAttribution NOTIFY attributionChanged)
     Q_PROPERTY(QString packname READ packname WRITE setPackname NOTIFY packnameChanged)
@@ -47,6 +48,7 @@ public:
     bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
 
     QString roomid() const { return QString::fromStdString(roomid_); }
+    bool fromSpace() const { return fromSpace_; }
     QString statekey() const { return QString::fromStdString(statekey_); }
     QString packname() const { return QString::fromStdString(pack.pack->display_name); }
     QString attribution() const { return QString::fromStdString(pack.pack->attribution); }
@@ -91,4 +93,6 @@ private:
 
     mtx::events::msc2545::ImagePack pack;
     std::vector<std::string> shortcodes;
+
+    bool fromSpace_ = false;
 };