summary refs log tree commit diff
path: root/src/SingleImagePackModel.cpp
diff options
context:
space:
mode:
authorkamathmanu <manuriddle@gmail.com>2021-08-07 21:20:43 +0000
committerGitHub <noreply@github.com>2021-08-07 21:20:43 +0000
commit2dfccda73c44d97e9e3e52db3e03315e8ef656a5 (patch)
tree52c9855610cbdf6f6284cfacbaba07f676a0f621 /src/SingleImagePackModel.cpp
parentFix Duplicate fetched chunk (diff)
parentShow encryption errors in qml and add request keys button (diff)
downloadnheko-2dfccda73c44d97e9e3e52db3e03315e8ef656a5.tar.xz
Merge branch 'master' into nhekoRoomDirectory
Diffstat (limited to 'src/SingleImagePackModel.cpp')
-rw-r--r--src/SingleImagePackModel.cpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp
index 6c508da0..7bf55617 100644
--- a/src/SingleImagePackModel.cpp
+++ b/src/SingleImagePackModel.cpp
@@ -4,20 +4,35 @@
 
 #include "SingleImagePackModel.h"
 
+#include <QFile>
+#include <QMimeDatabase>
+
 #include "Cache_p.h"
+#include "ChatPage.h"
+#include "Logging.h"
 #include "MatrixClient.h"
+#include "Utils.h"
+#include "timeline/Permissions.h"
+#include "timeline/TimelineModel.h"
+
+Q_DECLARE_METATYPE(mtx::common::ImageInfo)
 
 SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
   : QAbstractListModel(parent)
   , roomid_(std::move(pack_.source_room))
   , statekey_(std::move(pack_.state_key))
+  , old_statekey_(statekey_)
   , pack(std::move(pack_.pack))
 {
+        [[maybe_unused]] static auto imageInfoType = qRegisterMetaType<mtx::common::ImageInfo>();
+
         if (!pack.pack)
                 pack.pack = mtx::events::msc2545::ImagePack::PackDescription{};
 
         for (const auto &e : pack.images)
                 shortcodes.push_back(e.first);
+
+        connect(this, &SingleImagePackModel::addImage, this, &SingleImagePackModel::addImageCb);
 }
 
 int
@@ -62,6 +77,73 @@ SingleImagePackModel::data(const QModelIndex &index, int role) const
 }
 
 bool
+SingleImagePackModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+        using mtx::events::msc2545::PackUsage;
+
+        if (hasIndex(index.row(), index.column(), index.parent())) {
+                auto &img = pack.images.at(shortcodes.at(index.row()));
+                switch (role) {
+                case ShortCode: {
+                        auto newCode = value.toString().toStdString();
+
+                        // otherwise we delete this by accident
+                        if (pack.images.count(newCode))
+                                return false;
+
+                        auto tmp     = img;
+                        auto oldCode = shortcodes.at(index.row());
+                        pack.images.erase(oldCode);
+                        shortcodes[index.row()] = newCode;
+                        pack.images.insert({newCode, tmp});
+
+                        emit dataChanged(
+                          this->index(index.row()), this->index(index.row()), {Roles::ShortCode});
+                        return true;
+                }
+                case Body:
+                        img.body = value.toString().toStdString();
+                        emit dataChanged(
+                          this->index(index.row()), this->index(index.row()), {Roles::Body});
+                        return true;
+                case IsEmote: {
+                        bool isEmote = value.toBool();
+                        bool isSticker =
+                          img.overrides_usage() ? img.is_sticker() : pack.pack->is_sticker();
+
+                        img.usage.set(PackUsage::Emoji, isEmote);
+                        img.usage.set(PackUsage::Sticker, isSticker);
+
+                        if (img.usage == pack.pack->usage)
+                                img.usage.reset();
+
+                        emit dataChanged(
+                          this->index(index.row()), this->index(index.row()), {Roles::IsEmote});
+
+                        return true;
+                }
+                case IsSticker: {
+                        bool isEmote =
+                          img.overrides_usage() ? img.is_emoji() : pack.pack->is_emoji();
+                        bool isSticker = value.toBool();
+
+                        img.usage.set(PackUsage::Emoji, isEmote);
+                        img.usage.set(PackUsage::Sticker, isSticker);
+
+                        if (img.usage == pack.pack->usage)
+                                img.usage.reset();
+
+                        emit dataChanged(
+                          this->index(index.row()), this->index(index.row()), {Roles::IsSticker});
+
+                        return true;
+                }
+                }
+        }
+        return false;
+}
+
+bool
 SingleImagePackModel::isGloballyEnabled() const
 {
         if (auto roomPacks =
@@ -98,3 +180,171 @@ SingleImagePackModel::setGloballyEnabled(bool enabled)
                 // emit this->globallyEnabledChanged();
         });
 }
+
+bool
+SingleImagePackModel::canEdit() const
+{
+        if (roomid_.empty())
+                return true;
+        else
+                return Permissions(QString::fromStdString(roomid_))
+                  .canChange(qml_mtx_events::ImagePackInRoom);
+}
+
+void
+SingleImagePackModel::setPackname(QString val)
+{
+        auto val_ = val.toStdString();
+        if (val_ != this->pack.pack->display_name) {
+                this->pack.pack->display_name = val_;
+                emit packnameChanged();
+        }
+}
+
+void
+SingleImagePackModel::setAttribution(QString val)
+{
+        auto val_ = val.toStdString();
+        if (val_ != this->pack.pack->attribution) {
+                this->pack.pack->attribution = val_;
+                emit attributionChanged();
+        }
+}
+
+void
+SingleImagePackModel::setAvatarUrl(QString val)
+{
+        auto val_ = val.toStdString();
+        if (val_ != this->pack.pack->avatar_url) {
+                this->pack.pack->avatar_url = val_;
+                emit avatarUrlChanged();
+        }
+}
+
+void
+SingleImagePackModel::setStatekey(QString val)
+{
+        auto val_ = val.toStdString();
+        if (val_ != statekey_) {
+                statekey_ = val_;
+                emit statekeyChanged();
+        }
+}
+
+void
+SingleImagePackModel::setIsStickerPack(bool val)
+{
+        using mtx::events::msc2545::PackUsage;
+        if (val != pack.pack->is_sticker()) {
+                pack.pack->usage.set(PackUsage::Sticker, val);
+                emit isStickerPackChanged();
+        }
+}
+
+void
+SingleImagePackModel::setIsEmotePack(bool val)
+{
+        using mtx::events::msc2545::PackUsage;
+        if (val != pack.pack->is_emoji()) {
+                pack.pack->usage.set(PackUsage::Emoji, val);
+                emit isEmotePackChanged();
+        }
+}
+
+void
+SingleImagePackModel::save()
+{
+        if (roomid_.empty()) {
+                http::client()->put_account_data(pack, [](mtx::http::RequestErr e) {
+                        if (e)
+                                ChatPage::instance()->showNotification(
+                                  tr("Failed to update image pack: {}")
+                                    .arg(QString::fromStdString(e->matrix_error.error)));
+                });
+        } else {
+                if (old_statekey_ != statekey_) {
+                        http::client()->send_state_event(
+                          roomid_,
+                          to_string(mtx::events::EventType::ImagePackInRoom),
+                          old_statekey_,
+                          nlohmann::json::object(),
+                          [](const mtx::responses::EventId &, mtx::http::RequestErr e) {
+                                  if (e)
+                                          ChatPage::instance()->showNotification(
+                                            tr("Failed to delete old image pack: {}")
+                                              .arg(QString::fromStdString(e->matrix_error.error)));
+                          });
+                }
+
+                http::client()->send_state_event(
+                  roomid_,
+                  statekey_,
+                  pack,
+                  [this](const mtx::responses::EventId &, mtx::http::RequestErr e) {
+                          if (e)
+                                  ChatPage::instance()->showNotification(
+                                    tr("Failed to update image pack: {}")
+                                      .arg(QString::fromStdString(e->matrix_error.error)));
+
+                          nhlog::net()->info("Uploaded image pack: {}", statekey_);
+                  });
+        }
+}
+
+void
+SingleImagePackModel::addStickers(QList<QUrl> files)
+{
+        for (const auto &f : files) {
+                auto file = QFile(f.toLocalFile());
+                if (!file.open(QFile::ReadOnly)) {
+                        ChatPage::instance()->showNotification(
+                          tr("Failed to open image: {}").arg(f.toLocalFile()));
+                        return;
+                }
+
+                auto bytes = file.readAll();
+                auto img   = utils::readImage(bytes);
+
+                mtx::common::ImageInfo info{};
+
+                auto sz = img.size() / 2;
+                if (sz.width() > 512 || sz.height() > 512) {
+                        sz.scale(512, 512, Qt::AspectRatioMode::KeepAspectRatio);
+                }
+
+                info.h    = sz.height();
+                info.w    = sz.width();
+                info.size = bytes.size();
+
+                auto filename = f.fileName().toStdString();
+                http::client()->upload(
+                  bytes.toStdString(),
+                  QMimeDatabase().mimeTypeForFile(f.toLocalFile()).name().toStdString(),
+                  filename,
+                  [this, filename, info](const mtx::responses::ContentURI &uri,
+                                         mtx::http::RequestErr e) {
+                          if (e) {
+                                  ChatPage::instance()->showNotification(
+                                    tr("Failed to upload image: {}")
+                                      .arg(QString::fromStdString(e->matrix_error.error)));
+                                  return;
+                          }
+
+                          emit addImage(uri.content_uri, filename, info);
+                  });
+        }
+}
+void
+SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info)
+{
+        mtx::events::msc2545::PackImage img{};
+        img.url  = uri;
+        img.info = info;
+        beginInsertRows(
+          QModelIndex(), static_cast<int>(shortcodes.size()), static_cast<int>(shortcodes.size()));
+
+        pack.images[filename] = img;
+        shortcodes.push_back(filename);
+
+        endInsertRows();
+}