From acd10b1e1dcecc407c0dd06df95c0436c75df4cd Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 9 Apr 2026 10:57:43 +0300 Subject: [PATCH] Added subscriber-only poll restrictions in creation flow and MTProto flags --- .../poll/filled/filled_poll_subscribers.svg | 7 +++++ Telegram/Resources/langs/lang.strings | 2 ++ .../SourceFiles/boxes/create_poll_box.cpp | 27 ++++++++++++++++--- Telegram/SourceFiles/boxes/polls.style | 1 + Telegram/SourceFiles/data/data_poll.cpp | 11 +++++++- Telegram/SourceFiles/data/data_poll.h | 2 ++ 6 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 Telegram/Resources/icons/poll/filled/filled_poll_subscribers.svg diff --git a/Telegram/Resources/icons/poll/filled/filled_poll_subscribers.svg b/Telegram/Resources/icons/poll/filled/filled_poll_subscribers.svg new file mode 100644 index 0000000000..52b73e4d19 --- /dev/null +++ b/Telegram/Resources/icons/poll/filled/filled_poll_subscribers.svg @@ -0,0 +1,7 @@ + + + Filled / filled_poll_subscribers + + + + diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 9363db85fa..4af5e88359 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -6995,6 +6995,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_polls_create_poll_ends" = "Poll ends"; "lng_polls_create_hide_results" = "Hide results"; "lng_polls_create_hide_results_about" = "If you switch this on, results will appear only after the poll closes."; +"lng_polls_create_restrict_to_subscribers" = "Restrict to Subscribers"; +"lng_polls_create_restrict_to_subscribers_about" = "Only subscribers who joined 24+ hours ago can vote."; "lng_polls_create_duration_custom" = "Custom"; "lng_polls_create_deadline_title" = "Deadline"; "lng_polls_create_deadline_button" = "Set Deadline"; diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index bbd253a4d2..5266267e82 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -2537,6 +2537,7 @@ object_ptr CreatePollBox::setupContent() { Ui::AddSkip(container); Ui::AddSubsectionTitle(container, tr::lng_polls_create_settings()); + const auto isBroadcastChannel = _peer->isChannel(); const auto showWhoVoted = (!(_disabled & PollData::Flag::PublicVotes)) ? AddPollToggleButton( @@ -2732,10 +2733,18 @@ object_ptr CreatePollBox::setupContent() { st::settingsButtonNoIcon) )->toggleOn(rpl::single(false)); - Ui::AddSkip(durationInner); - Ui::AddDividerText( - durationInner, - tr::lng_polls_create_hide_results_about()); + const auto restrictToSubscribers = isBroadcastChannel + ? AddPollToggleButton( + container, + tr::lng_polls_create_restrict_to_subscribers(), + tr::lng_polls_create_restrict_to_subscribers_about(), + { + .icon = &st::pollBoxFilledPollSubscribersIcon, + .background = &st::settingsIconBg4, + }, + rpl::single(!!(_chosen & PollData::Flag::SubscribersOnly)), + st::detailedSettingsButtonStyle).get() + : nullptr; const auto solution = setupSolution( container, @@ -2775,6 +2784,10 @@ object_ptr CreatePollBox::setupContent() { }; quiz->setToggleLocked(_disabled & PollData::Flag::Quiz); shuffle->setToggleLocked(_disabled & PollData::Flag::ShuffleAnswers); + if (restrictToSubscribers) { + restrictToSubscribers->setToggleLocked( + _disabled & PollData::Flag::SubscribersOnly); + } updateQuizDependentLocks(quiz->toggled()); using namespace rpl::mappers; @@ -2862,6 +2875,8 @@ object_ptr CreatePollBox::setupContent() { } const auto publicVotes = (showWhoVoted && showWhoVoted->toggled()); const auto multiChoice = multiple->toggled(); + const auto subscribersOnly = (restrictToSubscribers + && restrictToSubscribers->toggled()); const auto hideResultsEnabled = duration->toggled() && hideResults->toggled(); result.setFlags(Flag(0) @@ -2871,6 +2886,7 @@ object_ptr CreatePollBox::setupContent() { | (!revoting->toggled() ? Flag::RevotingDisabled : Flag(0)) | (shuffle->toggled() ? Flag::ShuffleAnswers : Flag(0)) | (quiz->toggled() ? Flag::Quiz : Flag(0)) + | (subscribersOnly ? Flag::SubscribersOnly : Flag(0)) | (hideResultsEnabled ? Flag::HideResultsUntilClose : Flag(0))); @@ -3049,6 +3065,9 @@ object_ptr CreatePollBox::setupContent() { duration->finishAnimating(); durationWrap->finishAnimating(); hideResults->finishAnimating(); + if (restrictToSubscribers) { + restrictToSubscribers->finishAnimating(); + } return result; } diff --git a/Telegram/SourceFiles/boxes/polls.style b/Telegram/SourceFiles/boxes/polls.style index b68834fc16..c1846047b2 100644 --- a/Telegram/SourceFiles/boxes/polls.style +++ b/Telegram/SourceFiles/boxes/polls.style @@ -136,6 +136,7 @@ pollBoxFilledPollCorrectIcon: icon{{ "poll/filled/filled_poll_correct", activeBu pollBoxFilledPollRevoteIcon: icon{{ "poll/filled/filled_poll_revote", activeButtonFg }}; pollBoxFilledPollShuffleIcon: icon{{ "poll/filled/filled_poll_shuffle", activeButtonFg }}; pollBoxFilledPollMultipleIcon: icon{{ "poll/filled/filled_poll_multiple", activeButtonFg }}; +pollBoxFilledPollSubscribersIcon: icon{{ "poll/filled/filled_poll_subscribers-20x20", activeButtonFg }}; pollAttachTextSkip: 28px; pollAttachProgressMargin: 4px; diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index 8ef9149883..583377f3bf 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -105,7 +105,8 @@ bool PollData::applyChanges(const MTPDpoll &poll) { | (poll.is_hide_results_until_close() ? Flag::HideResultsUntilClose : Flag(0)) - | (poll.is_creator() ? Flag::Creator : Flag(0)); + | (poll.is_creator() ? Flag::Creator : Flag(0)) + | (poll.is_subscribers_only() ? Flag::SubscribersOnly : Flag(0)); const auto newCloseDate = poll.vclose_date().value_or_empty(); const auto newClosePeriod = poll.vclose_period().value_or_empty(); auto newAnswers = ranges::views::all( @@ -368,6 +369,10 @@ bool PollData::creator() const { return (_flags & Flag::Creator); } +bool PollData::subscribersOnly() const { + return (_flags & Flag::SubscribersOnly); +} + QString PollData::debugString() const { auto result = QString(); result += u"Poll #"_q + QString::number(id) + u'\n'; @@ -384,6 +389,9 @@ QString PollData::debugString() const { if (publicVotes()) { result += u"[PublicVotes]"_q; } + if (subscribersOnly()) { + result += u"[SubscribersOnly]"_q; + } if (!result.endsWith(u'\n')) { result += u'\n'; } @@ -531,6 +539,7 @@ MTPPoll PollDataToMTP(not_null poll, bool close) { | (poll->hideResultsUntilClose() ? Flag::f_hide_results_until_close : Flag(0)) + | (poll->subscribersOnly() ? Flag::f_subscribers_only : Flag(0)) | (poll->closePeriod > 0 ? Flag::f_close_period : Flag(0)) | (poll->closeDate > 0 ? Flag::f_close_date : Flag(0)); return MTP_poll( diff --git a/Telegram/SourceFiles/data/data_poll.h b/Telegram/SourceFiles/data/data_poll.h index 03760f8771..cbc7d3713b 100644 --- a/Telegram/SourceFiles/data/data_poll.h +++ b/Telegram/SourceFiles/data/data_poll.h @@ -76,6 +76,7 @@ struct PollData { OpenAnswers = 0x040, HideResultsUntilClose = 0x080, Creator = 0x100, + SubscribersOnly = 0x200, }; friend inline constexpr bool is_flag_type(Flag) { return true; }; using Flags = base::flags; @@ -101,6 +102,7 @@ struct PollData { [[nodiscard]] bool openAnswers() const; [[nodiscard]] bool hideResultsUntilClose() const; [[nodiscard]] bool creator() const; + [[nodiscard]] bool subscribersOnly() const; [[nodiscard]] QString debugString() const;