mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Replaced old photo crop box with photo editor for profile photos.
This commit is contained in:
parent
a996b14291
commit
17465e1082
8 changed files with 162 additions and 113 deletions
|
@ -466,6 +466,7 @@ void GroupInfoBox::prepare() {
|
||||||
|
|
||||||
_photo.create(
|
_photo.create(
|
||||||
this,
|
this,
|
||||||
|
&_navigation->parentController()->window(),
|
||||||
((_type == Type::Channel)
|
((_type == Type::Channel)
|
||||||
? tr::lng_create_channel_crop
|
? tr::lng_create_channel_crop
|
||||||
: tr::lng_create_group_crop)(tr::now),
|
: tr::lng_create_group_crop)(tr::now),
|
||||||
|
|
|
@ -495,6 +495,7 @@ object_ptr<Ui::RpWidget> Controller::createPhotoEdit() {
|
||||||
_wrap,
|
_wrap,
|
||||||
object_ptr<Ui::UserpicButton>(
|
object_ptr<Ui::UserpicButton>(
|
||||||
_wrap,
|
_wrap,
|
||||||
|
&_navigation->parentController()->window(),
|
||||||
_peer,
|
_peer,
|
||||||
Ui::UserpicButton::Role::ChangePhoto,
|
Ui::UserpicButton::Role::ChangePhoto,
|
||||||
st::defaultUserpicButton),
|
st::defaultUserpicButton),
|
||||||
|
|
|
@ -7,12 +7,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "editor/photo_editor_layer_widget.h"
|
#include "editor/photo_editor_layer_widget.h"
|
||||||
|
|
||||||
|
#include "app.h" // readImage
|
||||||
|
#include "boxes/confirm_box.h" // InformBox
|
||||||
#include "editor/photo_editor.h"
|
#include "editor/photo_editor.h"
|
||||||
#include "storage/storage_media_prepare.h"
|
#include "storage/storage_media_prepare.h"
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
|
||||||
namespace Editor {
|
namespace Editor {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kProfilePhotoSize = 640;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void OpenWithPreparedFile(
|
void OpenWithPreparedFile(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
@ -48,6 +57,80 @@ void OpenWithPreparedFile(
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrepareProfilePhoto(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
not_null<Window::Controller*> controller,
|
||||||
|
Fn<void(QImage &&image)> &&doneCallback) {
|
||||||
|
const auto resizeToMinSize = [=](
|
||||||
|
QImage &&image,
|
||||||
|
Qt::AspectRatioMode mode) {
|
||||||
|
const auto &minSize = kProfilePhotoSize;
|
||||||
|
if ((image.width() < minSize) || (image.height() < minSize)) {
|
||||||
|
return image.scaled(
|
||||||
|
minSize,
|
||||||
|
minSize,
|
||||||
|
mode,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
return std::move(image);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto callback = [=, done = std::move(doneCallback)](
|
||||||
|
const FileDialog::OpenResult &result) {
|
||||||
|
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto image = result.remoteContent.isEmpty()
|
||||||
|
? App::readImage(result.paths.front())
|
||||||
|
: App::readImage(result.remoteContent);
|
||||||
|
if (image.isNull()
|
||||||
|
|| (image.width() > (10 * image.height()))
|
||||||
|
|| (image.height() > (10 * image.width()))) {
|
||||||
|
controller->show(Box<InformBox>(tr::lng_bad_photo(tr::now)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
image = resizeToMinSize(
|
||||||
|
std::move(image),
|
||||||
|
Qt::KeepAspectRatioByExpanding);
|
||||||
|
const auto fileImage = std::make_shared<Image>(std::move(image));
|
||||||
|
|
||||||
|
auto applyModifications = [=, done = std::move(done)](
|
||||||
|
const PhotoModifications &mods) {
|
||||||
|
done(resizeToMinSize(
|
||||||
|
ImageModified(fileImage->original(), mods),
|
||||||
|
Qt::KeepAspectRatio));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto crop = [&] {
|
||||||
|
const auto &i = fileImage;
|
||||||
|
const auto minSide = std::min(i->width(), i->height());
|
||||||
|
return QRect(
|
||||||
|
(i->width() - minSide) / 2,
|
||||||
|
(i->height() - minSide) / 2,
|
||||||
|
minSide,
|
||||||
|
minSide);
|
||||||
|
}();
|
||||||
|
|
||||||
|
controller->showLayer(
|
||||||
|
std::make_unique<LayerWidget>(
|
||||||
|
parent,
|
||||||
|
controller,
|
||||||
|
fileImage,
|
||||||
|
PhotoModifications{ .crop = std::move(crop) },
|
||||||
|
std::move(applyModifications),
|
||||||
|
EditorData{
|
||||||
|
.cropType = EditorData::CropType::Ellipse,
|
||||||
|
.keepAspectRatio = true, }),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
};
|
||||||
|
FileDialog::GetOpenPath(
|
||||||
|
parent.get(),
|
||||||
|
tr::lng_choose_image(tr::now),
|
||||||
|
FileDialog::ImagesOrAllFilter(),
|
||||||
|
crl::guard(parent, callback));
|
||||||
|
}
|
||||||
|
|
||||||
LayerWidget::LayerWidget(
|
LayerWidget::LayerWidget(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
not_null<Window::Controller*> window,
|
not_null<Window::Controller*> window,
|
||||||
|
|
|
@ -31,6 +31,11 @@ void OpenWithPreparedFile(
|
||||||
int previewWidth,
|
int previewWidth,
|
||||||
Fn<void()> &&doneCallback);
|
Fn<void()> &&doneCallback);
|
||||||
|
|
||||||
|
void PrepareProfilePhoto(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
not_null<Window::Controller*> controller,
|
||||||
|
Fn<void(QImage &&image)> &&doneCallback);
|
||||||
|
|
||||||
class PhotoEditor;
|
class PhotoEditor;
|
||||||
|
|
||||||
class LayerWidget : public Ui::LayerWidget {
|
class LayerWidget : public Ui::LayerWidget {
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
|
#include "editor/photo_editor_layer_widget.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
@ -269,6 +270,13 @@ Cover::Cover(
|
||||||
|
|
||||||
initViewers(std::move(title));
|
initViewers(std::move(title));
|
||||||
setupChildGeometry();
|
setupChildGeometry();
|
||||||
|
|
||||||
|
_userpic->uploadPhotoRequests(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
_peer->session().api().uploadPeerPhoto(
|
||||||
|
_peer,
|
||||||
|
_userpic->takeResultImage());
|
||||||
|
}, _userpic->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::setupChildGeometry() {
|
void Cover::setupChildGeometry() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "settings/settings_information.h"
|
#include "settings/settings_information.h"
|
||||||
|
|
||||||
|
#include "editor/photo_editor_layer_widget.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/wrap/padding_wrap.h"
|
#include "ui/wrap/padding_wrap.h"
|
||||||
|
@ -63,38 +64,13 @@ void SetupPhoto(
|
||||||
st::settingsInfoPhotoSet);
|
st::settingsInfoPhotoSet);
|
||||||
upload->setFullRadius(true);
|
upload->setFullRadius(true);
|
||||||
upload->addClickHandler([=] {
|
upload->addClickHandler([=] {
|
||||||
const auto filter = FileDialog::ImagesOrAllFilter();
|
auto callback = [=](QImage &&image) {
|
||||||
const auto callback = [=](const FileDialog::OpenResult &result) {
|
self->session().api().uploadPeerPhoto(self, std::move(image));
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto image = result.remoteContent.isEmpty()
|
|
||||||
? App::readImage(result.paths.front())
|
|
||||||
: App::readImage(result.remoteContent);
|
|
||||||
if (image.isNull()
|
|
||||||
|| image.width() > 10 * image.height()
|
|
||||||
|| image.height() > 10 * image.width()) {
|
|
||||||
controller->show(Box<InformBox>(tr::lng_bad_photo(tr::now)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto box = Box<PhotoCropBox>(
|
|
||||||
image,
|
|
||||||
tr::lng_settings_crop_profile(tr::now));
|
|
||||||
box->ready(
|
|
||||||
) | rpl::start_with_next([=](QImage &&image) {
|
|
||||||
self->session().api().uploadPeerPhoto(
|
|
||||||
self,
|
|
||||||
std::move(image));
|
|
||||||
}, box->lifetime());
|
|
||||||
controller->show(std::move(box));
|
|
||||||
};
|
};
|
||||||
FileDialog::GetOpenPath(
|
Editor::PrepareProfilePhoto(
|
||||||
upload,
|
upload,
|
||||||
tr::lng_choose_image(tr::now),
|
&controller->window(),
|
||||||
filter,
|
std::move(callback));
|
||||||
crl::guard(upload, callback));
|
|
||||||
});
|
});
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
wrap->widthValue(),
|
wrap->widthValue(),
|
||||||
|
|
|
@ -29,9 +29,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "boxes/photo_crop_box.h"
|
#include "boxes/photo_crop_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
#include "editor/photo_editor_layer_widget.h"
|
||||||
#include "media/streaming/media_streaming_instance.h"
|
#include "media/streaming/media_streaming_instance.h"
|
||||||
#include "media/streaming/media_streaming_player.h"
|
#include "media/streaming/media_streaming_player.h"
|
||||||
#include "media/streaming/media_streaming_document.h"
|
#include "media/streaming/media_streaming_document.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -68,74 +70,6 @@ QPixmap CreateSquarePixmap(int width, Callback &&paintCallback) {
|
||||||
return App::pixmapFromImageInPlace(std::move(image));
|
return App::pixmapFromImageInPlace(std::move(image));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Callback>
|
|
||||||
void SuggestPhoto(
|
|
||||||
const QImage &image,
|
|
||||||
const QString &title,
|
|
||||||
Callback &&callback) {
|
|
||||||
auto badAspect = [](int a, int b) {
|
|
||||||
return (a >= 10 * b);
|
|
||||||
};
|
|
||||||
if (image.isNull()
|
|
||||||
|| badAspect(image.width(), image.height())
|
|
||||||
|| badAspect(image.height(), image.width())) {
|
|
||||||
Ui::show(
|
|
||||||
Box<InformBox>(tr::lng_bad_photo(tr::now)),
|
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto box = Ui::show(
|
|
||||||
Box<PhotoCropBox>(image, title),
|
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
box->ready(
|
|
||||||
) | rpl::start_with_next(
|
|
||||||
std::forward<Callback>(callback),
|
|
||||||
box->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Callback>
|
|
||||||
void SuggestPhotoFile(
|
|
||||||
const FileDialog::OpenResult &result,
|
|
||||||
const QString &title,
|
|
||||||
Callback &&callback) {
|
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto image = [&] {
|
|
||||||
if (!result.remoteContent.isEmpty()) {
|
|
||||||
return App::readImage(result.remoteContent);
|
|
||||||
} else if (!result.paths.isEmpty()) {
|
|
||||||
return App::readImage(result.paths.front());
|
|
||||||
}
|
|
||||||
return QImage();
|
|
||||||
}();
|
|
||||||
SuggestPhoto(
|
|
||||||
image,
|
|
||||||
title,
|
|
||||||
std::forward<Callback>(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Callback>
|
|
||||||
void ShowChoosePhotoBox(
|
|
||||||
QPointer<QWidget> parent,
|
|
||||||
const QString &title,
|
|
||||||
Callback &&callback) {
|
|
||||||
auto filter = FileDialog::ImagesOrAllFilter();
|
|
||||||
auto handleChosenPhoto = [
|
|
||||||
title,
|
|
||||||
callback = std::forward<Callback>(callback)
|
|
||||||
](auto &&result) mutable {
|
|
||||||
SuggestPhotoFile(result, title, std::move(callback));
|
|
||||||
};
|
|
||||||
FileDialog::GetOpenPath(
|
|
||||||
parent,
|
|
||||||
tr::lng_choose_image(tr::now),
|
|
||||||
filter,
|
|
||||||
std::move(handleChosenPhoto));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
HistoryDownButton::HistoryDownButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple)
|
HistoryDownButton::HistoryDownButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple)
|
||||||
|
@ -183,11 +117,33 @@ void HistoryDownButton::setUnreadCount(int unreadCount) {
|
||||||
|
|
||||||
UserpicButton::UserpicButton(
|
UserpicButton::UserpicButton(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Role role,
|
||||||
|
const style::UserpicButton &st)
|
||||||
|
: RippleButton(parent, st.changeButton.ripple)
|
||||||
|
, _st(st)
|
||||||
|
, _controller(window->sessionController())
|
||||||
|
, _window(window)
|
||||||
|
, _peer(peer)
|
||||||
|
, _cropTitle(CropTitle(peer))
|
||||||
|
, _role(role) {
|
||||||
|
Expects(_role == Role::ChangePhoto);
|
||||||
|
|
||||||
|
_waiting = false;
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
UserpicButton::UserpicButton(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
const QString &cropTitle,
|
const QString &cropTitle,
|
||||||
Role role,
|
Role role,
|
||||||
const style::UserpicButton &st)
|
const style::UserpicButton &st)
|
||||||
: RippleButton(parent, st.changeButton.ripple)
|
: RippleButton(parent, st.changeButton.ripple)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
|
, _controller(window->sessionController())
|
||||||
|
, _window(window)
|
||||||
, _cropTitle(cropTitle)
|
, _cropTitle(cropTitle)
|
||||||
, _role(role) {
|
, _role(role) {
|
||||||
Expects(_role == Role::ChangePhoto);
|
Expects(_role == Role::ChangePhoto);
|
||||||
|
@ -205,6 +161,7 @@ UserpicButton::UserpicButton(
|
||||||
: RippleButton(parent, st.changeButton.ripple)
|
: RippleButton(parent, st.changeButton.ripple)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
|
, _window(&controller->window())
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _cropTitle(CropTitle(_peer))
|
, _cropTitle(CropTitle(_peer))
|
||||||
, _role(role) {
|
, _role(role) {
|
||||||
|
@ -246,7 +203,7 @@ void UserpicButton::setClickHandlerByRole() {
|
||||||
addClickHandler(App::LambdaDelayed(
|
addClickHandler(App::LambdaDelayed(
|
||||||
_st.changeButton.ripple.hideDuration,
|
_st.changeButton.ripple.hideDuration,
|
||||||
this,
|
this,
|
||||||
[this] { changePhotoLazy(); }));
|
[=] { changePhotoLocally(); }));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Role::OpenPhoto:
|
case Role::OpenPhoto:
|
||||||
|
@ -265,18 +222,20 @@ void UserpicButton::setClickHandlerByRole() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::changePhotoLazy() {
|
void UserpicButton::changePhotoLocally(bool requestToUpload) {
|
||||||
auto callback = crl::guard(
|
if (!_window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto callback = [=](QImage &&image) {
|
||||||
|
setImage(std::move(image));
|
||||||
|
if (requestToUpload) {
|
||||||
|
_uploadPhotoRequests.fire({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Editor::PrepareProfilePhoto(
|
||||||
this,
|
this,
|
||||||
[this](QImage &&image) { setImage(std::move(image)); });
|
_window,
|
||||||
ShowChoosePhotoBox(this, _cropTitle, std::move(callback));
|
std::move(callback));
|
||||||
}
|
|
||||||
|
|
||||||
void UserpicButton::uploadNewPeerPhoto() {
|
|
||||||
auto callback = crl::guard(this, [=](QImage &&image) {
|
|
||||||
_peer->session().api().uploadPeerPhoto(_peer, std::move(image));
|
|
||||||
});
|
|
||||||
ShowChoosePhotoBox(this, _cropTitle, std::move(callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::openPeerPhoto() {
|
void UserpicButton::openPeerPhoto() {
|
||||||
|
@ -284,7 +243,7 @@ void UserpicButton::openPeerPhoto() {
|
||||||
Expects(_controller != nullptr);
|
Expects(_controller != nullptr);
|
||||||
|
|
||||||
if (_changeOverlayEnabled && _cursorInChangeOverlay) {
|
if (_changeOverlayEnabled && _cursorInChangeOverlay) {
|
||||||
uploadNewPeerPhoto();
|
changePhotoLocally(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,6 +733,10 @@ void UserpicButton::prepareUserpicPixmap() {
|
||||||
: InMemoryKey();
|
: InMemoryKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<> UserpicButton::uploadPhotoRequests() const {
|
||||||
|
return _uploadPhotoRequests.events();
|
||||||
|
}
|
||||||
|
|
||||||
SilentToggle::SilentToggle(QWidget *parent, not_null<ChannelData*> channel)
|
SilentToggle::SilentToggle(QWidget *parent, not_null<ChannelData*> channel)
|
||||||
: RippleButton(parent, st::historySilentToggle.ripple)
|
: RippleButton(parent, st::historySilentToggle.ripple)
|
||||||
, _st(st::historySilentToggle)
|
, _st(st::historySilentToggle)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CloudImageView;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
class Controller;
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
|
@ -68,6 +69,13 @@ public:
|
||||||
|
|
||||||
UserpicButton(
|
UserpicButton(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
not_null<::Window::Controller*> window,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Role role,
|
||||||
|
const style::UserpicButton &st);
|
||||||
|
UserpicButton(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<::Window::Controller*> window,
|
||||||
const QString &cropTitle,
|
const QString &cropTitle,
|
||||||
Role role,
|
Role role,
|
||||||
const style::UserpicButton &st);
|
const style::UserpicButton &st);
|
||||||
|
@ -86,6 +94,8 @@ public:
|
||||||
void switchChangePhotoOverlay(bool enabled);
|
void switchChangePhotoOverlay(bool enabled);
|
||||||
void showSavedMessagesOnSelf(bool enabled);
|
void showSavedMessagesOnSelf(bool enabled);
|
||||||
|
|
||||||
|
rpl::producer<> uploadPhotoRequests() const;
|
||||||
|
|
||||||
QImage takeResultImage() {
|
QImage takeResultImage() {
|
||||||
return std::move(_result);
|
return std::move(_result);
|
||||||
}
|
}
|
||||||
|
@ -128,11 +138,11 @@ private:
|
||||||
void grabOldUserpic();
|
void grabOldUserpic();
|
||||||
void setClickHandlerByRole();
|
void setClickHandlerByRole();
|
||||||
void openPeerPhoto();
|
void openPeerPhoto();
|
||||||
void changePhotoLazy();
|
void changePhotoLocally(bool requestToUpload = false);
|
||||||
void uploadNewPeerPhoto();
|
|
||||||
|
|
||||||
const style::UserpicButton &_st;
|
const style::UserpicButton &_st;
|
||||||
::Window::SessionController *_controller = nullptr;
|
::Window::SessionController *_controller = nullptr;
|
||||||
|
::Window::Controller *_window = nullptr;
|
||||||
PeerData *_peer = nullptr;
|
PeerData *_peer = nullptr;
|
||||||
std::shared_ptr<Data::CloudImageView> _userpicView;
|
std::shared_ptr<Data::CloudImageView> _userpicView;
|
||||||
QString _cropTitle;
|
QString _cropTitle;
|
||||||
|
@ -154,6 +164,8 @@ private:
|
||||||
bool _changeOverlayEnabled = false;
|
bool _changeOverlayEnabled = false;
|
||||||
Ui::Animations::Simple _changeOverlayShown;
|
Ui::Animations::Simple _changeOverlayShown;
|
||||||
|
|
||||||
|
rpl::event_stream<> _uploadPhotoRequests;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SilentToggle
|
class SilentToggle
|
||||||
|
|
Loading…
Add table
Reference in a new issue