Make lambda that updates avatar a class method

This commit is contained in:
Konstantinos Sideris 2018-08-29 16:15:31 +03:00
parent 56ee290b03
commit b7362298b0
2 changed files with 91 additions and 91 deletions

View file

@ -363,97 +363,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
auto filter = new ClickableFilter(this); auto filter = new ClickableFilter(this);
avatar_->installEventFilter(filter); avatar_->installEventFilter(filter);
avatar_->setCursor(Qt::PointingHandCursor); avatar_->setCursor(Qt::PointingHandCursor);
connect(filter, &ClickableFilter::clicked, this, [this]() { connect(filter, &ClickableFilter::clicked, this, &RoomSettings::updateAvatar);
const auto fileName = QFileDialog::getOpenFileName(
this, tr("Select an avatar"), "", 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") {
displayErrorMessage(tr("The selected media is not an image"));
return;
}
if (!file.open(QIODevice::ReadOnly)) {
displayErrorMessage(
tr("Error while reading media: %1").arg(file.errorString()));
return;
}
if (spinner_) {
startLoadingSpinner();
resetErrorLabel();
}
// 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::displayErrorMessage);
connect(
proxy.get(), &ThreadProxy::avatarChanged, this, &RoomSettings::setAvatar);
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 = room_id_.toStdString(),
content = std::move(bin)](const mtx::responses::ContentURI &res,
mtx::http::RequestErr err) {
if (err) {
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<state::Avatar, EventType::RoomAvatar>(
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 proxy->avatarChanged(QImage::fromData(content));
});
});
});
} }
auto roomNameLabel = new QLabel(QString::fromStdString(info_.name), this); auto roomNameLabel = new QLabel(QString::fromStdString(info_.name), this);
@ -737,3 +647,89 @@ RoomSettings::resetErrorLabel()
errorLabel_->clear(); errorLabel_->clear();
} }
} }
void
RoomSettings::updateAvatar()
{
const auto fileName =
QFileDialog::getOpenFileName(this, tr("Select an avatar"), "", 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") {
displayErrorMessage(tr("The selected media is not an image"));
return;
}
if (!file.open(QIODevice::ReadOnly)) {
displayErrorMessage(tr("Error while reading media: %1").arg(file.errorString()));
return;
}
if (spinner_) {
startLoadingSpinner();
resetErrorLabel();
}
// 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::displayErrorMessage);
connect(proxy.get(), &ThreadProxy::avatarChanged, this, &RoomSettings::setAvatar);
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 = room_id_.toStdString(),
content = std::move(bin)](const mtx::responses::ContentURI &res,
mtx::http::RequestErr err) {
if (err) {
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<state::Avatar, EventType::RoomAvatar>(
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 proxy->avatarChanged(QImage::fromData(content));
});
});
}

View file

@ -102,6 +102,10 @@ protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
private slots:
//! The file dialog opens so the user can select and upload a new room avatar.
void updateAvatar();
private: private:
//! Whether the user has enough power level to send m.room.join_rules events. //! Whether the user has enough power level to send m.room.join_rules events.
bool canChangeJoinRules(const std::string &room_id, const std::string &user_id) const; bool canChangeJoinRules(const std::string &room_id, const std::string &user_id) const;