From b8028886b0b40c3f98b801424dace0540950d3ce Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 15 Mar 2022 16:35:28 +0400 Subject: [PATCH] Add upload photo button to Edit Info settings. --- Telegram/Resources/icons/settings/photo.png | Bin 0 -> 435 bytes .../Resources/icons/settings/photo@2x.png | Bin 0 -> 855 bytes .../Resources/icons/settings/photo@3x.png | Bin 0 -> 1195 bytes Telegram/SourceFiles/settings/settings.style | 9 ++++ .../settings/settings_information.cpp | 49 ++++++++++++++++++ .../SourceFiles/settings/settings_main.cpp | 1 - Telegram/SourceFiles/ui/special_buttons.cpp | 42 ++++++++++----- Telegram/SourceFiles/ui/special_buttons.h | 18 ++++++- 8 files changed, 103 insertions(+), 16 deletions(-) create mode 100644 Telegram/Resources/icons/settings/photo.png create mode 100644 Telegram/Resources/icons/settings/photo@2x.png create mode 100644 Telegram/Resources/icons/settings/photo@3x.png diff --git a/Telegram/Resources/icons/settings/photo.png b/Telegram/Resources/icons/settings/photo.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6d4e0a6ac1f55637f9cbecb5e69f5d692a4219 GIT binary patch literal 435 zcmV;k0ZjghP)5kR40T;s6y=r0^Sr+Ar}I<#zV|#& zD5|RJX`rs_q9}@@sO$QvRaKQxgfZr$Ns`F2Jho(6PLhQ0VvL2N)9Lh`%kvxn48us% zG)+^(FaRLW^I0N(qup+|TCFIhV|l;dm&>K&I3kfGl3uS@%d%8e9ZOBqY}>wEE~30p zgb*TxbX_-=UDpvp5JIy=i^b!k2SGq7bzK)@j4^gymr@!8fk^ZN{zk(v_`c6~ecvC3 zL3E=JzF>?!R+XgV@fbx>S(X5>-|r8HgDCt=mSr=3^%q%|2{(%47ywMubutHY$6vcnxCJ+d;+ijMWue96kKp?PMH{o#DFbpeh2!>&V!(m%pELcN=ARHVVY;JCD zZEY!vqG?(%7_`;F)6>)C<>l?|Ekfw|`Pnqh`Fw7x!Y8V#jz%Nv<6(u-Xr!vD6F1Rl zbUK|b*9~DhokpWkR=)x(kj-YjUayl!S%lZ?&1SQ#=o%}qx3{;j^vlajqtUpzx#{(K z0I<8en@XiJnasw<20zhC@$XctRsP7=YPC=(^fNIO3e{>ger~l|U9zD_V@P}`nCaUga(5F{U-Q)zEY_)pU+9??d`2p zD*1dq5*0;pFc{b!A?7aQ7{wTqcBN9$G|l7rc)JRMplMpAQX!WZV<&5c)A1i4E*6Us zfubm^C88(_(Zpi0m5sGM!E*lS#YvnQ%TGr|`wg-SvqqU&J6*8BuTASt6r}s5(z>0C?W_#B9W-q>#bHx zk|bx9nQLe^oAEO}9#1}>&*$?P2OQSK|V*{s{`HX04G h;9Oi>TwMNFegPOAN+l|D7jo~NJC)zjIex}ve!Jtm z?>o;k@64QYMg-yE;o;%o;o;%o;rV}nE~u_Tp>R5#+uPf6xqM}1g>`g19zQ=nw_2^M ztE;D{rv+(%%2x5T;y>UxUaeMPb!Jwo z)hdqT@LgFfmcd}KELRf-gMr0jf$2&h5HuQ%<+_^CXfy-@0W@O5N005t<7 zXm4+i(}h8he!t&rHk-|6zu)Ir3Q!D?vGw)!ITX+|T__Yh9*;ty5Q#)utyZhmibNuX zLgDdv3WWkq({q%aPt4bNz1~@Gm~y#nGMT2AHJME1a(ULuUauEKGrR}!Z)lnh27@-6 ztyZf|kF3>dHk&ON49?d&2+Y(mx7$5yeYe~F(>oT4L{h2LmxnM6!!Yd2L#b3M5{bZ7 z0t8^kNRs?K$;jpMcs$b8eovcKc%SBPt=SYg8 zTrL+Y*y(isL}T@Oot5QqIHspK91d1Wyrif{p%G1fNe{QMjwE1gbH zDZ&M4#*UAVnZtZOpUGsVr(`mjd_F&=$ie}cpu62JYbhv`$y%+}ck!)Oi}jfe!?4L` zsh>4LOQll3-_QJoq9`246N$v<;6x&U<2Xf8%pd)Jzf>xPr3VPWwPLT=(`YoG)6Hgc zC=^Pk)9G|N6bhNm=Fc%2ji%S@ft+Oti(s0jNs|0-Z!!f8!vL4|;Km^D$Baf}E|-%? zB;Y9$i6ocH8I4A`O5lGQu-omGN=2{Ng9PjK`bwo@x7(r1fNu;z5S>m(l4L9vQ>j$n z#i&%OSS&`8q)w+>gof2c6h#nZb#?XZ?CkXP^!E0)SS;S(-%r+oN~LmVXXohXXn%hn zMHlr)F#>38I2_Jb9Ys;A)oQg`=S$}z2Iy97x7*yrzyzikp->1o$t;@J*H?%;00co0 zf*_V{il%9rAPAVQ5ClO{G@H#X*Ht!~UC8?eMNxtvmU2(_dOd<5W^y(21rQ2_2L}f# zm1=EmZPwg57!HT+cKhb$=I!n651fvNhlhuUhlhuUhll5n@fRNPH9_3OhF<^x002ov JPDHLkV1n5$F}nZ& literal 0 HcmV?d00001 diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index b2390d04b..e361c9cfe 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -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; diff --git a/Telegram/SourceFiles/settings/settings_information.cpp b/Telegram/SourceFiles/settings/settings_information.cpp index 340e523c2..8b67a6845 100644 --- a/Telegram/SourceFiles/settings/settings_information.cpp +++ b/Telegram/SourceFiles/settings/settings_information.cpp @@ -111,6 +111,40 @@ private: }; } +[[nodiscard]] not_null CreateUploadButton( + not_null parent, + not_null controller) { + const auto background = Ui::CreateChild(parent.get()); + const auto upload = Ui::CreateChild( + 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 container, not_null 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( 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)); diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index 8300eb11c..5906aed48 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -113,7 +113,6 @@ Cover::Cover( setupChildGeometry(); _userpic->switchChangePhotoOverlay(_user->isSelf()); - _userpic->uploadPhotoRequests( ) | rpl::start_with_next([=] { _user->session().api().peerPhoto().upload( diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index b47d48534..271a9949c 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -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 channel) : RippleButton(parent, st::historySilentToggle.ripple) , _st(st::historySilentToggle) diff --git a/Telegram/SourceFiles/ui/special_buttons.h b/Telegram/SourceFiles/ui/special_buttons.h index 56cddef54..d744d07da 100644 --- a/Telegram/SourceFiles/ui/special_buttons.h +++ b/Telegram/SourceFiles/ui/special_buttons.h @@ -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 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 _chosenImages; rpl::event_stream<> _uploadPhotoRequests; };