diff --git a/resources/qml/dialogs/ImagePackEditorDialog.qml b/resources/qml/dialogs/ImagePackEditorDialog.qml index 1db5d45f..d5be9580 100644 --- a/resources/qml/dialogs/ImagePackEditorDialog.qml +++ b/resources/qml/dialogs/ImagePackEditorDialog.qml @@ -148,6 +148,27 @@ ApplicationWindow { width: 130 crop: false Layout.alignment: Qt.AlignHCenter + + ImageButton { + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Change the overview image for this pack") + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: Nheko.paddingMedium + anchors.topMargin: Nheko.paddingMedium + image: ":/icons/icons/ui/edit.svg" + onClicked: addAvatarDialog.open() + + FileDialog { + id: addAvatarDialog + + folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation) + fileMode: FileDialog.OpenFile + nameFilters: [qsTr("Overview Image (*.png *.webp *.jpg *.jpeg)")] + onAccepted: imagePack.setAvatar(file) + } + } } MatrixText { diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp index 978a0480..2c1b833a 100644 --- a/src/SingleImagePackModel.cpp +++ b/src/SingleImagePackModel.cpp @@ -33,6 +33,7 @@ SingleImagePackModel::SingleImagePackModel(ImagePackInfo pack_, QObject *parent) shortcodes.push_back(e.first); connect(this, &SingleImagePackModel::addImage, this, &SingleImagePackModel::addImageCb); + connect(this, &SingleImagePackModel::avatarUploaded, this, &SingleImagePackModel::setAvatarUrl); } int @@ -215,6 +216,17 @@ SingleImagePackModel::setAvatarUrl(QString val) } } +QString +SingleImagePackModel::avatarUrl() const +{ + if (!pack.pack->avatar_url.empty()) + return QString::fromStdString(pack.pack->avatar_url); + else if (!pack.images.empty()) + return QString::fromStdString(pack.images.begin()->second.url); + else + return ""; +} + void SingleImagePackModel::setStatekey(QString val) { @@ -331,6 +343,35 @@ SingleImagePackModel::addStickers(QList files) } } +void +SingleImagePackModel::setAvatar(QUrl f) +{ + auto file = QFile(f.toLocalFile()); + if (!file.open(QFile::ReadOnly)) { + ChatPage::instance()->showNotification(tr("Failed to open image: %1").arg(f.toLocalFile())); + return; + } + + auto bytes = file.readAll(); + auto img = utils::readImage(bytes); + + auto filename = f.fileName().toStdString(); + http::client()->upload( + bytes.toStdString(), + QMimeDatabase().mimeTypeForFile(f.toLocalFile()).name().toStdString(), + filename, + [this, filename](const mtx::responses::ContentURI &uri, mtx::http::RequestErr e) { + if (e) { + ChatPage::instance()->showNotification( + tr("Failed to upload image: %1") + .arg(QString::fromStdString(e->matrix_error.error))); + return; + } + + emit avatarUploaded(QString::fromStdString(uri.content_uri)); + }); +} + void SingleImagePackModel::remove(int idx) { @@ -356,4 +397,7 @@ SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::com shortcodes.push_back(filename); endInsertRows(); + + if (this->pack.pack->avatar_url.empty()) + this->setAvatarUrl(QString::fromStdString(uri)); } diff --git a/src/SingleImagePackModel.h b/src/SingleImagePackModel.h index cd8b0547..f658a8e5 100644 --- a/src/SingleImagePackModel.h +++ b/src/SingleImagePackModel.h @@ -49,7 +49,7 @@ public: 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); } - QString avatarUrl() const { return QString::fromStdString(pack.pack->avatar_url); } + QString avatarUrl() const; bool isStickerPack() const { return pack.pack->is_sticker(); } bool isEmotePack() const { return pack.pack->is_emoji(); } @@ -67,6 +67,7 @@ public: Q_INVOKABLE void save(); Q_INVOKABLE void addStickers(QList files); Q_INVOKABLE void remove(int index); + Q_INVOKABLE void setAvatar(QUrl file); signals: void globallyEnabledChanged(); @@ -78,6 +79,7 @@ signals: void isStickerPackChanged(); void addImage(std::string uri, std::string filename, mtx::common::ImageInfo info); + void avatarUploaded(QString uri); private slots: void addImageCb(std::string uri, std::string filename, mtx::common::ImageInfo info);