From fdce4bada78e1a11a119b0d8f67a2faf1982dde2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 29 May 2025 14:56:49 +0400 Subject: [PATCH] Implement nice topic mode editing. --- .../animations/edit_peers/topics.tgs | Bin 0 -> 8162 bytes .../animations/edit_peers/topics_list.tgs | Bin 0 -> 2613 bytes .../animations/edit_peers/topics_tabs.tgs | Bin 0 -> 3808 bytes Telegram/Resources/langs/lang.strings | 7 + .../Resources/qrc/telegram/animations.qrc | 3 + .../boxes/peers/edit_peer_info_box.cpp | 58 +++-- .../boxes/peers/toggle_topics_box.cpp | 226 ++++++++++++++++++ .../boxes/peers/toggle_topics_box.h | 20 ++ Telegram/SourceFiles/data/data_channel.cpp | 2 +- Telegram/SourceFiles/data/data_session.cpp | 7 +- .../SourceFiles/history/history_widget.cpp | 16 +- .../view/history_view_chat_section.cpp | 16 +- Telegram/SourceFiles/info/info.style | 10 + .../info_statistics_inner_widget.cpp | 1 - Telegram/SourceFiles/mtproto/scheme/api.tl | 1 + .../SourceFiles/settings/settings_common.cpp | 11 +- .../SourceFiles/settings/settings_common.h | 3 +- .../window/window_session_controller.cpp | 21 +- Telegram/cmake/td_ui.cmake | 2 + Telegram/lib_lottie | 2 +- 20 files changed, 373 insertions(+), 33 deletions(-) create mode 100644 Telegram/Resources/animations/edit_peers/topics.tgs create mode 100644 Telegram/Resources/animations/edit_peers/topics_list.tgs create mode 100644 Telegram/Resources/animations/edit_peers/topics_tabs.tgs create mode 100644 Telegram/SourceFiles/boxes/peers/toggle_topics_box.cpp create mode 100644 Telegram/SourceFiles/boxes/peers/toggle_topics_box.h diff --git a/Telegram/Resources/animations/edit_peers/topics.tgs b/Telegram/Resources/animations/edit_peers/topics.tgs new file mode 100644 index 0000000000000000000000000000000000000000..a5552a4acb86a3ec730cbd662b9e8b03ea0338fd GIT binary patch literal 8162 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%0AEQ zA!$YoeEd&<&Pm%H>h}+;zoU)$lA(m_#VuC}PlV}6LhetuyB%N1LeptyU{RypMHB8Y z)i>V5i<4Uid}4|_2R&A80TZEp{})nIp?&RoE54uKD`3r*U#u+qlo>wr6@x3oK z(YjJ=^E+tT;znvJwToy99b&+5R z8pRyRJ-}~2?qXXz-bz$^MZVyq`CK6@C>J{s=f>6LUWBO5xS@&k_PKcn)~;P4j~E0K z4bZ2}|7FogQu&hegMQEabO4=;Cb+>0^h5O@G>S$KEOK&S26KlUhoZkCK>4xP-bZ3_Ft0tY&I&H+SJE*?5X6`ud&! ze;aoJyc*y?&!O0zwHn^U>waHmd`Gj`Gl=)EKsZ{OWd@+$Us%KK-A8iNOL54Oa)R=l zZY$0baM>i3N@tiq5z5)|TCph;H2L>R8kv&LvC1&G+cpwIVg8%L^OF9C{_Gn;j3~L| zp-S*-laZQV21r6hVokL|GrBdRLLc0tmzy#ZB0vfT{jJBZ@n^o?%Y&n?o{;4bY4czj zn-|&!%X|v&XWIHlrEId(SIx`L>3?PN?3c~`+eno-`;d?eH9+fS?KlrMsKD`DCtV*z z-}(Je9P?Q0_WJUNEMdzzA-_~UGRd9Pbg{6s{e3UX9V9uT==+0XHwN3pfEOAaJ!#6Az&XSikkij@PlHyFM{=VR5$Z7zJUFD-W`t0OTEN664M5+mKd?SR8JhJ_hNs`>><2hM{t z1(M^g9j@F-`^BjBM^%<3Jo1`ArG)pAz;-VmLygxW6eEB|?E`6S<@^D?V~} zY?15tH7@gpSh(WuGM?HZS%Rvj8N$0Hom2ZS|o7DAl}x?rUl%5W^~==<#Ufn)z) z91K7hiC%#lmDL;>>!FxXrXrT9CBw~L&gN z|D7+UJF3k!b%XDy{%z`Chh)W@Z2px_tNmdejfa%d(_$!-M%6{ z8?Z37a3?ip?&w~2+#3uJ>UYV5+2=;q8RHsUK}W*B0d|)?3xPqK=q22nno>3!}^&ZLLNZtk1=g3uCN)A;txYAJgJuaZnd2#dC6* ziE^3g=DXRX;?50Tb>T7o)kJX#VFDOZj)&1@VY*6VWyqDTAR5%&b=JZ2mzIoRp-~Yv zZgTwERW;uXDa-H%;d^AY5Ha3=HR7^9Nzma>GXHU+kQnA!DmRbbM!5hz{F`CkYAje0 zE`|aqjW&?qq4G5YQm>5=o6AGOMMtU>_OW=_b@2Pq7GPNIP2Y#7G zUuh+&Gc+^WUPoUkV$FyU>Z4qnPpy}H7-0whHwY;lu;s9WBj0L!cstQp^>oR`uULYY-#0zPqq((7V$YFCFb zcJ*RaVwn@I(D){;K`&@(yJIIpnRH`tGcxt0{rFka#Q(r6lDZLH!ekAOdT?5{OMzSs ztmmv{BFYqg_qKKE`+Vcq^|^D1UyMj)7M%eE2Rd)jkai%-l%258`C-)^B_h$$Qe_!X z3B#^8;OG#^C>>BdE$5g1=@L~-IlE#MEK%UriYHD`J)(f;8gF4N|BeumDa|eM=2#s^ z`^UgYyTZLJuOI~uKDr$EtS9vmPU`Y*UaL!KkfzTM<2>G-xQVPaLtQRsg0uNi+a}p& z*bJ>3x^?ePv?Q@;@3$dsQ`xn0)+3vG_)CQH1+;=?D RE&BXqaAzAllchOmHx$0PVz3ncX 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 XkKh*hZ=sBOz7zigZ~PuXYBc}=ISB++ literal 0 HcmV?d00001 diff --git a/Telegram/Resources/animations/edit_peers/topics_tabs.tgs b/Telegram/Resources/animations/edit_peers/topics_tabs.tgs new file mode 100644 index 0000000000000000000000000000000000000000..3a240b4c62e16edd0c96f7964c241498ae32e8b0 GIT binary patch literal 3808 zcmV<64j=I!iwFP!000021MM8kZX7x8SAssP3VKWB+sy=o&-LB5O z6sxPd)tQ6eTliJ@@F&1Zi`Dz|dvguF_P2NY^~G*|bGf~}x`ghRmzS$EXuaO;HhaMS z=IaW|&sKljUf=ykLW7U%FPkk_J{Y;SEC>#M(rT?ySg9~lbL3e}sa$0oYB0m`(Cb(x6{$W?dJWAaPPzxHSrVCID9w$!%##o#LaYzum2m%fXgRCW$RiHiUO z$iO64gA>2NIqPW4>iFK!emVrCPFM|l&S&X6*Nf2ML;WP45n(7iv#qtP!R!EFsEvE0Cxnl zs+JpI60r)G;4?0Paj*n1S3mTDn(ELy=cr&9Xao&oi7qhjr_DPH3mah#eFUacd#hno zO(oKhU|VP{u|)O+JBc*}LrW@Ah);CRAbu)=_JGNzXCB_h@uAe(02B<+7Z%)lD)AuA zK(mX$W0y)a=m?fX%e^Gl0Sy-0rV=?AD)G|LY%OAh5{Dym$z8D|}82be84;KFf1yBg3F!GMd#V7;Co zIe)Cq_S;VzG|6o0*ZcRc6xiDLV0_=MKkhd7BH8BaYbb_4X#J_}KR4TVn^)Llcc9DL zk1HCY-UmQ{;Xj2t#BEapTLYBw?s9QWr8La%S06tfz`w`s;%i&FbA5BvnCw0#IeA?!9jDUMjFg3+VH=DF> zH|f7`)|Z>@bc3Ew;$AH6*J26r9I&D_rfd;G>%m5vWMx$T zHLPakm(-jZew#wPNOvRMMF5{H*`}53-#%SjeB2O|9wpm5UP7_@Z)%{JA0&KVvGffH z&FTvZe_1Fhga_TaQka)a?L6 zv}tT)BotUZOzjCc3XYBhWJ^>?5S=@q18%JhgaoJ&;Ad_{jdFhmv-~gX88yW%E9*>=yQ!is>*?gE zh}DX*y80|Q;%>Eds;r}~b_>eds;oj?34+HYw}MobPti$bLsCWrWK|JLdwf!?p!CQZ zSv~rsn<}YhPbaDb$rmMk1|`+cp`@-=(tlrFZZ6i_SHFGQ?{9Aosp_-155%u0yADP^ z*=tBBu*lZLozE>1I>*|#GO)l5oQbIZW}1W&3v`LCWsLECefbJtoqak9bk>R2b> z--!ncKXPVD{m{|$A|uHuozwB``&REf1?FN3TjIvqOXUs(Ic-!F?X#|qd^!rK+A7*9 zF~H`6TL|@9-gKg>OD)Hh0aINXxl}59C~#~&1%P8SLc}0;8_0zj37Xw(Mn=;rT3v6l zOVgaVyfa2&w=lA@P~&k^_j(rlUZQDE`@$4kEK59EV&@{~tHsK}cch>ru^6MH;8I{H zt@pu@PZ1S?0|nk?k72YFxld1%Cfx)BJV*>1!yfNA6xyp`(5*3^1EIYpP@924qFm?a z@@NN&7Arj>sc=XKo?yOKU=j)iZ~!m^fDAFcgcG0719@K5f!jBTr+6hPeHx#rE5v2QX$EO>Af%-LY+ z`b^uAqs-8(NhnaTx~X1GfG$C#N9kGj4!v}MB+H(Xe4|0e7Bqwa%cAH9z5}6K77$a! zsqrF%1y#~zmNW^pS?uV!JVL9n5uz9|ApQ}(7URfBRVIo_W{M99v0fBn{jd;s?Hc0@ z_|8(+vIORmth49!Wm{dFV3Y^Z-dZ6>LD(Asm}rUQn>ae771@AwPqa8qvKB{iC0e>d zOxYF!m&#;t^suCDIw^(H3))sjZMCc2W2CDTlcv~}IU=FeHc@N*7`AEU4=p8ID3)6S zO}ek^>Xj!OD;*i{1B)q;xvQm0_o@?*cQ>e#46*Qn1S z*)%U#I43!b&Q6R^K9c(7BkAA%*k66#yn4O9K>n<^n;Y`#kLO=>%EAT>vP8G;r@6H0 zEqDhqZ;{qDJIYwcRaJyGw{2ThZCl(`)YbO^Z(N6-)FJdPqPpN&1Yr!8jkOFlO-oD0 zgLTjEmf#%ty5A}afZ2J9#ZeYaSY;M`n+b1c#~K*8D#Jo(FkxPdO32N%z>8>bjz z)X1g`DXQZ>sVXu9xmN+`QTylL9x?uB6uSoSJ4PY7u*;=Q_=Ai+v9hPNvW*dZ$kI|Y>zJht%a#_f?~d8nc6w$ZV$T6>rQskvoW$;q zwk7^7+Y+a?1>F{*BRVgf83u|2AV>ZUKeA5M&rK(+8hTH+0QDo|LQtLJ1Q{Y8rUHi$ z2(w2n_m-f^Skx+*r{HR5g=^Bl2b z7e3kZz`-mgxI2cq<-?2(6bxc=8K21H(lM9L3G?fn<;mA<>sp?6Q;t7=@{{G5(pb;n z8z$Z|tmS9R?OFhi3e|KOy4m`-(lHmTta-2_3FTlL=CFru ztfep0(54^4kmp!IP1^~oW}JqE34KVu8_8#|%x*IIiZds0hJIb^?;GRqi|zNL>GzH0 z_oLwt#qNj3?1!UP-z>7xJjUut*z@>3^Uk9pH7+PSrCNWt-_pBfrc>h2TF^{^$sxx^A{n%fzTxbx&=731?V zkXM}M?lI($LCp2WeAeD8PO9tUK!^jU-?~0V%!;-#q(C_8ASfp1v-D9T$fAIdDiAhR zrD=<2G71u*GZBa6#V*Q={r^_G4s5cjR0iQ;pftwxoOG-P+KyD2?O^kqFd{r0WUE_b ztNYfgI=rxHX6!A8_BhH}U*pslJfp&K2p;df_^j$#*jWQ7*twy|*vlPT#@--5aHZDL zS5nDh9-y9FSK}C$HV@N|-jG(ZUK083ye89r{OuRM1~I_0#vGk54tF;J(@j@tov*gg zkJq7GX2C|v89WIz;77Q+IgpyN?-?QNk;9t|F z^w^$G)K5OJ$M(Sf`u1)X6gXMJ&Xdx0f;*J;^F3L_QEIA9NipTIQ)3g_ZO7L9{MU*R&rGN!W1=dv#VKJ}Dkr8BSfbI= z?Qhf01dmr`lbYg`%Q*3=wWbNvqmUjYwAj|;80!?tG^hJtb?aT)8=t)Y4h#G5ei|>2 zzxpQpyg9Q=TX2=T4}K}WsSO7$9o-4;0^nrNsdSoORcZ6$ZOVn<*Qv1;9anUM?56G$%=NJ4b(Q>0hnDKeq$+>5FrYXnj-}GT3I=|&guVb#U|4ES8qyRwgB5hz zP-ZSg!6m(1gKy(luEmHPW)LBy`$2lVEvHv?lm{ytM=-*%du$6*D#M5U<(yK#b zJV~VgC&N9`8eNGeHG$R_~$?^8|jECf%$tf<%u5n_vIbTCm%15*bAS( zPWG_DP>X3;KlS4d;I2ISpjm0?../../animations/hello_status.tgs ../../animations/starref_link.tgs ../../animations/media_forbidden.tgs + ../../animations/edit_peers/topics.tgs + ../../animations/edit_peers/topics_tabs.tgs + ../../animations/edit_peers/topics_list.tgs ../../animations/dice/dice_idle.tgs ../../animations/dice/dart_idle.tgs diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 7cfffe5c15..c53412162a 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/edit_peer_requests_box.h" #include "boxes/peers/edit_peer_reactions.h" #include "boxes/peers/replace_boost_box.h" +#include "boxes/peers/toggle_topics_box.h" #include "boxes/peers/verify_peers_box.h" #include "boxes/peer_list_controllers.h" #include "boxes/edit_privacy_box.h" // EditDirectMessagesPriceBox @@ -377,6 +378,7 @@ private: std::optional description; std::optional hiddenPreHistory; std::optional forum; + std::optional forumTabs; std::optional autotranslate; std::optional signatures; std::optional signatureProfiles; @@ -481,6 +483,7 @@ private: std::optional _historyVisibilitySavedValue; std::optional _typeDataSavedValue; std::optional _forumSavedValue; + std::optional _forumTabsSavedValue; std::optional _autotranslateSavedValue; std::optional _signaturesSavedValue; std::optional _signatureProfilesSavedValue; @@ -1104,21 +1107,30 @@ void Controller::fillDirectMessagesButton() { void Controller::fillForumButton() { Expects(_controls.buttonsLayout != nullptr); + _forumSavedValue = _peer->isForum(); + _forumTabsSavedValue = !_peer->isChannel() + || !_peer->isForum() + || _peer->asChannel()->useSubsectionTabs(); + + const auto changes = std::make_shared>(); + const auto label = [=] { + return !*_forumSavedValue + ? tr::lng_manage_monoforum_off(tr::now) + : *_forumTabsSavedValue + ? tr::lng_edit_topics_tabs(tr::now) + : tr::lng_edit_topics_list(tr::now); + }; const auto button = _controls.forumToggle = _controls.buttonsLayout->add( EditPeerInfoBox::CreateButton( _controls.buttonsLayout, tr::lng_forum_topics_switch(), - rpl::single(QString()), + changes->events_starting_with({}) | rpl::map(label), [] {}, st::manageGroupTopicsButton, { &st::menuIconTopics })); - const auto unlocks = std::make_shared>(); - button->toggleOn( - rpl::single(_peer->isForum()) | rpl::then(unlocks->events()) - )->toggledValue( - ) | rpl::start_with_next([=](bool toggled) { - if (_controls.forumToggleLocked && toggled) { - unlocks->fire(false); + + button->setClickedCallback(crl::guard(this, [=] { + if (!*_forumSavedValue && _controls.forumToggleLocked) { if (_discussionLinkSavedValue && *_discussionLinkSavedValue) { ShowForumForDiscussionError(_navigation); } else { @@ -1130,13 +1142,21 @@ void Controller::fillForumButton() { Ui::Text::RichLangValue)); } } else { - _forumSavedValue = toggled; - if (toggled) { - _savingData.hiddenPreHistory = false; - } - refreshHistoryVisibility(); + _navigation->uiShow()->show(Box( + Ui::ToggleTopicsBox, + *_forumSavedValue, + *_forumTabsSavedValue, + crl::guard(this, [=](bool topics, bool topicsTabs) { + _forumSavedValue = topics; + _forumTabsSavedValue = !topics || topicsTabs; + if (topics) { + _savingData.hiddenPreHistory = false; + } + changes->fire({}); + refreshHistoryVisibility(); + }))); } - }, _controls.buttonsLayout->lifetime()); + })); refreshForumToggleLocked(); } @@ -2143,6 +2163,7 @@ bool Controller::validateForum(Saving &to) const { return true; } to.forum = _forumSavedValue; + to.forumTabs = _forumTabsSavedValue; return true; } @@ -2589,8 +2610,13 @@ void Controller::togglePreHistoryHidden( void Controller::saveForum() { const auto channel = _peer->asChannel(); + const auto nowForum = _peer->isForum(); + const auto nowForumTabs = !channel + || !nowForum + || channel->useSubsectionTabs(); if (!_savingData.forum - || *_savingData.forum == _peer->isForum()) { + || (*_savingData.forum == nowForum + && *_savingData.forumTabs == nowForumTabs)) { return continueSave(); } else if (!channel) { const auto saveForChannel = [=](not_null channel) { @@ -2608,7 +2634,7 @@ void Controller::saveForum() { _api.request(MTPchannels_ToggleForum( channel->inputChannel, MTP_bool(*_savingData.forum), - MTP_bool(channel->flags() & ChannelDataFlag::ForumTabs) + MTP_bool(*_savingData.forum && *_savingData.forumTabs) )).done([=](const MTPUpdates &result) { const auto weak = base::make_weak(this); channel->session().api().applyUpdates(result); diff --git a/Telegram/SourceFiles/boxes/peers/toggle_topics_box.cpp b/Telegram/SourceFiles/boxes/peers/toggle_topics_box.cpp new file mode 100644 index 0000000000..b2fed66b25 --- /dev/null +++ b/Telegram/SourceFiles/boxes/peers/toggle_topics_box.cpp @@ -0,0 +1,226 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "boxes/peers/toggle_topics_box.h" + +#include "lang/lang_keys.h" +#include "lottie/lottie_icon.h" +#include "settings/settings_common.h" +#include "ui/effects/ripple_animation.h" +#include "ui/layers/generic_box.h" +#include "ui/text/text_utilities.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/labels.h" +#include "ui/wrap/slide_wrap.h" +#include "ui/wrap/vertical_layout.h" +#include "ui/painter.h" +#include "ui/vertical_list.h" +#include "styles/style_info.h" +#include "styles/style_layers.h" +#include "styles/style_settings.h" + +namespace Ui { +namespace { + +enum class LayoutType { + Tabs, + List +}; + +class LayoutButton final : public Ui::RippleButton { +public: + LayoutButton( + QWidget *parent, + LayoutType type, + std::shared_ptr> group); + +private: + void paintEvent(QPaintEvent *e) override; + + QImage prepareRippleMask() const override; + + Ui::FlatLabel _text; + Ui::Animations::Simple _activeAnimation; + bool _active = false; + +}; + +LayoutButton::LayoutButton( + QWidget *parent, + LayoutType type, + std::shared_ptr> group) +: RippleButton(parent, st::defaultRippleAnimationBgOver) +, _text(this, st::topicsLayoutButtonLabel) +, _active(group->current() == type) { + _text.setText(type == LayoutType::Tabs + ? tr::lng_edit_topics_tabs(tr::now) + : tr::lng_edit_topics_list(tr::now)); + const auto iconColorOverride = [=] { + return anim::color( + st::windowSubTextFg, + st::windowActiveTextFg, + _activeAnimation.value(_active ? 1. : 0.)); + }; + const auto iconSize = st::topicsLayoutButtonIconSize; + auto [iconWidget, iconAnimate] = Settings::CreateLottieIcon( + this, + { + .name = (type == LayoutType::Tabs + ? u"topics_tabs"_q + : u"topics_list"_q), + .color = &st::windowSubTextFg, + .sizeOverride = { iconSize, iconSize }, + .colorizeUsingAlpha = true, + }, + st::topicsLayoutButtonIconPadding, + iconColorOverride); + const auto icon = iconWidget.release(); + setClickedCallback([=] { + group->setValue(type); + }); + group->value() | rpl::start_with_next([=](LayoutType value) { + const auto active = (value == type); + _text.setTextColorOverride(active + ? st::windowFgActive->c + : std::optional()); + + if (_active == active) { + return; + } + _active = active; + _text.update(); + if (_active) { + iconAnimate(anim::repeat::once); + } + _activeAnimation.start([=] { + icon->update(); + }, _active ? 0. : 1., _active ? 0. : 1., st::fadeWrapDuration); + }, lifetime()); + + _text.paintRequest() | rpl::start_with_next([=](QRect clip) { + if (_active) { + auto p = QPainter(&_text); + auto hq = PainterHighQualityEnabler(p); + const auto radius = _text.height() / 2.; + p.setPen(Qt::NoPen); + p.setBrush(st::windowBgActive); + p.drawRoundedRect(_text.rect(), radius, radius); + } + }, _text.lifetime()); + + const auto padding = st::topicsLayoutButtonPadding; + const auto skip = st::topicsLayoutButtonSkip; + const auto text = _text.height(); + + resize( + padding.left() + icon->width() + padding.right(), + padding.top() + icon->height() + skip + text + padding.bottom()); + icon->move(padding.left(), padding.top()); + _text.move( + (width() - _text.width()) / 2, + padding.top() + icon->height() + skip); +} + +void LayoutButton::paintEvent(QPaintEvent *e) { + auto p = QPainter(this); + const auto rippleBg = anim::color( + st::windowBgOver, + st::lightButtonBgOver, + _activeAnimation.value(_active ? 1. : 0.)); + paintRipple(p, QPoint(), &rippleBg); +} + +QImage LayoutButton::prepareRippleMask() const { + return Ui::RippleAnimation::RoundRectMask(size(), st::boxRadius); +} + +} // namespace + +void ToggleTopicsBox( + not_null box, + bool enabled, + bool tabs, + Fn callback) { + box->setTitle(tr::lng_forum_topics_switch()); + box->setWidth(st::boxWideWidth); + + const auto container = box->verticalLayout(); + + Settings::AddDividerTextWithLottie(container, { + .lottie = u"topics"_q, + .lottieSize = st::settingsFilterIconSize, + .lottieMargins = st::settingsFilterIconPadding, + .showFinished = box->showFinishes(), + .about = tr::lng_edit_topics_about( + Ui::Text::RichLangValue + ), + .aboutMargins = st::settingsFilterDividerLabelPadding, + }); + + Ui::AddSkip(container); + + const auto toggle = container->add( + object_ptr( + container, + tr::lng_edit_topics_enable(), + st::settingsButtonNoIcon)); + toggle->toggleOn(rpl::single(enabled)); + + const auto group = std::make_shared>(tabs + ? LayoutType::Tabs + : LayoutType::List); + + const auto layoutWrap = container->add( + object_ptr>( + container, + object_ptr(container))); + const auto layout = layoutWrap->entity(); + + Ui::AddSubsectionTitle(layout, tr::lng_edit_topics_layout()); + const auto buttons = layout->add( + object_ptr(layout), + QMargins(0, 0, 0, st::defaultVerticalListSkip * 2)); + + const auto tabsButton = Ui::CreateChild( + buttons, + LayoutType::Tabs, + group); + const auto listButton = Ui::CreateChild( + buttons, + LayoutType::List, + group); + + buttons->resize(container->width(), tabsButton->height()); + buttons->widthValue() | rpl::start_with_next([=](int outer) { + const auto skip = st::boxRowPadding.left() - st::boxRadius; + tabsButton->moveToLeft(skip, 0, outer); + listButton->moveToRight(skip, 0, outer); + }, buttons->lifetime()); + + Ui::AddDividerText( + layout, + tr::lng_edit_topics_layout_about(Ui::Text::RichLangValue)); + + layoutWrap->toggle(enabled, anim::type::instant); + toggle->toggledChanges( + ) | rpl::start_with_next([=](bool checked) { + layoutWrap->toggle(checked, anim::type::normal); + }, layoutWrap->lifetime()); + + box->addButton(tr::lng_settings_save(), [=] { + const auto enabledValue = toggle->toggled(); + const auto tabsValue = (group->current() == LayoutType::Tabs); + callback(enabledValue, tabsValue); + box->closeBox(); + }); + + box->addButton(tr::lng_cancel(), [=] { + box->closeBox(); + }); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/boxes/peers/toggle_topics_box.h b/Telegram/SourceFiles/boxes/peers/toggle_topics_box.h new file mode 100644 index 0000000000..0bd4ad3685 --- /dev/null +++ b/Telegram/SourceFiles/boxes/peers/toggle_topics_box.h @@ -0,0 +1,20 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/layers/generic_box.h" + +namespace Ui { + +void ToggleTopicsBox( + not_null box, + bool enabled, + bool tabs, + Fn callback); + +} // namespace Ui diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 6684631180..43182a6ad6 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -410,7 +410,7 @@ void ChannelData::setPendingRequestsCount( bool ChannelData::useSubsectionTabs() const { return isForum() - && ((flags() & ChannelDataFlag::ForumTabs) || true); AssertIsDebug(); + && (flags() & ChannelDataFlag::ForumTabs); } ChatRestrictionsInfo ChannelData::KickedRestrictedRights( diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index ec41e8ee17..f9a3127f56 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -979,12 +979,13 @@ not_null Session::processChat(const MTPChat &data) { | Flag::CallNotEmpty | Flag::Forbidden | (!minimal - ? (Flag::Left | Flag::Creator | Flag::ForumTabs) + ? (Flag::Left | Flag::Creator) : Flag()) | Flag::NoForwards | Flag::JoinToWrite | Flag::RequestToJoin | Flag::Forum + | Flag::ForumTabs | ((!minimal && !data.is_stories_hidden_min()) ? Flag::StoriesHidden : Flag()) @@ -1016,8 +1017,7 @@ not_null Session::processChat(const MTPChat &data) { : Flag()) | (!minimal ? ((data.is_left() ? Flag::Left : Flag()) - | (data.is_creator() ? Flag::Creator : Flag()) - | (data.is_forum_tabs() ? Flag::ForumTabs : Flag())) + | (data.is_creator() ? Flag::Creator : Flag())) : Flag()) | (data.is_noforwards() ? Flag::NoForwards : Flag()) | (data.is_join_to_send() ? Flag::JoinToWrite : Flag()) @@ -1025,6 +1025,7 @@ not_null Session::processChat(const MTPChat &data) { | ((data.is_forum() && data.is_megagroup()) ? Flag::Forum : Flag()) + | (data.is_forum_tabs() ? Flag::ForumTabs : Flag()) | ((!minimal && !data.is_stories_hidden_min() && data.is_stories_hidden()) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 8a88024743..0630c14547 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -2623,6 +2623,7 @@ void HistoryWidget::showHistory( channel->flagsValue( ) | rpl::start_with_next([=] { refreshJoinChannelText(); + validateSubsectionTabs(); }, _list->lifetime()); } else { refreshJoinChannelText(); @@ -8245,8 +8246,18 @@ void HistoryWidget::showPremiumToast(not_null document) { void HistoryWidget::validateSubsectionTabs() { if (!_history || !HistoryView::SubsectionTabs::UsedFor(_history)) { - _subsectionTabsLifetime.destroy(); - _subsectionTabs = nullptr; + if (_subsectionTabs) { + _subsectionTabsLifetime.destroy(); + _subsectionTabs = nullptr; + updateControlsGeometry(); + if (const auto forum = _history->asForum()) { + controller()->showForum(forum, { + Window::SectionShow::Way::Backward, + anim::type::normal, + anim::activation::background, + }); + } + } return; } else if (_subsectionTabs) { return; @@ -8259,6 +8270,7 @@ void HistoryWidget::validateSubsectionTabs() { _history); } _subsectionTabs->removeRequests() | rpl::start_with_next([=] { + _subsectionTabsLifetime.destroy(); _subsectionTabs = nullptr; updateControlsGeometry(); }, _subsectionTabsLifetime); diff --git a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp index 6829d8a432..70e7d71042 100644 --- a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp @@ -928,6 +928,7 @@ void ChatWidget::setupComposeControls() { channel->flagsValue() ) | rpl::start_with_next([=] { refreshJoinGroupButton(); + validateSubsectionTabs(); }, lifetime()); } else { refreshJoinGroupButton(); @@ -1522,8 +1523,18 @@ void ChatWidget::edit( void ChatWidget::validateSubsectionTabs() { if (!HistoryView::SubsectionTabs::UsedFor(_history)) { - _subsectionTabsLifetime.destroy(); - _subsectionTabs = nullptr; + if (_subsectionTabs) { + _subsectionTabsLifetime.destroy(); + _subsectionTabs = nullptr; + updateControlsGeometry(); + if (const auto forum = _history->asForum()) { + controller()->showForum(forum, { + Window::SectionShow::Way::Backward, + anim::type::normal, + anim::activation::background, + }); + } + } return; } else if (_subsectionTabs) { return; @@ -1537,6 +1548,7 @@ void ChatWidget::validateSubsectionTabs() { thread); } _subsectionTabs->removeRequests() | rpl::start_with_next([=] { + _subsectionTabsLifetime.destroy(); _subsectionTabs = nullptr; updateControlsGeometry(); }, _subsectionTabsLifetime); diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 3097de7a26..a9446d9c08 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -1177,3 +1177,13 @@ infoGiftTooltip: ImportantTooltip(defaultImportantTooltip) { padding: margins(8px, 2px, 8px, 3px); } infoGiftTooltipFont: font(11px semibold); + +topicsLayoutButtonLabel: FlatLabel(defaultFlatLabel) { + style: semiboldTextStyle; + margin: margins(10px, 4px, 10px, 4px); + textFg: windowSubTextFg; +} +topicsLayoutButtonIconPadding: margins(4px, 0px, 4px, 0px); +topicsLayoutButtonIconSize: 140px; +topicsLayoutButtonPadding: margins(4px, 0px, 4px, 12px); +topicsLayoutButtonSkip: 0px; diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp index 5412b5886b..f02f2f07c6 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp @@ -957,4 +957,3 @@ void InnerWidget::showFinished() { } } // namespace Info::Statistics - diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 1955440642..fc937d352b 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -2506,6 +2506,7 @@ channels.restrictSponsoredMessages#9ae91519 channel:InputChannel restricted:Bool channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; channels.updatePaidMessagesPrice#4b12327b flags:# broadcast_messages_allowed:flags.0?true channel:InputChannel send_paid_messages_stars:long = Updates; channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates; +channels.getMessageAuthor#ece2a0e6 channel:InputChannel id:int = User; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp index 465a70735c..68bceccf38 100644 --- a/Telegram/SourceFiles/settings/settings_common.cpp +++ b/Telegram/SourceFiles/settings/settings_common.cpp @@ -242,7 +242,8 @@ void AddDividerTextWithLottie( LottieIcon CreateLottieIcon( not_null parent, Lottie::IconDescriptor &&descriptor, - style::margins padding) { + style::margins padding, + Fn colorOverride) { Expects(!descriptor.frame); // I'm not sure it considers limitFps. descriptor.limitFps = true; @@ -262,7 +263,9 @@ LottieIcon CreateLottieIcon( const auto looped = raw->lifetime().make_state(true); const auto start = [=] { - icon->animate([=] { raw->update(); }, 0, icon->framesCount() - 1); + icon->animate([=] { + raw->update(); + }, 0, icon->framesCount() - 1); }; const auto animate = [=](anim::repeat repeat) { *looped = (repeat == anim::repeat::loop); @@ -272,7 +275,9 @@ LottieIcon CreateLottieIcon( ) | rpl::start_with_next([=] { auto p = QPainter(raw); const auto left = (raw->width() - width) / 2; - icon->paint(p, left, padding.top()); + icon->paint(p, left, padding.top(), colorOverride + ? colorOverride() + : std::optional()); if (!icon->animating() && icon->frameIndex() > 0 && *looped) { start(); } diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h index 2c2c31b64b..6a9e214951 100644 --- a/Telegram/SourceFiles/settings/settings_common.h +++ b/Telegram/SourceFiles/settings/settings_common.h @@ -204,7 +204,8 @@ struct LottieIcon { [[nodiscard]] LottieIcon CreateLottieIcon( not_null parent, Lottie::IconDescriptor &&descriptor, - style::margins padding = {}); + style::margins padding = {}, + Fn colorOverride = nullptr); struct SliderWithLabel { object_ptr widget; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index d0ba08a2c7..5e123fd458 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_saved_sublist.h" #include "data/data_session.h" #include "data/data_file_origin.h" +#include "data/data_flags.h" #include "data/data_folder.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -1896,10 +1897,11 @@ void SessionController::showForum( if (_shownForum.current() != forum) { return; } - forum->destroyed( - ) | rpl::start_with_next([=, history = forum->history()] { + const auto history = forum->history(); + const auto closeAndShowHistory = [=](bool showOnlyIfEmpty) { const auto now = activeChatCurrent().owningHistory(); - const auto showHistory = !now || (now == history); + const auto showHistory = !now + || (!showOnlyIfEmpty && (now == history)); const auto weak = base::make_weak(this); closeForum(); if (weak && showHistory) { @@ -1909,6 +1911,19 @@ void SessionController::showForum( anim::activation::background, }); } + }; + forum->destroyed( + ) | rpl::start_with_next([=] { + closeAndShowHistory(false); + }, _shownForumLifetime); + using FlagChange = Data::Flags::Change; + forum->channel()->flagsValue( + ) | rpl::start_with_next([=](FlagChange change) { + if (change.diff & ChannelDataFlag::ForumTabs) { + if (HistoryView::SubsectionTabs::UsedFor(history)) { + closeAndShowHistory(true); + } + } }, _shownForumLifetime); content()->showForum(forum, params); closeMonoforum(); diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index f39e17f834..7bdd372fd6 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -58,6 +58,8 @@ PRIVATE boxes/peers/edit_peer_history_visibility_box.cpp boxes/peers/edit_peer_history_visibility_box.h + boxes/peers/toggle_topics_box.cpp + boxes/peers/toggle_topics_box.h calls/group/ui/calls_group_recording_box.cpp calls/group/ui/calls_group_recording_box.h diff --git a/Telegram/lib_lottie b/Telegram/lib_lottie index 4038a11f63..4fc3ac0ea5 160000 --- a/Telegram/lib_lottie +++ b/Telegram/lib_lottie @@ -1 +1 @@ -Subproject commit 4038a11f635311073f6d55786490920b043cb319 +Subproject commit 4fc3ac0ea52f271cc9b108481f83d56fd76ab0ed