diff --git a/Telegram/Resources/animations/edit_peers/topics.tgs b/Telegram/Resources/animations/edit_peers/topics.tgs new file mode 100644 index 0000000000..a5552a4acb Binary files /dev/null and b/Telegram/Resources/animations/edit_peers/topics.tgs differ diff --git a/Telegram/Resources/animations/edit_peers/topics_list.tgs b/Telegram/Resources/animations/edit_peers/topics_list.tgs new file mode 100644 index 0000000000..d85bf7ff85 Binary files /dev/null and b/Telegram/Resources/animations/edit_peers/topics_list.tgs differ 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 0000000000..3a240b4c62 Binary files /dev/null and b/Telegram/Resources/animations/edit_peers/topics_tabs.tgs differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 39db6ae517..2cb115b74b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3216,6 +3216,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_feature_transcribe" = "Voice-to-Text Conversion"; "lng_feature_autotranslate" = "Autotranslation of Messages"; +"lng_edit_topics_enable" = "Enable Topics"; +"lng_edit_topics_about" = "The group chat will be divided into topics created by admins or users."; +"lng_edit_topics_layout" = "Topics layout"; +"lng_edit_topics_layout_about" = "Choose how topics appear for all members."; +"lng_edit_topics_tabs" = "Tabs"; +"lng_edit_topics_list" = "List"; + "lng_giveaway_new_title" = "Boosts via Gifts"; "lng_giveaway_new_about" = "Get more boosts for your channel by gifting Premium to your subscribers."; "lng_giveaway_new_about_group" = "Get more boosts for your group by gifting Premium to your members."; diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index ae94041686..09702ee5d0 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -33,6 +33,9 @@ ../../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