summary refs log tree commit diff
path: root/src/ui/RoomSettings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/RoomSettings.cpp')
-rw-r--r--src/ui/RoomSettings.cpp167
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