Add upload photo button to Edit Info settings.

This commit is contained in:
John Preston 2022-03-15 16:35:28 +04:00
parent f31be7784b
commit b8028886b0
8 changed files with 103 additions and 16 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -142,9 +142,18 @@ settingsInfoPhoto: UserpicButton(defaultUserpicButton) {
size: size(settingsInfoPhotoSize, settingsInfoPhotoSize); size: size(settingsInfoPhotoSize, settingsInfoPhotoSize);
photoSize: settingsInfoPhotoSize; photoSize: settingsInfoPhotoSize;
} }
settingsInfoUploadSize: 32px;
settingsInfoUpload: UserpicButton(defaultUserpicButton) {
size: size(settingsInfoUploadSize, settingsInfoUploadSize);
photoSize: settingsInfoUploadSize;
changeIcon: icon {{ "settings/photo", activeButtonFg }};
changeIconPosition: point(4px, 4px);
}
settingsInfoUploadBorder: 2px;
settingsInfoPhotoTop: 0px; settingsInfoPhotoTop: 0px;
settingsInfoPhotoSkip: 7px; settingsInfoPhotoSkip: 7px;
settingsInfoNameSkip: -1px; settingsInfoNameSkip: -1px;
settingsInfoUploadLeft: 6px;
settingsBio: InputField(defaultInputField) { settingsBio: InputField(defaultInputField) {
textBg: transparent; textBg: transparent;

View file

@ -111,6 +111,40 @@ private:
}; };
} }
[[nodiscard]] not_null<Ui::UserpicButton*> CreateUploadButton(
not_null<Ui::RpWidget*> parent,
not_null<Window::SessionController*> controller) {
const auto background = Ui::CreateChild<Ui::RpWidget>(parent.get());
const auto upload = Ui::CreateChild<Ui::UserpicButton>(
parent.get(),
&controller->window(),
tr::lng_settings_crop_profile(tr::now),
Ui::UserpicButton::Role::ChoosePhoto,
st::settingsInfoUpload);
const auto border = st::settingsInfoUploadBorder;
const auto size = upload->rect().marginsAdded(
{ border, border, border, border }
).size();
background->resize(size);
background->paintRequest(
) | rpl::start_with_next([=] {
auto p = QPainter(background);
auto hq = PainterHighQualityEnabler(p);
p.setBrush(st::boxBg);
p.setPen(Qt::NoPen);
p.drawEllipse(background->rect());
}, background->lifetime());
upload->positionValue(
) | rpl::start_with_next([=](QPoint position) {
background->move(position - QPoint(border, border));
}, background->lifetime());
return upload;
}
void SetupPhoto( void SetupPhoto(
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
@ -124,6 +158,15 @@ void SetupPhoto(
self, self,
Ui::UserpicButton::Role::OpenPhoto, Ui::UserpicButton::Role::OpenPhoto,
st::settingsInfoPhoto); st::settingsInfoPhoto);
const auto upload = CreateUploadButton(wrap, controller);
upload->chosenImages(
) | rpl::start_with_next([=](QImage &&image) {
self->session().api().peerPhoto().upload(
self,
base::duplicate(image));
photo->changeTo(std::move(image));
}, upload->lifetime());
const auto name = Ui::CreateChild<Ui::FlatLabel>( const auto name = Ui::CreateChild<Ui::FlatLabel>(
wrap, wrap,
@ -146,6 +189,12 @@ void SetupPhoto(
photo->moveToLeft( photo->moveToLeft(
(max - photoWidth) / 2, (max - photoWidth) / 2,
st::settingsInfoPhotoTop); st::settingsInfoPhotoTop);
upload->moveToLeft(
((max - photoWidth) / 2
+ photoWidth
- upload->width()
+ st::settingsInfoUploadLeft),
photo->y() + photo->height() - upload->height());
name->moveToLeft( name->moveToLeft(
(max - nameWidth) / 2, (max - nameWidth) / 2,
(photo->y() + photo->height() + st::settingsInfoPhotoSkip)); (photo->y() + photo->height() + st::settingsInfoPhotoSkip));

View file

@ -113,7 +113,6 @@ Cover::Cover(
setupChildGeometry(); setupChildGeometry();
_userpic->switchChangePhotoOverlay(_user->isSelf()); _userpic->switchChangePhotoOverlay(_user->isSelf());
_userpic->uploadPhotoRequests( _userpic->uploadPhotoRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
_user->session().api().peerPhoto().upload( _user->session().api().peerPhoto().upload(

View file

@ -190,7 +190,7 @@ UserpicButton::UserpicButton(
, _window(window) , _window(window)
, _cropTitle(cropTitle) , _cropTitle(cropTitle)
, _role(role) { , _role(role) {
Expects(_role == Role::ChangePhoto); Expects(_role == Role::ChangePhoto || _role == Role::ChoosePhoto);
_waiting = false; _waiting = false;
prepare(); prepare();
@ -239,10 +239,24 @@ void UserpicButton::prepare() {
prepareUserpicPixmap(); prepareUserpicPixmap();
} }
setClickHandlerByRole(); setClickHandlerByRole();
if (_role == Role::ChangePhoto) {
chosenImages(
) | rpl::start_with_next([=](QImage &&image) {
setImage(std::move(image));
if (_requestToUpload) {
_uploadPhotoRequests.fire({});
}
}, lifetime());
}
} }
void UserpicButton::setClickHandlerByRole() { void UserpicButton::setClickHandlerByRole() {
switch (_role) { switch (_role) {
case Role::ChoosePhoto:
addClickHandler([=] { choosePhotoLocally(); });
break;
case Role::ChangePhoto: case Role::ChangePhoto:
addClickHandler([=] { changePhotoLocally(); }); addClickHandler([=] { changePhotoLocally(); });
break; break;
@ -263,25 +277,26 @@ void UserpicButton::setClickHandlerByRole() {
} }
} }
void UserpicButton::changePhotoLocally(bool requestToUpload) { void UserpicButton::changeTo(QImage &&image) {
setImage(std::move(image));
}
void UserpicButton::choosePhotoLocally() {
if (!_window) { if (!_window) {
return; return;
} }
auto callback = [=](QImage &&image) { auto callback = [=](QImage &&image) {
setImage(std::move(image)); _chosenImages.fire(std::move(image));
if (requestToUpload) {
_uploadPhotoRequests.fire({});
}
}; };
const auto chooseFile = [=] { const auto chooseFile = [=] {
base::call_delayed( base::call_delayed(
_st.changeButton.ripple.hideDuration, _st.changeButton.ripple.hideDuration,
crl::guard(this, [=] { crl::guard(this, [=] {
Editor::PrepareProfilePhotoFromFile( Editor::PrepareProfilePhotoFromFile(
this, this,
_window, _window,
callback); callback);
})); }));
}; };
if (!IsCameraAvailable()) { if (!IsCameraAvailable()) {
chooseFile(); chooseFile();
@ -295,6 +310,11 @@ void UserpicButton::changePhotoLocally(bool requestToUpload) {
} }
} }
void UserpicButton::changePhotoLocally(bool requestToUpload) {
_requestToUpload = requestToUpload;
choosePhotoLocally();
}
void UserpicButton::openPeerPhoto() { void UserpicButton::openPeerPhoto() {
Expects(_peer != nullptr); Expects(_peer != nullptr);
Expects(_controller != nullptr); Expects(_controller != nullptr);
@ -368,7 +388,7 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
paintUserpicFrame(p, photoPosition); paintUserpicFrame(p, photoPosition);
} }
if (_role == Role::ChangePhoto) { if (_role == Role::ChangePhoto || _role == Role::ChoosePhoto) {
auto over = isOver() || isDown(); auto over = isOver() || isDown();
if (over) { if (over) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
@ -789,10 +809,6 @@ 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)

View file

@ -63,6 +63,7 @@ private:
class UserpicButton : public RippleButton { class UserpicButton : public RippleButton {
public: public:
enum class Role { enum class Role {
ChoosePhoto,
ChangePhoto, ChangePhoto,
OpenPhoto, OpenPhoto,
OpenProfile, OpenProfile,
@ -96,12 +97,22 @@ public:
void switchChangePhotoOverlay(bool enabled); void switchChangePhotoOverlay(bool enabled);
void showSavedMessagesOnSelf(bool enabled); void showSavedMessagesOnSelf(bool enabled);
rpl::producer<> uploadPhotoRequests() const; // Role::ChoosePhoto
[[nodiscard]] rpl::producer<QImage> chosenImages() const {
return _chosenImages.events();
}
QImage takeResultImage() { // Role::ChangePhoto
[[nodiscard]] rpl::producer<> uploadPhotoRequests() const {
return _uploadPhotoRequests.events();
}
[[nodiscard]] QImage takeResultImage() {
return std::move(_result); return std::move(_result);
} }
// For Role::OpenPhoto as if it is Role::ChangePhoto.
void changeTo(QImage &&image);
protected: protected:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override;
@ -140,6 +151,7 @@ private:
void grabOldUserpic(); void grabOldUserpic();
void setClickHandlerByRole(); void setClickHandlerByRole();
void openPeerPhoto(); void openPeerPhoto();
void choosePhotoLocally();
void changePhotoLocally(bool requestToUpload = false); void changePhotoLocally(bool requestToUpload = false);
const style::UserpicButton &_st; const style::UserpicButton &_st;
@ -154,6 +166,7 @@ private:
QPixmap _userpic, _oldUserpic; QPixmap _userpic, _oldUserpic;
bool _userpicHasImage = false; bool _userpicHasImage = false;
bool _userpicCustom = false; bool _userpicCustom = false;
bool _requestToUpload = false;
InMemoryKey _userpicUniqueKey; InMemoryKey _userpicUniqueKey;
Ui::Animations::Simple _a_appearance; Ui::Animations::Simple _a_appearance;
QImage _result; QImage _result;
@ -168,6 +181,7 @@ private:
bool _changeOverlayEnabled = false; bool _changeOverlayEnabled = false;
Ui::Animations::Simple _changeOverlayShown; Ui::Animations::Simple _changeOverlayShown;
rpl::event_stream<QImage> _chosenImages;
rpl::event_stream<> _uploadPhotoRequests; rpl::event_stream<> _uploadPhotoRequests;
}; };