mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to set color for chats filter from settings.
This commit is contained in:
parent
6baba5a7b2
commit
cfc40ee966
6 changed files with 137 additions and 22 deletions
|
@ -5160,6 +5160,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_enable_tags" = "Show Folder Tags";
|
"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" = "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_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_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";
|
"lng_filters_link" = "Share Folder";
|
||||||
|
|
|
@ -7,22 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "boxes/filters/edit_filter_box.h"
|
#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_list.h"
|
||||||
#include "boxes/filters/edit_filter_chats_preview.h"
|
#include "boxes/filters/edit_filter_chats_preview.h"
|
||||||
#include "boxes/filters/edit_filter_links.h"
|
#include "boxes/filters/edit_filter_links.h"
|
||||||
#include "boxes/premium_limits_box.h"
|
#include "boxes/premium_limits_box.h"
|
||||||
|
#include "boxes/premium_preview_box.h"
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "core/application.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "core/core_settings.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 "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat_filters.h"
|
#include "data/data_chat_filters.h"
|
||||||
#include "data/data_peer.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_premium_limits.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.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 "history/history.h"
|
||||||
|
#include "info/userpic/info_userpic_color_circle_button.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.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 "window/window_controller.h"
|
||||||
#include "apiwrap.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_info_userpic_builder.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -336,6 +338,7 @@ void EditFilterBox(
|
||||||
const Data::ChatFilter &data,
|
const Data::ChatFilter &data,
|
||||||
Fn<void(Data::ChatFilter)> next)> saveAnd) {
|
Fn<void(Data::ChatFilter)> next)> saveAnd) {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
constexpr auto kColorsCount = 8;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
rpl::variable<Data::ChatFilter> rules;
|
rpl::variable<Data::ChatFilter> rules;
|
||||||
|
@ -343,6 +346,7 @@ void EditFilterBox(
|
||||||
rpl::variable<bool> hasLinks;
|
rpl::variable<bool> hasLinks;
|
||||||
rpl::variable<bool> chatlist;
|
rpl::variable<bool> chatlist;
|
||||||
rpl::variable<bool> creating;
|
rpl::variable<bool> creating;
|
||||||
|
rpl::variable<int> colorIndex;
|
||||||
};
|
};
|
||||||
const auto owner = &window->session().data();
|
const auto owner = &window->session().data();
|
||||||
const auto state = box->lifetime().make_state<State>(State{
|
const auto state = box->lifetime().make_state<State>(State{
|
||||||
|
@ -350,6 +354,7 @@ void EditFilterBox(
|
||||||
.chatlist = filter.chatlist(),
|
.chatlist = filter.chatlist(),
|
||||||
.creating = filter.title().isEmpty(),
|
.creating = filter.title().isEmpty(),
|
||||||
});
|
});
|
||||||
|
state->colorIndex = filter.colorIndex().value_or(kColorsCount - 1);
|
||||||
state->links = owner->chatsFilters().chatlistLinks(filter.id()),
|
state->links = owner->chatsFilters().chatlistLinks(filter.id()),
|
||||||
state->hasLinks = state->links.value() | rpl::map([=](const auto &v) {
|
state->hasLinks = state->links.value() | rpl::map([=](const auto &v) {
|
||||||
return !v.empty();
|
return !v.empty();
|
||||||
|
@ -504,6 +509,99 @@ void EditFilterBox(
|
||||||
Ui::AddDividerText(excludeInner, tr::lng_filters_exclude_about());
|
Ui::AddDividerText(excludeInner, tr::lng_filters_exclude_about());
|
||||||
Ui::AddSkip(excludeInner);
|
Ui::AddSkip(excludeInner);
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto wrap = content->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
content,
|
||||||
|
object_ptr<Ui::VerticalLayout>(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<not_null<UserpicBuilder::CircleButton*>>();
|
||||||
|
const auto animation
|
||||||
|
= line->lifetime().make_state<Ui::Animations::Simple>();
|
||||||
|
for (auto i = 0; i < kColorsCount; ++i) {
|
||||||
|
const auto button = Ui::CreateChild<UserpicBuilder::CircleButton>(
|
||||||
|
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<Ui::RpWidget>(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<Data::ChatFilter> {
|
const auto collect = [=]() -> std::optional<Data::ChatFilter> {
|
||||||
const auto title = name->getLastText().trimmed();
|
const auto title = name->getLastText().trimmed();
|
||||||
const auto rules = data->current();
|
const auto rules = data->current();
|
||||||
|
@ -520,7 +618,11 @@ void EditFilterBox(
|
||||||
window->window().showToast(tr::lng_filters_default(tr::now));
|
window->window().showToast(tr::lng_filters_default(tr::now));
|
||||||
return {};
|
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(
|
Ui::AddSubsectionTitle(
|
||||||
|
|
|
@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/layers/generic_box.h"
|
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class GenericBox;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class ChatFilter;
|
class ChatFilter;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -168,6 +168,12 @@ ChatFilter ChatFilter::withTitle(const QString &title) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChatFilter ChatFilter::withColorIndex(std::optional<uint8> c) const {
|
||||||
|
auto result = *this;
|
||||||
|
result._colorIndex = c;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const {
|
ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const {
|
||||||
auto result = *this;
|
auto result = *this;
|
||||||
result._flags &= Flag::RulesMask;
|
result._flags &= Flag::RulesMask;
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] ChatFilter withId(FilterId id) const;
|
[[nodiscard]] ChatFilter withId(FilterId id) const;
|
||||||
[[nodiscard]] ChatFilter withTitle(const QString &title) const;
|
[[nodiscard]] ChatFilter withTitle(const QString &title) const;
|
||||||
|
[[nodiscard]] ChatFilter withColorIndex(std::optional<uint8>) const;
|
||||||
[[nodiscard]] ChatFilter withChatlist(
|
[[nodiscard]] ChatFilter withChatlist(
|
||||||
bool chatlist,
|
bool chatlist,
|
||||||
bool hasMyLinks) const;
|
bool hasMyLinks) const;
|
||||||
|
|
|
@ -219,6 +219,7 @@ void FilterRowButton::updateData(const Data::ChatFilter &filter) {
|
||||||
|
|
||||||
_title.setText(st::contactsNameStyle, filter.title());
|
_title.setText(st::contactsNameStyle, filter.title());
|
||||||
_icon = Ui::ComputeFilterIcon(filter);
|
_icon = Ui::ComputeFilterIcon(filter);
|
||||||
|
_colorIndex = filter.colorIndex();
|
||||||
updateCount(filter);
|
updateCount(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue