diff options
Diffstat (limited to 'src/ui/RoomSettings.cpp')
-rw-r--r-- | src/ui/RoomSettings.cpp | 167 |
1 files changed, 156 insertions, 11 deletions
diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp index 49e48e40..3ff1d5d5 100644 --- a/src/ui/RoomSettings.cpp +++ b/src/ui/RoomSettings.cpp @@ -1,5 +1,9 @@ #include "RoomSettings.h" +#include <QFileDialog> +#include <QImageReader> +#include <QMimeDatabase> +#include <QStandardPaths> #include <mtx/responses/common.hpp> #include <mtx/responses/media.hpp> @@ -84,6 +88,18 @@ RoomSettings::roomVersion() const return QString::fromStdString(info_.version); } +bool +RoomSettings::isLoading() const +{ + return isLoading_; +} + +QString +RoomSettings::roomAvatarUrl() +{ + return QString::fromStdString(info_.avatar_url); +} + int RoomSettings::memberCount() const { @@ -96,7 +112,6 @@ RoomSettings::retrieveRoomInfo() try { usesEncryption_ = cache::isRoomEncrypted(roomid_.toStdString()); info_ = cache::singleRoomInfo(roomid_.toStdString()); - // setAvatar(); } catch (const lmdb::error &) { nhlog::db()->warn("failed to retrieve room info from cache: {}", roomid_.toStdString()); @@ -143,9 +158,9 @@ RoomSettings::enableEncryption() room_id, err->matrix_error.error, status_code); - //emit enableEncryptionError( - // tr("Failed to enable encryption: %1") - // .arg(QString::fromStdString(err->matrix_error.error))); + emit displayError( + tr("Failed to enable encryption: %1") + .arg(QString::fromStdString(err->matrix_error.error))); usesEncryption_ = false; emit encryptionChanged(); return; @@ -173,6 +188,33 @@ RoomSettings::canChangeJoinRules() const } bool +RoomSettings::canChangeNameAndTopic() const +{ + try { + return cache::hasEnoughPowerLevel({EventType::RoomName, EventType::RoomTopic}, + roomid_.toStdString(), + utils::localUser().toStdString()); + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } + + return false; +} + +bool +RoomSettings::canChangeAvatar() const +{ + try { + return cache::hasEnoughPowerLevel( + {EventType::RoomAvatar}, roomid_.toStdString(), utils::localUser().toStdString()); + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } + + return false; +} + +bool RoomSettings::isEncryptionEnabled() const { return usesEncryption_; @@ -269,8 +311,8 @@ RoomSettings::updateAccessRules(const std::string &room_id, const mtx::events::state::JoinRules &join_rule, const mtx::events::state::GuestAccess &guest_access) { - // startLoadingSpinner(); - // resetErrorLabel(); + isLoading_ = true; + emit loadingChanged(); http::client()->send_state_event( room_id, @@ -281,8 +323,9 @@ RoomSettings::updateAccessRules(const std::string &room_id, nhlog::net()->warn("failed to send m.room.join_rule: {} {}", static_cast<int>(err->status_code), err->matrix_error.error); - // emit showErrorMessage(QString::fromStdString(err->matrix_error.error)); - + emit displayError(QString::fromStdString(err->matrix_error.error)); + isLoading_ = false; + emit loadingChanged(); return; } @@ -294,13 +337,115 @@ RoomSettings::updateAccessRules(const std::string &room_id, nhlog::net()->warn("failed to send m.room.guest_access: {} {}", static_cast<int>(err->status_code), err->matrix_error.error); - // emit showErrorMessage( - // QString::fromStdString(err->matrix_error.error)); + emit displayError( + QString::fromStdString(err->matrix_error.error)); + } + + isLoading_ = false; + emit loadingChanged(); + }); + }); +} + +void +RoomSettings::stopLoading() +{ + isLoading_ = false; + emit loadingChanged(); +} + +void +RoomSettings::avatarChanged() +{ + retrieveRoomInfo(); + emit avatarUrlChanged(); +} + +void +RoomSettings::updateAvatar() +{ + const QString picturesFolder = + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + const QString fileName = QFileDialog::getOpenFileName( + nullptr, tr("Select an avatar"), picturesFolder, tr("All Files (*)")); + + if (fileName.isEmpty()) + return; + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); + + const auto format = mime.name().split("/")[0]; + + QFile file{fileName, this}; + if (format != "image") { + emit displayError(tr("The selected file is not an image")); + return; + } + + if (!file.open(QIODevice::ReadOnly)) { + emit displayError(tr("Error while reading file: %1").arg(file.errorString())); + return; + } + + isLoading_ = true; + emit loadingChanged(); + + // Events emitted from the http callbacks (different threads) will + // be queued back into the UI thread through this proxy object. + auto proxy = std::make_shared<ThreadProxy>(); + connect(proxy.get(), &ThreadProxy::error, this, &RoomSettings::displayError); + connect(proxy.get(), &ThreadProxy::avatarChanged, this, &RoomSettings::avatarChanged); + connect(proxy.get(), &ThreadProxy::stopLoading, this, &RoomSettings::stopLoading); + + const auto bin = file.peek(file.size()); + const auto payload = std::string(bin.data(), bin.size()); + const auto dimensions = QImageReader(&file).size(); + + // First we need to create a new mxc URI + // (i.e upload media to the Matrix content repository) for the new avatar. + http::client()->upload( + payload, + mime.name().toStdString(), + QFileInfo(fileName).fileName().toStdString(), + [proxy = std::move(proxy), + dimensions, + payload, + mimetype = mime.name().toStdString(), + size = payload.size(), + room_id = roomid_.toStdString(), + content = std::move(bin)](const mtx::responses::ContentURI &res, + mtx::http::RequestErr err) { + if (err) { + emit proxy->stopLoading(); + emit proxy->error( + tr("Failed to upload image: %s") + .arg(QString::fromStdString(err->matrix_error.error))); + return; + } + + using namespace mtx::events; + state::Avatar avatar_event; + avatar_event.image_info.w = dimensions.width(); + avatar_event.image_info.h = dimensions.height(); + avatar_event.image_info.mimetype = mimetype; + avatar_event.image_info.size = size; + avatar_event.url = res.content_uri; + + http::client()->send_state_event( + room_id, + avatar_event, + [content = std::move(content), proxy = std::move(proxy)]( + const mtx::responses::EventId &, mtx::http::RequestErr err) { + if (err) { + emit proxy->error( + tr("Failed to upload image: %s") + .arg(QString::fromStdString(err->matrix_error.error))); return; } - // emit signal that stops loading spinner and reset error label + emit proxy->stopLoading(); + emit proxy->avatarChanged(); }); }); } \ No newline at end of file |