From 7afb9f1fc8c676f5021ab52e7b6c31e879ebf7a7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 21 Oct 2025 16:34:41 +0400 Subject: [PATCH] Make toggle comments button. --- .../icons/chat/input_comments_expand.png | Bin 0 -> 833 bytes .../icons/chat/input_comments_expand@2x.png | Bin 0 -> 1647 bytes .../icons/chat/input_comments_expand@3x.png | Bin 0 -> 2364 bytes .../icons/chat/input_comments_hide.png | Bin 0 -> 839 bytes .../icons/chat/input_comments_hide@2x.png | Bin 0 -> 1674 bytes .../icons/chat/input_comments_hide@3x.png | Bin 0 -> 2397 bytes .../Resources/icons/chat/input_send_round.png | Bin 0 -> 514 bytes .../icons/chat/input_send_round@2x.png | Bin 0 -> 1012 bytes .../icons/chat/input_send_round@3x.png | Bin 0 -> 1384 bytes Telegram/Resources/langs/lang.strings | 5 + .../chat_helpers/chat_helpers.style | 10 +- .../chat_helpers/compose/compose_features.h | 1 + .../view/controls/compose_controls_common.h | 9 +- .../history_view_compose_controls.cpp | 151 +++++++++++------- .../controls/history_view_compose_controls.h | 13 +- .../stories/media_stories_controller.cpp | 17 +- .../media/stories/media_stories_controller.h | 11 ++ .../media/stories/media_stories_reply.cpp | 6 + .../SourceFiles/media/view/media_view.style | 40 +++-- .../SourceFiles/ui/controls/send_button.cpp | 23 +++ .../SourceFiles/ui/controls/send_button.h | 2 + 21 files changed, 217 insertions(+), 71 deletions(-) create mode 100644 Telegram/Resources/icons/chat/input_comments_expand.png create mode 100644 Telegram/Resources/icons/chat/input_comments_expand@2x.png create mode 100644 Telegram/Resources/icons/chat/input_comments_expand@3x.png create mode 100644 Telegram/Resources/icons/chat/input_comments_hide.png create mode 100644 Telegram/Resources/icons/chat/input_comments_hide@2x.png create mode 100644 Telegram/Resources/icons/chat/input_comments_hide@3x.png create mode 100644 Telegram/Resources/icons/chat/input_send_round.png create mode 100644 Telegram/Resources/icons/chat/input_send_round@2x.png create mode 100644 Telegram/Resources/icons/chat/input_send_round@3x.png diff --git a/Telegram/Resources/icons/chat/input_comments_expand.png b/Telegram/Resources/icons/chat/input_comments_expand.png new file mode 100644 index 0000000000000000000000000000000000000000..2a67d963186765d47d24226ed215c413be2d30bd GIT binary patch literal 833 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 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/chat/input_comments_expand@3x.png b/Telegram/Resources/icons/chat/input_comments_expand@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..4e675a43f0dc2bebc4c68816f9b42ed85b51fd23 GIT binary patch literal 2364 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 U^~C=aumAu607*qoM6N<$f{r5tm;e9( literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/chat/input_comments_hide@3x.png b/Telegram/Resources/icons/chat/input_comments_hide@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e6f6d925c0e5b1b23ac05631cb9e2f3f44e73b38 GIT binary patch literal 2397 zcmV-j38MCiP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*IS@$4Nv%RA>e5n^%YxOAv;4jhJ(e zm;;Czb3hbP3>ZOCOqfs%C@T7<_@IJdco1_|FpHQ4BPwPvW5$FLbH4YxcXrF#IX&^r zp52E%58BgR_1E7s-Cfnyy-7(~zpOWqDc(SGVp!zLm8(F30@(Wa@#BvlKN4Ux`i^DG zmaRd925s83sZ*y;jT$woSFc{ISTQ;#ouOlI-n_Yc_wJoLcW&IcapJ^@%a~g_usj5=ll2X{|Wd*1x3^W$wa-XRjbyD6)Qe`_zM7s1c3$I zW)1>@2D!IA=KAyJ&$Sue=**cjy*1;INKQ`1gzeKo12S=-D%Je?^V_}^{e%P>K8jHx4h&DW2e43cXQ)@oZ3j@g<{q*UR0O4NRw{IT?C^{VoXfFr7 zFbm19UAv@L6owBU9v#E*NYK!%AQ=p+bLY-lfAi+e!SvHp+7={0HGs9VXU|Ha+L%atpqqnL>kCwl8-gapLoqd^$j9xSF!npi41v>AFr720lG3Kc5!>(?)lPFSSt#>u%2dO{W2kav{r(W8fm;^QL-q8&{| z&;UIhh(KP0rb)##ZQ4}Y__)L@@|Xz=(9_-MD0DT6ynxrOgH+22_bs36d#*DEy$2^m}75O!5*5u5YGe#sp1?p?pt`$JQJ(VFT z@{o6wC-oBb!M+&!-lHS zTx`{qme-H2CBx4D!Gj0dG=RYRL16c(73qROt9bF^TBu^hiUuK5RqNKR zZF^e+xn|9pnPlyCEn2kDQ6B_=0?;n!@XSV2b1qr3q(Lxy_Uw8na>iv4a;V}c?D6Br z+QyeJU%Gei?jW90-Lq#;#I)9P*mp0RtT692y8}jvYHDmaGDY zGO^-w=gzf>9X)!~JVRoYRZX{U-2{iPqFT}xPn|j?a+4-aO55n`i6dFutAJRA)vH(M z$dSX+$62jgx6UT8apOjPmg~#X|3XuyOcAK_=g&JTYEG0L6}Pr%xT_d^Aj$Fu^v3E?l?}>#W9)AMXRq zQG~O3Av|No3`e=Tb?b^81)r|W39fJ7zBU)9!M}d}+PimeCtW}FWy+M%fNoBLA;Afv zNXH-Aaw+27yLSR81)P*)7;RZLj?=h?h#^o!i5rGd%AGpLZM+5 zNUDYcOI6aYZ13K^snv=5pNL0?xmK@^961thubsl1SEaWbac&2Lz6^XO&c>FOqhs7= zloUfy%oKT@ItJ1GIwJRhqMCvD7>*-s+Z+gd|NcFiizbT}EwVm6|6aRx&E@qB960dB zix-Fy5O74`cKYUml9YrZ)NkIrDR!ms?Af#C&6~Sw`)g!pfjbu5*|TRG^+-JOw*Vq$ z6>u-ypr?mbt5!8?*(%9Vj~qFY-K|p+fh z^tG6a{hXNHWx5;LGPAP$W}Ce|Jzc-x?1`Rv^W>P=7;7IseY&;yxnD}|_Wb*0<>mI} z?_^>OY;9$iJKni-=jP3u=K1$pR^rrH5rUERMQAG0qjT(@o=OG%Q~ z>lZH)*e37TVX@5XkkSE#)$7;)|N2_|Nap!@w#sYR`?;K*4|j{}Go4kMWBFkQ(?q6c ia-yQ5O{dysGBNybD0*x9rTPXa{5@U$T-G@yGywo?mcYya literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/chat/input_send_round@2x.png b/Telegram/Resources/icons/chat/input_send_round@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..92b3b02c7f00e57fdafc21f827933fa39c3e32ba GIT binary patch literal 1012 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@HF@6^D?4|&|9ro>R$rf=pI@?B>ZlSQU*C%tFYfLx z|Nr;*cY7WYaq-0(i}>BWy|W)3>3n~0Z?h${BeOHdbm@o!&k4HcPMwmHk(o1dW@dVN z`{@b(^X(o^TC}V=B_-w3<;%gr!AFlCExgGtSpVmTVIAv~Q&tuhYhrhQJ3rsPBjVuc zPv5>RyW+Lxm!+j;3I`uTZBv)E%k z{QmwvH8u6jnKPFzUHbn1etWmF@waz(yPtVp+L4r$R9adJbc(x~i1zOvA0NMZ^~&M0 zs;X-KogIy#ya5HjzPwzrlVM#{e0=@AJ(c!#e-5OY#K=e(0G0Uo_&Dr6uwiHAXSEov z$$*MmYWc~)!alP4!9OG!xyEEW|Jd3Serd#Gg0g~NxNHOd)8H*Vhi z{K=C$JB!)ZN!l|wZEb8~VlG>gb94VbJj@>RYU0uJbFJCG zGbg&Gq^KA;D!e|P62G(P=!p{?H+2^H7ffxOacjCxWYe1I8fFH4pFe*te|wA7N9lwb z(_w}gNewS~ZcaIHz`-Q-M3lkJ(9qBmw+wIoSTwo4{rIUUOwcb$J zoa5r*apKd{(-R-_MT%)lzi8x@HcObgDCEMmYu~P~kDrm)5bxsZ+8Wed_>!GXqHecg zYGWi%P{ku7VGTa5=#$LL{pKo#KK}apdSj^V%3U3y{5t%6gA`6MbbHUhz;emc#W5s< z^=*`=#@0ZIe`k$!Q+yWjs7fX&Cku*kxpuNTo!YQLK}<{|5eQsohNox+wdwG97Y9vA zY2;Cy`E&li+yB4*{a*8U=l$>ZSD(9U@!j@$?fvJq=PlnCtc%}&qrI{L3p}vMHX-@q zi+>HpWo3RI9v+^aAHRIDv9=y|w#eZ{&)zwGVc?e#*eEDoov{P+GMMZx8`@@Hu zr?4s&1AQtq>8x>TcJ}P~^Y`!CrPUNEc=P1RlQu6{w^mhFnwp!>pFdywklwx*pFRZz z?33)+xN&30-9IrZe9?7j#l@F-%szxZx*{qfvS$7I)6JoqlS)datanXXQ@g|6YSo%G zE;~Md{yaJ0%=}+Je(c!0_h{i$Vbgr7;wVe|uPW=1#@A>oRv%Wp3E-W-uQ8{w! z)~`p8oTdr7PTObpVJUO4pWnGtr@C}>7PH=1dg)S7^NKZVbW-9Lvp%`LV~54Qti8wb z^72YcOD*J7m?BSo`LdhdYKF@3yLV&tlX;4oo13evs$Lkq`TDgqF;TId ze|ABAeSS*AgK&eQm|Ofo!NKY2>Gt;atfi-gmM>ejXYXFih>ssXp4!_yuQmBf&Vv^( zBErJ9?cS};9h-CT>{;KyKtcI{qM}caA1}U9HObDv;6S>0Y0vBn*RGY7mbzvI`OTa; z^I_f;#sD|BwnNoNGc$8?Os+~W*ZcUK`S9Vx>(|=qvyuwR%iWK?c=INwD~cs%nG{?3 ztcX=oF%8G&`CPV`@c#XK5j!qk-lgVe?%k`)$?0)gEy(TURa#KX*>UVa?jLiiML;C8+;O%cI{eN(55V|Q}##t_wBQ54U}uu zmz#0GHS5q(hxG^BJbHfbH{V4CijvvU7_`*}uzw;o!u-W22H`m5vg;@h`v3fyae20qlcSl!jpcJ}B| zR>@G&>3ZE8uWE3IzU@4cG)Fu(Ac*7bix(3ZR+VKXB{eZMf75w!`9&7DVRLj;)Rjdd z9m!d)6JB5Bnh~NZAf&lzvtFB`Cl4Q=(1#bCzkmP!a^_Z1(q%U{wr|{;plb&+l6umOeS-_A3bpNzZf%1!I zIBeI?zIW(Q)3mPt{cB#lcrkabZ02np+oFz2u6%c378g2i9T*sxw8y@oPyONJ$H_&n zr%j(;&rp@w@uPj^xpRL1)(ck%h2J*)9J=Dgf}c57y%*m(_wrap.get(), _st.like) : nullptr) -, _editStars(_features.editMessageStars - ? Ui::CreateChild(_wrap.get(), _st.editStars) - : nullptr) , _attachToggle(_features.attachments ? Ui::CreateChild(_wrap.get(), _st.attach) : nullptr) @@ -1080,22 +1079,6 @@ void ComposeControls::initLikeButton() { } } -void ComposeControls::initEditStarsButton() { - if (_editStars) { - _editStars->setClickedCallback([=] { - _show->show(Calls::Group::MakeVideoStreamStarsBox({ - .show = _show, - .current = _chosenStarsCount.value_or(0), - .save = crl::guard(_editStars, [=](int count) { - _chosenStarsCount = count; - updateSendButtonType(); - }), - .name = _history ? _history->peer->name() : QString(), - })); - }); - } -} - void ComposeControls::updateLikeParent() { if (_like) { using namespace Controls; @@ -1131,19 +1114,8 @@ void ComposeControls::updateFeatures(ChatHelpers::ComposeFeatures features) { } changed = true; } - if (was.editMessageStars != features.editMessageStars) { - if (!features.editMessageStars) { - delete base::take(_editStars); - _chosenStarsCount = std::nullopt; - } else { - _editStars = Ui::CreateChild( - _wrap.get(), - _st.editStars); - initEditStarsButton(); - } - changed = true; - } - if (was.recordMediaMessage != features.recordMediaMessage) { + if (was.editMessageStars != features.editMessageStars + || was.recordMediaMessage != features.recordMediaMessage) { updateSendButtonType(); } if (was.attachments != features.attachments) { @@ -1158,6 +1130,9 @@ void ComposeControls::updateFeatures(ChatHelpers::ComposeFeatures features) { updateAttachBotsMenu(); changed = true; } + if (was.emojiOnlyPanel != features.emojiOnlyPanel) { + initFieldAutocomplete(); + } if (changed) { updateControlsGeometry(_wrap->size()); } @@ -1221,6 +1196,35 @@ const HistoryItemsList &ComposeControls::forwardItems() const { return _header->forwardItems(); } + +void ComposeControls::setToggleCommentsButton( + rpl::producer state) { + if (!state) { + delete base::take(_commentsShown); + } else { + _commentsShown = Ui::CreateChild( + _wrap.get(), + _st.commentsShow); + _commentsShown->setClickedCallback([=] { + _commentsShownToggles.fire({}); + }); + std::move( + state + ) | rpl::start_with_next([=](ToggleCommentsState value) { + const auto icon = (value == ToggleCommentsState::Shown) + ? &_st.commentsShown + : nullptr; + _commentsShown->setIconOverride(icon, icon); + }, _commentsShown->lifetime()); + } + updateControlsVisibility(); + updateControlsGeometry(_wrap->size()); +} + +rpl::producer<> ComposeControls::commentsShownToggles() const { + return _commentsShownToggles.events(); +} + bool ComposeControls::focus() { if (_wrap->isHidden() || _field->isHidden()) { return false; @@ -1722,6 +1726,19 @@ bool ComposeControls::showRecordButton() const { && !isEditingMessage(); } +bool ComposeControls::showEditStarsButton() const { + return _features.editMessageStars + && !HasSendText(_field) + && !readyToForward() + && !isEditingMessage() + && !shownStarsPerMessage(); +} + +int ComposeControls::shownStarsPerMessage() const { + return _chosenStarsCount.value_or( + _history ? _history->peer->starsPerMessageChecked() : 0); +} + void ComposeControls::clearListenState() { _voiceRecordBar->clearListenState(); } @@ -1860,7 +1877,7 @@ void ComposeControls::updateSubmitSettings() { void ComposeControls::initFieldAutocomplete() { _emojiSuggestions = nullptr; _autocomplete = nullptr; - if (!_history) { + if (!_history || _features.emojiOnlyPanel) { return; } ChatHelpers::InitFieldAutocomplete(_autocomplete, { @@ -2355,10 +2372,21 @@ void ComposeControls::initSendButton() { _send->finishAnimating(); _send->clicks( - ) | rpl::filter([=] { - return (_send->type() == Ui::SendButton::Type::Cancel); - }) | rpl::start_with_next([=] { - cancelInlineBot(); + ) | rpl::start_with_next([=] { + const auto type = _send->type(); + if (type == Ui::SendButton::Type::EditPrice) { + _show->show(Calls::Group::MakeVideoStreamStarsBox({ + .show = _show, + .current = _chosenStarsCount.value_or(0), + .save = crl::guard(_send, [=](int count) { + _chosenStarsCount = count; + updateSendButtonType(); + }), + .name = _history ? _history->peer->name() : QString(), + })); + } else if (type == Ui::SendButton::Type::Cancel) { + cancelInlineBot(); + } }, _send->lifetime()); const auto send = crl::guard(_send.get(), [=](Api::SendOptions options) { @@ -2764,6 +2792,8 @@ auto ComposeControls::computeSendButtonType() const { return (video && _recordAvailability == both) ? Type::Round : Type::Record; + } else if (showEditStarsButton()) { + return Type::EditPrice; } return (_mode == Mode::Normal) ? Type::Send : Type::Schedule; } @@ -2792,13 +2822,10 @@ void ComposeControls::updateSendButtonType() { ? _slowmodeSecondsLeft.current() : 0; }(); - const auto peer = _history ? _history->peer.get() : nullptr; - const auto stars = _chosenStarsCount.value_or( - peer ? peer->starsPerMessageChecked() : 0); _send->setState({ .type = type, .slowmodeDelay = delay, - .starsToSend = stars, + .starsToSend = shownStarsPerMessage(), }); _send->setDisabled(_sendDisabledBySlowmode.current() && (type == Type::Send @@ -2812,10 +2839,16 @@ void ComposeControls::finishAnimating() { } void ComposeControls::updateControlsGeometry(QSize size) { - // (_attachToggle|_replaceMedia) (_sendAs) -- _inlineResults ------ _tabbedPanel -- _fieldBarCancel + // (_commentsShown) (_attachToggle|_replaceMedia) (_sendAs) -- _inlineResults ------ _tabbedPanel -- _fieldBarCancel // (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_botCommandStart) _tabbedSelectorToggle _send const auto fieldWidth = size.width() + - (_commentsShown + ? (_st.padding.left() + + _commentsShown->width() + + _st.padding.right() + + _st.commentsSkip) + : 0) - _st.padding.left() - (_attachToggle ? _attachToggle->width() : 0) - (_sendAs ? _sendAs->width() : 0) @@ -2823,7 +2856,6 @@ void ComposeControls::updateControlsGeometry(QSize size) { - _send->width() - _tabbedSelectorToggle->width() - (_likeShown ? _like->width() : 0) - - (_editStars ? _editStars->width() : 0) - (_botCommandShown ? _botCommandStart->width() : 0) - (_silent ? _silent->width() : 0) - (_scheduled ? _scheduled->width() : 0) @@ -2841,6 +2873,13 @@ void ComposeControls::updateControlsGeometry(QSize size) { const auto buttonsTop = size.height() - _st.attach.height; auto left = _st.padding.left(); + if (_commentsShown) { + _commentsShown->moveToLeft(left, buttonsTop); + left += _commentsShown->width() + + _st.padding.right() + + _st.commentsSkip + + _st.padding.left(); + } if (_replaceMedia) { _replaceMedia->moveToLeft(left, buttonsTop); } @@ -2877,10 +2916,6 @@ void ComposeControls::updateControlsGeometry(QSize size) { } } } - if (_editStars) { - _editStars->moveToRight(right, buttonsTop); - right += _editStars->width(); - } if (_botCommandStart) { _botCommandStart->moveToRight(right, buttonsTop); if (_botCommandShown) { @@ -2912,9 +2947,6 @@ void ComposeControls::updateControlsVisibility() { if (_like) { _like->setVisible(_likeShown); } - if (_editStars) { - _editStars->show(); - } if (_ttlInfo) { _ttlInfo->show(); } @@ -2930,6 +2962,9 @@ void ComposeControls::updateControlsVisibility() { if (_scheduled) { _scheduled->setVisible(!isEditingMessage()); } + if (_commentsShown) { + _commentsShown->show(); + } } bool ComposeControls::updateLikeShown() { @@ -3047,13 +3082,19 @@ void ComposeControls::updateAttachBotsMenu() { void ComposeControls::paintBackground(QPainter &p, QRect full, QRect clip) { if (_backgroundRect) { - //p.setCompositionMode(QPainter::CompositionMode_Source); - //p.fillRect(clip, Qt::transparent); - //p.setCompositionMode(QPainter::CompositionMode_SourceOver); - //_backgroundRect->paint(p, _wrap->rect()); auto hq = PainterHighQualityEnabler(p); p.setBrush(_st.bg); p.setPen(Qt::NoPen); + const auto r = _st.radius; + if (_commentsShown) { + p.drawRoundedRect(_commentsShown->geometry().marginsAdded( + { _st.padding.left(), 0, _st.padding.right(), 0 }), r, r); + full.setLeft(full.left() + + _commentsShown->width() + + _st.padding.left() + + _st.padding.right() + + _st.commentsSkip); + } p.drawRoundedRect(full, _st.radius, _st.radius); } else { p.fillRect(clip, _st.bg); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h index aa3f9c8d75..246ae1a694 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -137,6 +137,7 @@ public: using ReplyNextRequest = Controls::ReplyNextRequest; using FieldHistoryAction = Ui::InputField::HistoryAction; using Mode = ComposeControlsMode; + using ToggleCommentsState = Controls::ToggleCommentsState; ComposeControls( not_null parent, @@ -159,6 +160,9 @@ public: [[nodiscard]] rpl::producer height() const; [[nodiscard]] int heightCurrent() const; + void setToggleCommentsButton(rpl::producer state); + [[nodiscard]] rpl::producer<> commentsShownToggles() const; + bool focus(); [[nodiscard]] bool focused() const; [[nodiscard]] rpl::producer focusedValue() const; @@ -284,7 +288,6 @@ private: void initVoiceRecordBar(); void initKeyHandler(); void initLikeButton(); - void initEditStarsButton(); void updateLikeParent(); void updateSubmitSettings(); void updateSendButtonType(); @@ -318,7 +321,9 @@ private: void createTabbedPanel(); void setTabbedPanel(std::unique_ptr panel); - bool showRecordButton() const; + [[nodiscard]] bool showRecordButton() const; + [[nodiscard]] bool showEditStarsButton() const; + [[nodiscard]] int shownStarsPerMessage() const; bool updateBotCommandShown(); bool updateLikeShown(); @@ -393,9 +398,10 @@ private: const std::shared_ptr _send; Ui::IconButton *_like = nullptr; - Ui::IconButton *_editStars = nullptr; std::optional _chosenStarsCount; + Ui::IconButton *_commentsShown = nullptr; Ui::IconButton *_attachToggle = nullptr; + Ui::AbstractButton *_starsReaction = nullptr; std::unique_ptr _replaceMedia; const not_null _tabbedSelectorToggle; rpl::producer _fieldCustomPlaceholder; @@ -434,6 +440,7 @@ private: rpl::event_stream _replyNextRequests; rpl::event_stream<> _focusRequests; rpl::event_stream<> _showScheduledRequests; + rpl::event_stream<> _commentsShownToggles; rpl::variable _recording; rpl::variable _hasSendText; diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index eca3af3a7e..d6ee77365b 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_stories.h" #include "history/view/reactions/history_view_reactions_strip.h" +#include "history/view/controls/compose_controls_common.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "media/stories/media_stories_caption_full_view.h" @@ -452,7 +453,7 @@ void Controller::initLayout() { QSize(contentWidth, headerHeight)); } layout.controlsWidth = std::max( - layout.content.width(), + layout.content.width() + st::storiesControlsExtend * 2, st::storiesControlsMinWidth); layout.controlsBottomPosition = QPoint( (size.width() - layout.controlsWidth) / 2, @@ -1701,6 +1702,20 @@ void Controller::unfocusReply() { _wrap->setFocus(); } +rpl::producer Controller::commentsStateValue() const { + return _commentsState.value(); +} + +void Controller::setCommentsShownToggles(rpl::producer<> toggles) { + _commentsState = std::move( + toggles + ) | rpl::map([=] { + return (_commentsState.current() == CommentsState::Shown) + ? CommentsState::Hidden + : CommentsState::Shown; + }); +} + void Controller::shareRequested() { const auto show = _delegate->storiesShow(); if (auto box = PrepareShareBox(show, _shown, true)) { diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 151dac8f98..458a1956c9 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -33,6 +33,10 @@ struct FileOrigin; class DocumentMedia; } // namespace Data +namespace HistoryView::Controls { +enum class ToggleCommentsState; +} // namespace HistoryView::Controls + namespace HistoryView::Reactions { struct ChosenReaction; enum class AttachSelectorResult; @@ -75,6 +79,8 @@ enum class ReactionsMode; class StoryAreaView; struct RepostClickHandler; +using CommentsState = HistoryView::Controls::ToggleCommentsState; + enum class HeaderLayout { Normal, Outside, @@ -170,6 +176,9 @@ public: [[nodiscard]] const Data::StoryViews &views(int limit, bool initial); [[nodiscard]] rpl::producer<> moreViewsLoaded() const; + [[nodiscard]] rpl::producer commentsStateValue() const; + void setCommentsShownToggles(rpl::producer<> toggles); + void unfocusReply(); void shareRequested(); void deleteRequested(); @@ -320,6 +329,8 @@ private: mutable std::vector _areas; mutable rpl::variable _weatherInCelsius; + rpl::variable _commentsState; + std::vector _cachedSourcesList; int _cachedSourceIndex = -1; bool _showingUnreadSources = false; diff --git a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp index a4185bef50..15513a3d36 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp @@ -115,6 +115,7 @@ namespace { .autocompleteCommands = false, .recordMediaMessage = !videoStream, .editMessageStars = videoStream, + .emojiOnlyPanel = videoStream, }; } @@ -836,6 +837,11 @@ void ReplyArea::show( _data = data; if (streamChanged) { _controls->updateFeatures(Features(_data.videoStream)); + _controls->setToggleCommentsButton(_data.videoStream + ? _controller->commentsStateValue() + : nullptr); + _controller->setCommentsShownToggles( + _controls->commentsShownToggles()); } if (!peerChanged) { if (_data.peer) { diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index d2da944da3..af3b568422 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -457,6 +457,7 @@ storiesHeaderRepostWidthMin: 40px; storiesShadowTop: icon{{ "mediaview/shadow_bottom-flip_vertical", windowShadowFg }}; storiesShadowBottom: mediaviewShadowBottom; storiesControlsMinWidth: 280px; +storiesControlsExtend: 4px; storiesFieldMargin: margins(0px, 18px, 0px, 12px); storiesSideSkip: 145px; storiesCaptionFull: FlatLabel(defaultFlatLabel) { @@ -479,24 +480,27 @@ storiesComposeRipple: RippleAnimation(defaultRippleAnimation) { color: groupCallMembersBgRipple; } storiesAttach: IconButton(historyAttach) { + width: 42px; height: 42px; icon: icon {{ "chat/input_attach", storiesComposeGrayIcon }}; iconOver: icon {{ "chat/input_attach", storiesComposeGrayIcon }}; - rippleAreaPosition: point(2px, 1px); + rippleAreaPosition: point(1px, 1px); ripple: storiesComposeRippleLight; } storiesLike: IconButton(storiesAttach) { icon: icon {{ "chat/input_like", storiesComposeGrayIcon }}; iconOver: icon {{ "chat/input_like", storiesComposeGrayIcon }}; } -storiesEditStars: IconButton(storiesAttach) { - icon: icon{{ "chat/input_paid", storiesComposeGrayIcon }}; - iconOver: icon{{ "chat/input_paid", storiesComposeGrayIcon }}; -} storiesRecordVoice: icon {{ "chat/input_record", storiesComposeGrayIcon }}; storiesRecordVoiceOver: icon {{ "chat/input_record", storiesComposeGrayIcon }}; storiesRecordRound: icon {{ "chat/input_video", storiesComposeGrayIcon }}; storiesRecordRoundOver: icon {{ "chat/input_video", storiesComposeGrayIcon }}; +storiesEditPrice: icon{{ "chat/input_paid", storiesComposeGrayIcon }}; +storiesEditPriceOver: icon{{ "chat/input_paid", storiesComposeGrayIcon }}; +//storiesEditStars: IconButton(storiesAttach) { +// icon: storiesEditPrice; +// iconOver: storiesEditPriceOver; +//} storiesRemoveSet: IconButton(stickerPanRemoveSet) { icon: icon {{ "simple_close", storiesComposeGrayIcon }}; iconOver: icon {{ "simple_close", storiesComposeGrayIcon }}; @@ -689,8 +693,9 @@ storiesBoxInputField: InputField(defaultComposeFilesField) { storiesComposeControls: ComposeControls(defaultComposeControls) { bg: storiesComposeBg; radius: 21px; - padding: margins(10px, 8px, 2px, 6px); + padding: margins(1px, 8px, 1px, 6px); field: InputField(historyComposeField) { + textMargins: margins(2px, 0px, 2px, 0px); textFg: storiesComposeWhiteText; textBg: storiesComposeBg; placeholderFg: storiesComposeGrayText; @@ -698,23 +703,38 @@ storiesComposeControls: ComposeControls(defaultComposeControls) { placeholderFgError: storiesComposeGrayText; menu: storiesPopupMenu; } + fieldLeft: 10px; send: SendButton(historySend) { - sendIconPosition: point(10px, 10px); + sendIconPosition: point(9px, 9px); + sendIconFillPadding: 5px; inner: IconButton(storiesAttach) { - icon: icon {{ "chat/input_send", storiesComposeBlue }}; - iconOver: icon {{ "chat/input_send", storiesComposeBlue }}; + width: 42px; + height: 42px; + icon: icon {{ "chat/input_send_round", windowFgActive }}; + iconOver: icon {{ "chat/input_send_round", windowFgActive }}; + rippleAreaSize: 40px; + rippleAreaPosition: point(1px, 1px); } record: storiesRecordVoice; recordOver: storiesRecordVoiceOver; round: storiesRecordRound; roundOver: storiesRecordRoundOver; + editPrice: storiesEditPrice; + editPriceOver: storiesEditPriceOver; sendDisabledFg: storiesComposeGrayText; } attach: storiesAttach; emoji: storiesAttachEmoji; like: storiesLike; liked: icon{}; - editStars: storiesEditStars; + commentsShow: IconButton(storiesAttach) { + icon: icon {{ "chat/input_comments_expand", storiesComposeGrayIcon }}; + iconOver: icon {{ "chat/input_comments_expand", storiesComposeGrayIcon }}; + } + commentsShown: icon {{ "chat/input_comments_hide", storiesComposeGrayIcon }}; + commentsSkip: 8px; + starsInactiveFg: storiesComposeGrayIcon; + starsSkip: 8px; suggestions: EmojiSuggestions(defaultEmojiSuggestions) { dropdown: InnerDropdown(emojiSuggestionsDropdown) { animation: PanelAnimation(defaultPanelAnimation) { diff --git a/Telegram/SourceFiles/ui/controls/send_button.cpp b/Telegram/SourceFiles/ui/controls/send_button.cpp index 7c90cfc03a..1cec209646 100644 --- a/Telegram/SourceFiles/ui/controls/send_button.cpp +++ b/Telegram/SourceFiles/ui/controls/send_button.cpp @@ -142,6 +142,7 @@ void SendButton::paintEvent(QPaintEvent *e) { break; case Type::Schedule: paintSchedule(p, over); break; case Type::Slowmode: paintSlowmode(p); break; + case Type::EditPrice: paintEditPrice(p, over); break; } } @@ -194,6 +195,14 @@ void SendButton::paintCancel(QPainter &p, bool over) { void SendButton::paintSend(QPainter &p, bool over) { const auto &sendIcon = over ? _st.inner.iconOver : _st.inner.icon; + if (const auto padding = _st.sendIconFillPadding; padding > 0) { + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(st::windowBgActive); + p.drawEllipse( + QRect(_st.sendIconPosition, sendIcon.size()).marginsAdded( + { padding, padding, padding, padding })); + } if (isDisabled()) { const auto color = st::historyRecordVoiceFg->c; sendIcon.paint(p, _st.sendIconPosition, width(), color); @@ -309,4 +318,18 @@ QPoint SendButton::prepareRippleStartPosition() const { return real - QPoint((width() - size) / 2, y); } +void SendButton::paintEditPrice(QPainter &p, bool over) { + if (!isDisabled()) { + paintRipple( + p, + (width() - _st.inner.rippleAreaSize) / 2, + _st.inner.rippleAreaPosition.y()); + } + + const auto &icon = (isDisabled() || !over) + ? _st.editPrice + : _st.editPriceOver; + icon.paintInCenter(p, rect()); +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/controls/send_button.h b/Telegram/SourceFiles/ui/controls/send_button.h index b1483bbc44..801f82c1d1 100644 --- a/Telegram/SourceFiles/ui/controls/send_button.h +++ b/Telegram/SourceFiles/ui/controls/send_button.h @@ -29,6 +29,7 @@ public: Round, Cancel, Slowmode, + EditPrice, }; struct State { Type type = Type::Send; @@ -71,6 +72,7 @@ private: void paintSend(QPainter &p, bool over); void paintSchedule(QPainter &p, bool over); void paintSlowmode(QPainter &p); + void paintEditPrice(QPainter &p, bool over); void paintStarsToSend(QPainter &p, bool over); const style::SendButton &_st;