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);
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;
settingsInfoPhotoSkip: 7px;
settingsInfoNameSkip: -1px;
settingsInfoUploadLeft: 6px;
settingsBio: InputField(defaultInputField) {
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(
not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller,
@ -124,6 +158,15 @@ void SetupPhoto(
self,
Ui::UserpicButton::Role::OpenPhoto,
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>(
wrap,
@ -146,6 +189,12 @@ void SetupPhoto(
photo->moveToLeft(
(max - photoWidth) / 2,
st::settingsInfoPhotoTop);
upload->moveToLeft(
((max - photoWidth) / 2
+ photoWidth
- upload->width()
+ st::settingsInfoUploadLeft),
photo->y() + photo->height() - upload->height());
name->moveToLeft(
(max - nameWidth) / 2,
(photo->y() + photo->height() + st::settingsInfoPhotoSkip));

View file

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

View file

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

View file

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