From cfc40ee966dd046d53c4f67293b7ba2718b14a5f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 14:56:58 +0300 Subject: [PATCH] Added ability to set color for chats filter from settings. --- Telegram/Resources/langs/lang.strings | 3 + .../boxes/filters/edit_filter_box.cpp | 142 +++++++++++++++--- .../boxes/filters/edit_filter_box.h | 6 +- .../SourceFiles/data/data_chat_filters.cpp | 6 + Telegram/SourceFiles/data/data_chat_filters.h | 1 + .../SourceFiles/settings/settings_folders.cpp | 1 + 6 files changed, 137 insertions(+), 22 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 20b1b7c6a..5919b2593 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5160,6 +5160,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_enable_tags" = "Show Folder Tags"; "lng_filters_enable_tags_about" = "Display folder names for each chat in the chat list."; "lng_filters_enable_tags_about_premium" = "Subscribe to **{link}** to display folder names for each chat in the chat list."; +"lng_filters_tag_color_subtitle" = "Folder color in chat list"; +"lng_filters_tag_color_about" = "Choose a color for the tag of this folder."; +"lng_filters_tag_color_no" = "No Tag"; "lng_filters_delete_sure" = "Are you sure you want to delete this folder? This will also deactivate all the invite links created to share this folder."; "lng_filters_link" = "Share Folder"; diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index df85e6254..d36a33f2c 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -7,22 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/filters/edit_filter_box.h" +#include "apiwrap.h" +#include "base/event_filter.h" #include "boxes/filters/edit_filter_chats_list.h" #include "boxes/filters/edit_filter_chats_preview.h" #include "boxes/filters/edit_filter_links.h" #include "boxes/premium_limits_box.h" +#include "boxes/premium_preview_box.h" #include "chat_helpers/emoji_suggestions_widget.h" -#include "ui/layers/generic_box.h" -#include "ui/text/text_utilities.h" -#include "ui/text/text_options.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/fields/input_field.h" -#include "ui/wrap/slide_wrap.h" -#include "ui/effects/panel_animation.h" -#include "ui/filter_icons.h" -#include "ui/filter_icon_panel.h" -#include "ui/painter.h" -#include "ui/vertical_list.h" +#include "core/application.h" +#include "core/core_settings.h" #include "data/data_channel.h" #include "data/data_chat_filters.h" #include "data/data_peer.h" @@ -30,22 +24,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_premium_limits.h" #include "data/data_session.h" #include "data/data_user.h" -#include "core/application.h" -#include "core/core_settings.h" -#include "settings/settings_common.h" -#include "base/event_filter.h" -#include "lang/lang_keys.h" #include "history/history.h" +#include "info/userpic/info_userpic_color_circle_button.h" +#include "lang/lang_keys.h" #include "main/main_session.h" -#include "window/window_session_controller.h" +#include "settings/settings_common.h" +#include "ui/effects/animations.h" +#include "ui/effects/panel_animation.h" +#include "ui/empty_userpic.h" +#include "ui/filter_icon_panel.h" +#include "ui/filter_icons.h" +#include "ui/layers/generic_box.h" +#include "ui/painter.h" +#include "ui/vertical_list.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/fields/input_field.h" +#include "ui/wrap/slide_wrap.h" #include "window/window_controller.h" -#include "apiwrap.h" +#include "window/window_session_controller.h" #include "styles/style_settings.h" #include "styles/style_boxes.h" #include "styles/style_layers.h" #include "styles/style_window.h" #include "styles/style_chat.h" -#include "styles/style_menu_icons.h" +#include "styles/style_info_userpic_builder.h" namespace { @@ -336,6 +338,7 @@ void EditFilterBox( const Data::ChatFilter &data, Fn next)> saveAnd) { using namespace rpl::mappers; + constexpr auto kColorsCount = 8; struct State { rpl::variable rules; @@ -343,6 +346,7 @@ void EditFilterBox( rpl::variable hasLinks; rpl::variable chatlist; rpl::variable creating; + rpl::variable colorIndex; }; const auto owner = &window->session().data(); const auto state = box->lifetime().make_state(State{ @@ -350,6 +354,7 @@ void EditFilterBox( .chatlist = filter.chatlist(), .creating = filter.title().isEmpty(), }); + state->colorIndex = filter.colorIndex().value_or(kColorsCount - 1); state->links = owner->chatsFilters().chatlistLinks(filter.id()), state->hasLinks = state->links.value() | rpl::map([=](const auto &v) { return !v.empty(); @@ -504,6 +509,99 @@ void EditFilterBox( Ui::AddDividerText(excludeInner, tr::lng_filters_exclude_about()); Ui::AddSkip(excludeInner); + { + const auto wrap = content->add( + object_ptr>( + content, + object_ptr(content))); + const auto colors = wrap->entity(); + const auto session = &window->session(); + + wrap->toggleOn( + rpl::combine( + session->premiumPossibleValue(), + session->data().chatsFilters().tagsEnabledValue(), + Data::AmPremiumValue(session) + ) | rpl::map([=] (bool possible, bool tagsEnabled, bool premium) { + return possible && (tagsEnabled || !premium); + }), + anim::type::instant); + + const auto isPremium = session->premium(); + Ui::AddSubsectionTitle(colors, tr::lng_filters_tag_color_subtitle()); + const auto side = st::userpicBuilderEmojiAccentColorSize; + const auto line = colors->add( + Ui::CreateSkipWidget(colors, side), + st::boxRowPadding); + auto buttons = std::vector>(); + const auto animation + = line->lifetime().make_state(); + for (auto i = 0; i < kColorsCount; ++i) { + const auto button = Ui::CreateChild( + line); + button->resize(side, side); + button->setIndex(i); + button->setSelectedProgress(isPremium + ? (state->colorIndex.current() == i) + : (i == (kColorsCount - 1))); + button->setBrush(Ui::EmptyUserpic::UserpicColor(i).color2); + buttons.push_back(button); + } + for (auto i = 0; i < kColorsCount; ++i) { + const auto &button = buttons[i]; + button->setClickedCallback([=] { + const auto was = state->colorIndex.current(); + const auto now = i; + if (was != now) { + animation->stop(); + animation->start([=](float64 progress) { + if (was >= 0) { + buttons[was]->setSelectedProgress(1. - progress); + } + buttons[now]->setSelectedProgress(progress); + }, 0., 1., st::universalDuration); + } + state->colorIndex = now; + }); + if (!session->premium()) { + button->setClickedCallback([w = window] { + ShowPremiumPreviewToBuy(w, PremiumFeature::FilterTags); + }); + } + } + line->sizeValue() | rpl::start_with_next([=](const QSize &size) { + const auto totalWidth = buttons.size() * side; + const auto spacing = (size.width() - totalWidth) + / (buttons.size() - 1); + for (auto i = 0; i < kColorsCount; ++i) { + const auto &button = buttons[i]; + button->moveToLeft(i * (side + spacing), 0); + } + }, line->lifetime()); + + { + const auto last = buttons.back(); + const auto icon = Ui::CreateChild(last); + icon->resize(side, side); + icon->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(icon); + (session->premium() + ? st::windowFilterSmallRemove.icon + : st::historySendDisabledIcon).paintInCenter( + p, + QRectF(icon->rect()), + st::historyPeerUserpicFg->c); + }, icon->lifetime()); + icon->setAttribute(Qt::WA_TransparentForMouseEvents); + last->setBrush(st::historyPeerArchiveUserpicBg); + } + + Ui::AddSkip(colors); + Ui::AddSkip(colors); + Ui::AddDividerText(colors, tr::lng_filters_tag_color_about()); + Ui::AddSkip(colors); + } + const auto collect = [=]() -> std::optional { const auto title = name->getLastText().trimmed(); const auto rules = data->current(); @@ -520,7 +618,11 @@ void EditFilterBox( window->window().showToast(tr::lng_filters_default(tr::now)); return {}; } - return rules.withTitle(title); + const auto rawColorIndex = state->colorIndex.current(); + const auto colorIndex = (rawColorIndex >= (kColorsCount - 1) + ? std::nullopt + : std::make_optional(rawColorIndex)); + return rules.withTitle(title).withColorIndex(colorIndex); }; Ui::AddSubsectionTitle( diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.h b/Telegram/SourceFiles/boxes/filters/edit_filter_box.h index 695dbbe92..cfff92907 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.h +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.h @@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "ui/layers/generic_box.h" - namespace Window { class SessionController; } // namespace Window +namespace Ui { +class GenericBox; +} // namespace Ui + namespace Data { class ChatFilter; } // namespace Data diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index ba3c0758d..224ee2797 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -168,6 +168,12 @@ ChatFilter ChatFilter::withTitle(const QString &title) const { return result; } +ChatFilter ChatFilter::withColorIndex(std::optional c) const { + auto result = *this; + result._colorIndex = c; + return result; +} + ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const { auto result = *this; result._flags &= Flag::RulesMask; diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 18630b391..82f050af0 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -60,6 +60,7 @@ public: [[nodiscard]] ChatFilter withId(FilterId id) const; [[nodiscard]] ChatFilter withTitle(const QString &title) const; + [[nodiscard]] ChatFilter withColorIndex(std::optional) const; [[nodiscard]] ChatFilter withChatlist( bool chatlist, bool hasMyLinks) const; diff --git a/Telegram/SourceFiles/settings/settings_folders.cpp b/Telegram/SourceFiles/settings/settings_folders.cpp index c0d595dd9..f91427005 100644 --- a/Telegram/SourceFiles/settings/settings_folders.cpp +++ b/Telegram/SourceFiles/settings/settings_folders.cpp @@ -219,6 +219,7 @@ void FilterRowButton::updateData(const Data::ChatFilter &filter) { _title.setText(st::contactsNameStyle, filter.title()); _icon = Ui::ComputeFilterIcon(filter); + _colorIndex = filter.colorIndex(); updateCount(filter); }