2021-07-21 14:37:57 +03:00
|
|
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
#include "SingleImagePackModel.h"
|
|
|
|
|
|
|
|
#include "Cache_p.h"
|
2021-08-06 02:45:47 +03:00
|
|
|
#include "ChatPage.h"
|
2021-07-21 14:37:57 +03:00
|
|
|
#include "MatrixClient.h"
|
2021-08-06 02:45:47 +03:00
|
|
|
#include "timeline/Permissions.h"
|
|
|
|
#include "timeline/TimelineModel.h"
|
|
|
|
|
|
|
|
#include "Logging.h"
|
2021-07-21 14:37:57 +03:00
|
|
|
|
|
|
|
SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent)
|
|
|
|
: QAbstractListModel(parent)
|
|
|
|
, roomid_(std::move(pack_.source_room))
|
|
|
|
, statekey_(std::move(pack_.state_key))
|
2021-08-06 02:45:47 +03:00
|
|
|
, old_statekey_(statekey_)
|
2021-07-21 14:37:57 +03:00
|
|
|
, pack(std::move(pack_.pack))
|
|
|
|
{
|
|
|
|
if (!pack.pack)
|
|
|
|
pack.pack = mtx::events::msc2545::ImagePack::PackDescription{};
|
|
|
|
|
|
|
|
for (const auto &e : pack.images)
|
|
|
|
shortcodes.push_back(e.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SingleImagePackModel::rowCount(const QModelIndex &) const
|
|
|
|
{
|
|
|
|
return (int)shortcodes.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
QHash<int, QByteArray>
|
|
|
|
SingleImagePackModel::roleNames() const
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
{Roles::Url, "url"},
|
|
|
|
{Roles::ShortCode, "shortCode"},
|
|
|
|
{Roles::Body, "body"},
|
|
|
|
{Roles::IsEmote, "isEmote"},
|
|
|
|
{Roles::IsSticker, "isSticker"},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant
|
|
|
|
SingleImagePackModel::data(const QModelIndex &index, int role) const
|
|
|
|
{
|
|
|
|
if (hasIndex(index.row(), index.column(), index.parent())) {
|
|
|
|
const auto &img = pack.images.at(shortcodes.at(index.row()));
|
|
|
|
switch (role) {
|
|
|
|
case Url:
|
|
|
|
return QString::fromStdString(img.url);
|
|
|
|
case ShortCode:
|
|
|
|
return QString::fromStdString(shortcodes.at(index.row()));
|
|
|
|
case Body:
|
|
|
|
return QString::fromStdString(img.body);
|
|
|
|
case IsEmote:
|
|
|
|
return img.overrides_usage() ? img.is_emoji() : pack.pack->is_emoji();
|
|
|
|
case IsSticker:
|
|
|
|
return img.overrides_usage() ? img.is_sticker() : pack.pack->is_sticker();
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2021-08-06 02:45:47 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-07-21 14:37:57 +03:00
|
|
|
bool
|
|
|
|
SingleImagePackModel::isGloballyEnabled() const
|
|
|
|
{
|
|
|
|
if (auto roomPacks =
|
|
|
|
cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) {
|
|
|
|
if (auto tmp = std::get_if<
|
|
|
|
mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePackRooms>>(
|
|
|
|
&*roomPacks)) {
|
|
|
|
if (tmp->content.rooms.count(roomid_) &&
|
|
|
|
tmp->content.rooms.at(roomid_).count(statekey_))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
void
|
|
|
|
SingleImagePackModel::setGloballyEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
mtx::events::msc2545::ImagePackRooms content{};
|
|
|
|
if (auto roomPacks =
|
|
|
|
cache::client()->getAccountData(mtx::events::EventType::ImagePackRooms)) {
|
|
|
|
if (auto tmp = std::get_if<
|
|
|
|
mtx::events::EphemeralEvent<mtx::events::msc2545::ImagePackRooms>>(
|
|
|
|
&*roomPacks)) {
|
|
|
|
content = tmp->content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enabled)
|
|
|
|
content.rooms[roomid_][statekey_] = {};
|
|
|
|
else
|
|
|
|
content.rooms[roomid_].erase(statekey_);
|
|
|
|
|
2021-07-23 19:21:55 +03:00
|
|
|
http::client()->put_account_data(content, [](mtx::http::RequestErr) {
|
2021-07-21 14:37:57 +03:00
|
|
|
// emit this->globallyEnabledChanged();
|
|
|
|
});
|
|
|
|
}
|
2021-08-06 02:45:47 +03:00
|
|
|
|
|
|
|
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, [this](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(),
|
|
|
|
[this](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)));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|