diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index cfc40d8ef2..00c843ebea 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -7662,6 +7662,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_vertical" = "Tabs on the left"; "lng_filters_horizontal" = "Tabs at the top"; "lng_filters_tabs_subtitle" = "Tabs appearance"; +"lng_filters_tabs_default" = "Default"; "lng_filters_tabs_text" = "Text only"; "lng_filters_tabs_text_icons" = "Text and icons"; "lng_filters_tabs_icons" = "Icons only"; diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index 6dcce5759b..373785cf4d 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -1243,6 +1243,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { const auto uncheckedChatFiltersTabsMode = static_cast( chatFiltersTabsMode); switch (uncheckedChatFiltersTabsMode) { + case Mode::Default: case Mode::TextOnly: case Mode::TextAndIcons: case Mode::IconsOnly: @@ -1742,7 +1743,7 @@ void Settings::resetOnLastLogout() { _recordVideoMessages = false; _videoQuality = {}; _chatFiltersHorizontal = false; - _chatFiltersTabsMode = Ui::ChatsFiltersTabsMode::TextOnly; + _chatFiltersTabsMode = Ui::ChatsFiltersTabsMode::Default; _pullToNextChannel = true; _quickDialogAction = Dialogs::Ui::QuickDialogAction::Disabled; _notificationsVolume = 100; diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index 82802b47e1..7192f0db82 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -1205,7 +1205,7 @@ private: Media::VideoQuality _videoQuality; rpl::variable _chatFiltersHorizontal = false; rpl::variable _chatFiltersTabsMode - = Ui::ChatsFiltersTabsMode::TextOnly; + = Ui::ChatsFiltersTabsMode::Default; base::flat_map _prefs; bool _tabbedReplacedWithInfo = false; // per-window diff --git a/Telegram/SourceFiles/settings/sections/settings_folders.cpp b/Telegram/SourceFiles/settings/sections/settings_folders.cpp index f717827e9e..463e2c3b77 100644 --- a/Telegram/SourceFiles/settings/sections/settings_folders.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_folders.cpp @@ -1149,35 +1149,25 @@ void BuildViewSection(SectionBuilder &builder) { Core::App().saveSettingsDelayed(); }); - const auto modeWrap = content->add( - object_ptr>( - content, - object_ptr(content))); - modeWrap->toggleOn(rpl::single( - Core::App().settings().chatFiltersHorizontal() - ) | rpl::then( - Core::App().settings().chatFiltersHorizontalChanges())); - modeWrap->finishAnimating(); - const auto modeContent = modeWrap->entity(); - - Ui::AddSkip(modeContent); + Ui::AddSkip(content); Ui::AddSubsectionTitle( - modeContent, + content, tr::lng_filters_tabs_subtitle()); using Mode = Ui::ChatsFiltersTabsMode; const auto modeGroup = std::make_shared>( Core::App().settings().chatFiltersTabsMode()); const auto addMode = [&](Mode value, const QString &text) { - modeContent->add( + content->add( object_ptr>( - modeContent, + content, modeGroup, value, text, st::settingsSendType), st::settingsSendTypePadding); }; + addMode(Mode::Default, tr::lng_filters_tabs_default(tr::now)); addMode(Mode::TextOnly, tr::lng_filters_tabs_text(tr::now)); addMode(Mode::TextAndIcons, tr::lng_filters_tabs_text_icons(tr::now)); addMode(Mode::IconsOnly, tr::lng_filters_tabs_icons(tr::now)); diff --git a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_mode.h b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_mode.h index ea2bd31e08..f5d3719406 100644 --- a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_mode.h +++ b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_mode.h @@ -9,10 +9,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { +// Values are serialized in Core::Settings, don't change them. enum class ChatsFiltersTabsMode { - TextOnly = 0, + Default = 0, TextAndIcons = 1, IconsOnly = 2, + TextOnly = 3, }; +[[nodiscard]] inline ChatsFiltersTabsMode HorizontalChatsFiltersTabsMode( + ChatsFiltersTabsMode mode) { + return (mode == ChatsFiltersTabsMode::Default) + ? ChatsFiltersTabsMode::TextOnly + : mode; +} + +[[nodiscard]] inline ChatsFiltersTabsMode VerticalChatsFiltersTabsMode( + ChatsFiltersTabsMode mode) { + return (mode == ChatsFiltersTabsMode::Default) + ? ChatsFiltersTabsMode::TextAndIcons + : mode; +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp index 41563abef6..9505861b5d 100644 --- a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp +++ b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp @@ -516,7 +516,7 @@ not_null AddChatFiltersTabsStrip( ) | rpl::on_next(rebuild, wrap->lifetime()); Core::App().settings().chatFiltersTabsModeValue( ) | rpl::on_next([=](ChatsFiltersTabsMode mode) { - slider->setTabsMode(mode); + slider->setTabsMode(HorizontalChatsFiltersTabsMode(mode)); scrollToIndex(slider->activeSection(), anim::type::instant); }, wrap->lifetime()); rebuild(); diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index 688c18c29e..40e009f133 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -267,6 +267,15 @@ windowFiltersButton: SideBarButton(defaultSideBarButton) { badgePosition: point(3px, 7px); iconPosition: point(-1px, 6px); } +windowFiltersButtonTextOnly: SideBarButton(windowFiltersButton) { + textTop: 15px; + minHeight: 44px; + badgePosition: point(15px, 1px); +} +windowFiltersButtonIconsOnly: SideBarButton(windowFiltersButton) { + iconPosition: point(-1px, -1px); + minHeight: 54px; +} windowFiltersMainMenu: SideBarButton(windowFiltersButton) { icon: icon {{ "dialogs/dialogs_menu", sideBarIconFg }}; iconPosition: point(-1px, -1px); diff --git a/Telegram/SourceFiles/window/window_filters_favorite.cpp b/Telegram/SourceFiles/window/window_filters_favorite.cpp index 5cceed629a..ebb103334f 100644 --- a/Telegram/SourceFiles/window/window_filters_favorite.cpp +++ b/Telegram/SourceFiles/window/window_filters_favorite.cpp @@ -11,7 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/options.h" #include "base/qthelp_url.h" #include "base/weak_ptr.h" +#include "core/application.h" #include "core/click_handler_types.h" +#include "core/core_settings.h" #include "core/local_url_handlers.h" #include "data/data_changes.h" #include "data/data_file_origin.h" @@ -252,8 +254,17 @@ bool FolderFavoriteButton::shown() const { return _shown.current(); } +Ui::ChatsFiltersTabsMode FolderFavoriteButton::tabsMode() const { + return Ui::VerticalChatsFiltersTabsMode( + Core::App().settings().chatFiltersTabsMode()); +} + int FolderFavoriteButton::resizeGetHeight(int newWidth) { + using Mode = Ui::ChatsFiltersTabsMode; const auto result = _st.minHeight; + if (tabsMode() == Mode::IconsOnly) { + return result; + } const auto text = std::min( _label.countHeight(newWidth - _st.textSkip * 2), _st.style.font->height * kMaxLabelLines); @@ -267,19 +278,26 @@ void FolderFavoriteButton::paintEvent(QPaintEvent *e) { RippleButton::paintRipple(p, 0, 0); - if (_thumbnail) { + using Mode = Ui::ChatsFiltersTabsMode; + const auto mode = tabsMode(); + if (_thumbnail && mode != Mode::TextOnly) { const auto size = st::foldersFavorite.width(); const auto x = (width() - size) / 2; - p.drawImage(x, _st.iconPosition.y(), _thumbnail->image(size)); + const auto y = (_st.iconPosition.y() < 0) + ? (height() - size) / 2 + : _st.iconPosition.y(); + p.drawImage(x, y, _thumbnail->image(size)); } - p.setPen(_st.textFg); - _label.draw(p, { - .position = { _st.textSkip, _st.textTop }, - .availableWidth = width() - 2 * _st.textSkip, - .align = style::al_top, - .elisionLines = kMaxLabelLines, - }); + if (mode != Mode::IconsOnly) { + p.setPen(_st.textFg); + _label.draw(p, { + .position = { _st.textSkip, _st.textTop }, + .availableWidth = width() - 2 * _st.textSkip, + .align = style::al_top, + .elisionLines = kMaxLabelLines, + }); + } } void FolderFavoriteButton::setLink(const QString &link) { diff --git a/Telegram/SourceFiles/window/window_filters_favorite.h b/Telegram/SourceFiles/window/window_filters_favorite.h index 14f3e391ae..d3c7d1426d 100644 --- a/Telegram/SourceFiles/window/window_filters_favorite.h +++ b/Telegram/SourceFiles/window/window_filters_favorite.h @@ -22,6 +22,7 @@ namespace Ui { class DynamicImage; class GenericBox; class PopupMenu; +enum class ChatsFiltersTabsMode; } // namespace Ui namespace Window { @@ -57,6 +58,8 @@ private: void paintEvent(QPaintEvent *e) override; + [[nodiscard]] Ui::ChatsFiltersTabsMode tabsMode() const; + void resolvePeer(const QString &usernameOrPhone, bool phone); void resolveInvite(const QString &hash); void resolveStickerSet(const QString &shortName); diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index 842206c2ea..eb8bf6008e 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "base/event_filter.h" #include "base/options.h" +#include "core/application.h" +#include "core/core_settings.h" #include "core/ui_integration.h" #include "data/data_session.h" #include "data/data_chat_filters.h" @@ -178,6 +180,23 @@ void FiltersMenu::setup() { _menu.setClickedCallback([=] { _session->widget()->showMainMenu(); }); + + Core::App().settings().chatFiltersTabsModeValue( + ) | rpl::skip(1) | rpl::on_next([=] { + if (!_list) { + return; + } + _setup = prepareButton( + _container, + -1, + { TextWithEntities{ tr::lng_filters_setup(tr::now) } }, + Ui::FilterIcon::Edit); + if (_favorite) { + _favorite = nullptr; + updateFavorite(); + } + refresh(); + }, _outer.lifetime()); } void FiltersMenu::setupDragAndDrop() { @@ -470,7 +489,7 @@ void FiltersMenu::createFavorite() { object_ptr( _container, _session, - st::windowFiltersButton)))); + buttonStyle())))); _favorite->toggle(false, anim::type::instant); _favorite->setFinishedCallback([=] { if (_favorite && !_favorite->toggled()) { @@ -499,6 +518,21 @@ bool FiltersMenu::premium() const { return _session->session().user()->isPremium(); } +Ui::ChatsFiltersTabsMode FiltersMenu::tabsMode() const { + return Ui::VerticalChatsFiltersTabsMode( + Core::App().settings().chatFiltersTabsMode()); +} + +const style::SideBarButton &FiltersMenu::buttonStyle() const { + using Mode = Ui::ChatsFiltersTabsMode; + switch (tabsMode()) { + case Mode::TextOnly: return st::windowFiltersButtonTextOnly; + case Mode::TextAndIcons: return st::windowFiltersButton; + case Mode::IconsOnly: return st::windowFiltersButtonIconsOnly; + } + return st::windowFiltersButton; +} + base::unique_qptr FiltersMenu::prepareAll() { return prepareButton( _container, @@ -527,10 +561,11 @@ base::unique_qptr FiltersMenu::prepareButton( // configuring the role up front avoids a transient or separately-announced // role change. const auto listItem = (id >= 0); + const auto mode = tabsMode(); auto prepared = object_ptr( container, id ? title.text : TextWithEntities{ tr::lng_filters_all(tr::now) }, - st::windowFiltersButton, + buttonStyle(), Core::TextContext({ .session = &_session->session(), .customEmojiLoopLimit = isStatic ? -1 : 0, @@ -538,6 +573,8 @@ base::unique_qptr FiltersMenu::prepareButton( paused); prepared->setLocked(locked); prepared->setIsListItem(listItem); + prepared->setShowIcon(mode != Ui::ChatsFiltersTabsMode::TextOnly); + prepared->setShowText(mode != Ui::ChatsFiltersTabsMode::IconsOnly); auto added = toBeginning ? container->insert(0, std::move(prepared)) : container->add(std::move(prepared)); diff --git a/Telegram/SourceFiles/window/window_filters_menu.h b/Telegram/SourceFiles/window/window_filters_menu.h index 4b77fbf2e6..541acb3a78 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.h +++ b/Telegram/SourceFiles/window/window_filters_menu.h @@ -22,6 +22,7 @@ namespace Ui { class VerticalLayout; class VerticalLayoutReorder; enum class FilterIcon : uchar; +enum class ChatsFiltersTabsMode; class PopupMenu; template class SlideWrap; @@ -51,6 +52,8 @@ private: int oldPosition, int newPosition); [[nodiscard]] bool premium() const; + [[nodiscard]] Ui::ChatsFiltersTabsMode tabsMode() const; + [[nodiscard]] const style::SideBarButton &buttonStyle() const; [[nodiscard]] base::unique_qptr prepareAll(); [[nodiscard]] base::unique_qptr prepareButton( not_null container, diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 07cea400e2..640bc4c8c6 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 07cea400e2e6b2a7c08a289472bf5976a77e6500 +Subproject commit 640bc4c8c6a5b2a40986a86167c48152fc35e8ce