Respect correct min-level for colors.

This commit is contained in:
John Preston 2023-12-20 23:02:54 -04:00
parent d5a1c354d0
commit 9201cf24f1
12 changed files with 106 additions and 13 deletions

View file

@ -2133,6 +2133,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boost_channel_needs_level_color#one" = "Your channel needs to reach **Level {count}** to change channel color."; "lng_boost_channel_needs_level_color#one" = "Your channel needs to reach **Level {count}** to change channel color.";
"lng_boost_channel_needs_level_color#other" = "Your channel needs to reach **Level {count}** to change channel color."; "lng_boost_channel_needs_level_color#other" = "Your channel needs to reach **Level {count}** to change channel color.";
"lng_boost_channel_title_wallpaper" = "Enable wallpapers";
"lng_boost_channel_needs_level_wallpaper#one" = "Your channel needs to reach **Level {count}** to change channel wallpaper.";
"lng_boost_channel_needs_level_wallpaper#other" = "Your channel needs to reach **Level {count}** to change channel wallpaper.";
"lng_boost_channel_title_status" = "Enable emoji status";
"lng_boost_channel_needs_level_status#one" = "Your channel needs to reach **Level {count}** to set emoji status.";
"lng_boost_channel_needs_level_status#other" = "Your channel needs to reach **Level {count}** to set emoji status.";
"lng_boost_channel_title_reactions" = "Custom reactions"; "lng_boost_channel_title_reactions" = "Custom reactions";
"lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction."; "lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction.";
"lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions."; "lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions.";
@ -2847,6 +2855,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_sign_messages" = "Sign messages"; "lng_edit_sign_messages" = "Sign messages";
"lng_edit_group" = "Edit group"; "lng_edit_group" = "Edit group";
"lng_edit_channel_color" = "Change name color"; "lng_edit_channel_color" = "Change name color";
"lng_edit_channel_level_min" = "Level 1+";
"lng_edit_channel_wallpaper" = "Channel wallpaper";
"lng_edit_channel_wallpaper_about" = "Set a wallpaper that will be visible for everyone reading your channel.";
"lng_edit_channel_status" = "Channel emoji status";
"lng_edit_channel_status_about" = "Choose a status that will be shown next to the channel's name.";
"lng_edit_self_title" = "Edit your name"; "lng_edit_self_title" = "Edit your name";
"lng_confirm_contact_data" = "New Contact"; "lng_confirm_contact_data" = "New Contact";
"lng_add_contact" = "Create"; "lng_add_contact" = "Create";

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_peer_colors.h" #include "api/api_peer_colors.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "data/data_peer.h"
#include "ui/chat/chat_style.h" #include "ui/chat/chat_style.h"
namespace Api { namespace Api {
@ -62,6 +63,16 @@ auto PeerColors::indicesValue() const
})); }));
} }
int PeerColors::requiredLevelFor(PeerId channel, uint8 index) const {
if (Data::DecideColorIndex(channel) == index) {
return 0;
} else if (const auto i = _requiredLevels.find(index)
; i != end(_requiredLevels)) {
return i->second;
}
return 1;
}
void PeerColors::apply(const MTPDhelp_peerColors &data) { void PeerColors::apply(const MTPDhelp_peerColors &data) {
auto suggested = std::vector<uint8>(); auto suggested = std::vector<uint8>();
auto colors = std::make_shared< auto colors = std::make_shared<
@ -89,6 +100,7 @@ void PeerColors::apply(const MTPDhelp_peerColors &data) {
}; };
const auto &list = data.vcolors().v; const auto &list = data.vcolors().v;
_requiredLevels.clear();
suggested.reserve(list.size()); suggested.reserve(list.size());
for (const auto &color : list) { for (const auto &color : list) {
const auto &data = color.data(); const auto &data = color.data();
@ -98,6 +110,9 @@ void PeerColors::apply(const MTPDhelp_peerColors &data) {
continue; continue;
} }
const auto colorIndex = uint8(colorIndexBare); const auto colorIndex = uint8(colorIndexBare);
if (const auto min = data.vchannel_min_level()) {
_requiredLevels[colorIndex] = min->v;
}
if (!data.is_hidden()) { if (!data.is_hidden()) {
suggested.push_back(colorIndex); suggested.push_back(colorIndex);
} }

View file

@ -28,6 +28,10 @@ public:
[[nodiscard]] auto indicesValue() const [[nodiscard]] auto indicesValue() const
-> rpl::producer<Ui::ColorIndicesCompressed>; -> rpl::producer<Ui::ColorIndicesCompressed>;
[[nodiscard]] int requiredLevelFor(
PeerId channel,
uint8 index) const;
private: private:
void request(); void request();
void apply(const MTPDhelp_peerColors &data); void apply(const MTPDhelp_peerColors &data);
@ -38,6 +42,7 @@ private:
mtpRequestId _requestId = 0; mtpRequestId _requestId = 0;
base::Timer _timer; base::Timer _timer;
rpl::variable<std::vector<uint8>> _suggested; rpl::variable<std::vector<uint8>> _suggested;
base::flat_map<uint8, int> _requiredLevels;
rpl::event_stream<> _colorIndicesChanged; rpl::event_stream<> _colorIndicesChanged;
std::unique_ptr<Ui::ColorIndicesCompressed> _colorIndicesCurrent; std::unique_ptr<Ui::ColorIndicesCompressed> _colorIndicesCurrent;

View file

@ -612,6 +612,7 @@ rpl::producer<rpl::no_value, QString> Boosts::request() {
_peer->input _peer->input
)).done([=](const MTPpremium_BoostsStatus &result) { )).done([=](const MTPpremium_BoostsStatus &result) {
const auto &data = result.data(); const auto &data = result.data();
channel->updateLevelHint(data.vlevel().v);
const auto hasPremium = !!data.vpremium_audience(); const auto hasPremium = !!data.vpremium_audience();
const auto premiumMemberCount = hasPremium const auto premiumMemberCount = hasPremium
? std::max(0, int(data.vpremium_audience()->data().vpart().v)) ? std::max(0, int(data.vpremium_audience()->data().vpart().v))

View file

@ -452,8 +452,11 @@ void Set(
: tr::lng_settings_color_changed_channel(tr::now)); : tr::lng_settings_color_changed_channel(tr::now));
}; };
const auto fail = [=](const MTP::Error &error) { const auto fail = [=](const MTP::Error &error) {
setLocal(wasIndex, wasEmojiId); const auto type = error.type();
show->showToast(error.type()); if (type != u"CHAT_NOT_MODIFIED"_q) {
setLocal(wasIndex, wasEmojiId);
show->showToast(type);
}
}; };
const auto send = [&](auto &&request) { const auto send = [&](auto &&request) {
peer->session().api().request( peer->session().api().request(
@ -469,7 +472,7 @@ void Set(
} else if (const auto channel = peer->asChannel()) { } else if (const auto channel = peer->asChannel()) {
using Flag = MTPchannels_UpdateColor::Flag; using Flag = MTPchannels_UpdateColor::Flag;
send(MTPchannels_UpdateColor( send(MTPchannels_UpdateColor(
MTP_flags(Flag::f_background_emoji_id), MTP_flags(Flag::f_color | Flag::f_background_emoji_id),
channel->inputChannel, channel->inputChannel,
MTP_int(colorIndex), MTP_int(colorIndex),
MTP_long(backgroundEmojiId))); MTP_long(backgroundEmojiId)));
@ -509,9 +512,19 @@ void Apply(
peer->input peer->input
)).done([=](const MTPpremium_BoostsStatus &result) { )).done([=](const MTPpremium_BoostsStatus &result) {
const auto &data = result.data(); const auto &data = result.data();
const auto required = session->account().appConfig().get<int>( if (const auto channel = peer->asChannel()) {
"channel_color_level_min", channel->updateLevelHint(data.vlevel().v);
5); }
const auto peerColors = &peer->session().api().peerColors();
const auto colorRequired = peerColors->requiredLevelFor(
peer->id,
colorIndex);
const auto iconRequired = backgroundEmojiId
? session->account().appConfig().get<int>(
"channel_bg_icon_level_min",
5)
: 0;
const auto required = std::max(colorRequired, iconRequired);
if (data.vlevel().v >= required) { if (data.vlevel().v >= required) {
Set(show, peer, colorIndex, backgroundEmojiId); Set(show, peer, colorIndex, backgroundEmojiId);
close(); close();
@ -842,11 +855,12 @@ void AddPeerColorButton(
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
not_null<PeerData*> peer) { not_null<PeerData*> peer) {
auto label = peer->isSelf()
? tr::lng_settings_theme_name_color()
: tr::lng_edit_channel_color();
const auto button = AddButtonWithIcon( const auto button = AddButtonWithIcon(
container, container,
(peer->isSelf() rpl::duplicate(label),
? tr::lng_settings_theme_name_color()
: tr::lng_edit_channel_color()),
st::settingsColorButton, st::settingsColorButton,
{ &st::menuIconChangeColors }); { &st::menuIconChangeColors });
@ -873,7 +887,7 @@ void AddPeerColorButton(
rpl::combine( rpl::combine(
button->widthValue(), button->widthValue(),
tr::lng_settings_theme_name_color(), rpl::duplicate(label),
rpl::duplicate(colorIndexValue) rpl::duplicate(colorIndexValue)
) | rpl::start_with_next([=]( ) | rpl::start_with_next([=](
int width, int width,

View file

@ -1294,6 +1294,9 @@ void Controller::editReactions() {
_peer->input _peer->input
)).done([=](const MTPpremium_BoostsStatus &result) { )).done([=](const MTPpremium_BoostsStatus &result) {
_controls.levelRequested = false; _controls.levelRequested = false;
if (const auto channel = _peer->asChannel()) {
channel->updateLevelHint(result.data().vlevel().v);
}
const auto link = qs(result.data().vboost_url()); const auto link = qs(result.data().vboost_url());
const auto weak = base::make_weak(_navigation->parentController()); const auto weak = base::make_weak(_navigation->parentController());
auto counters = ParseBoostCounters(result); auto counters = ParseBoostCounters(result);

View file

@ -949,6 +949,14 @@ void ChannelData::processTopics(const MTPVector<MTPForumTopic> &topics) {
} }
} }
int ChannelData::levelHint() const {
return _levelHint;
}
void ChannelData::updateLevelHint(int levelHint) {
_levelHint = levelHint;
}
namespace Data { namespace Data {
void ApplyMigration( void ApplyMigration(

View file

@ -463,6 +463,9 @@ public:
void processTopics(const MTPVector<MTPForumTopic> &topics); void processTopics(const MTPVector<MTPForumTopic> &topics);
[[nodiscard]] int levelHint() const;
void updateLevelHint(int levelHint);
// Still public data members. // Still public data members.
uint64 access = 0; uint64 access = 0;
@ -497,6 +500,7 @@ private:
int _restrictedCount = 0; int _restrictedCount = 0;
int _kickedCount = 0; int _kickedCount = 0;
int _pendingRequestsCount = 0; int _pendingRequestsCount = 0;
int _levelHint = 0;
std::vector<UserId> _recentRequesters; std::vector<UserId> _recentRequesters;
MsgId _availableMinId = 0; MsgId _availableMinId = 0;

View file

@ -845,6 +845,7 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
const auto wasCallNotEmpty = Data::ChannelHasActiveCall(channel); const auto wasCallNotEmpty = Data::ChannelHasActiveCall(channel);
channel->updateLevelHint(data.vlevel().value_or_empty());
if (const auto count = data.vparticipants_count()) { if (const auto count = data.vparticipants_count()) {
channel->setMembersCount(count->v); channel->setMembersCount(count->v);
} }

View file

@ -467,15 +467,32 @@ void AskBoostBox(
box->addTopButton(st::boxTitleClose, [=] { box->closeBox(); }); box->addTopButton(st::boxTitleClose, [=] { box->closeBox(); });
auto title = v::is<AskBoostChannelColor>(data.reason.data) auto title = v::match(data.reason.data, [&](
? tr::lng_boost_channel_title_color() AskBoostChannelColor data) {
: tr::lng_boost_channel_title_reactions(); return tr::lng_boost_channel_title_color();
}, [&](AskBoostWallpaper data) {
return tr::lng_boost_channel_title_wallpaper();
}, [&](AskBoostEmojiStatus data) {
return tr::lng_boost_channel_title_status();
}, [&](AskBoostCustomReactions data) {
return tr::lng_boost_channel_title_reactions();
});
auto reasonText = v::match(data.reason.data, [&]( auto reasonText = v::match(data.reason.data, [&](
AskBoostChannelColor data) { AskBoostChannelColor data) {
return tr::lng_boost_channel_needs_level_color( return tr::lng_boost_channel_needs_level_color(
lt_count, lt_count,
rpl::single(float64(data.requiredLevel)), rpl::single(float64(data.requiredLevel)),
Ui::Text::RichLangValue); Ui::Text::RichLangValue);
}, [&](AskBoostWallpaper data) {
return tr::lng_boost_channel_needs_level_wallpaper(
lt_count,
rpl::single(float64(data.requiredLevel)),
Ui::Text::RichLangValue);
}, [&](AskBoostEmojiStatus data) {
return tr::lng_boost_channel_needs_level_status(
lt_count,
rpl::single(float64(data.requiredLevel)),
Ui::Text::RichLangValue);
}, [&](AskBoostCustomReactions data) { }, [&](AskBoostCustomReactions data) {
return tr::lng_boost_channel_needs_level_reactions( return tr::lng_boost_channel_needs_level_reactions(
lt_count, lt_count,

View file

@ -54,6 +54,14 @@ struct AskBoostChannelColor {
int requiredLevel = 0; int requiredLevel = 0;
}; };
struct AskBoostWallpaper {
int requiredLevel = 0;
};
struct AskBoostEmojiStatus {
int requiredLevel = 0;
};
struct AskBoostCustomReactions { struct AskBoostCustomReactions {
int count = 0; int count = 0;
}; };
@ -61,6 +69,8 @@ struct AskBoostCustomReactions {
struct AskBoostReason { struct AskBoostReason {
std::variant< std::variant<
AskBoostChannelColor, AskBoostChannelColor,
AskBoostWallpaper,
AskBoostEmojiStatus,
AskBoostCustomReactions> data; AskBoostCustomReactions> data;
}; };

View file

@ -623,6 +623,7 @@ void SessionNavigation::resolveBoostState(not_null<ChannelData*> channel) {
channel->input channel->input
)).done([=](const MTPpremium_BoostsStatus &result) { )).done([=](const MTPpremium_BoostsStatus &result) {
_boostStateResolving = nullptr; _boostStateResolving = nullptr;
channel->updateLevelHint(result.data().vlevel().v);
const auto submit = [=](Fn<void(Ui::BoostCounters)> done) { const auto submit = [=](Fn<void(Ui::BoostCounters)> done) {
applyBoost(channel, done); applyBoost(channel, done);
}; };
@ -730,6 +731,7 @@ void SessionNavigation::applyBoostsChecked(
_api.request(MTPpremium_GetBoostsStatus( _api.request(MTPpremium_GetBoostsStatus(
channel->input channel->input
)).done([=](const MTPpremium_BoostsStatus &result) { )).done([=](const MTPpremium_BoostsStatus &result) {
channel->updateLevelHint(result.data().vlevel().v);
done(ParseBoostCounters(result)); done(ParseBoostCounters(result));
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
showToast(u"Error: "_q + error.type()); showToast(u"Error: "_q + error.type());