From f31337ecb5d5590f586d67bf5507e582e2c52935 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 22 Dec 2025 11:25:31 +0300 Subject: [PATCH] Improved style of box for denied unconfirmed authentications. --- Telegram/Resources/animations/ban.tgs | Bin 0 -> 2283 bytes .../Resources/qrc/telegram/animations.qrc | 1 + Telegram/SourceFiles/dialogs/dialogs.style | 3 + .../dialogs/dialogs_top_bar_suggestion.cpp | 16 +- .../ui/dialogs_top_bar_suggestion_content.cpp | 149 +++++++++++++++++- .../ui/dialogs_top_bar_suggestion_content.h | 6 + 6 files changed, 157 insertions(+), 18 deletions(-) create mode 100644 Telegram/Resources/animations/ban.tgs diff --git a/Telegram/Resources/animations/ban.tgs b/Telegram/Resources/animations/ban.tgs new file mode 100644 index 0000000000000000000000000000000000000000..1ac1aaa8a493a99160d772a7739224a08435cc68 GIT binary patch literal 2283 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../../animations/show_or_premium_lastseen.tgs ../../animations/show_or_premium_readtime.tgs ../../animations/passkeys.tgs + ../../animations/ban.tgs ../../animations/profile/profile_muting.tgs ../../animations/profile/profile_unmuting.tgs diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index a85d68fc2e..31a96f5737 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -842,6 +842,9 @@ dialogsTopBarSuggestionTitleStyle: TextStyle(defaultTextStyle) { dialogsTopBarSuggestionAboutStyle: TextStyle(defaultTextStyle) { font: font(11px); } +dialogsSuggestionDeniedAuthLottie: size(70px, 70px); +dialogsSuggestionDeniedAuthLottieCircle: size(90px, 90px); +dialogsSuggestionDeniedAuthLottieMargins: margins(10px, 10px, 10px, 10px); dialogsMiniQuoteIcon: icon{{ "chat/mini_quote", dialogsTextFg }}; diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp index 83292cec59..b8d344bb47 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp @@ -130,21 +130,7 @@ void ShowAuthToast( } if (const auto controller = FindSessionController(parent)) { const auto count = float64(list.size()); - controller->show(Box([=](not_null box) { - box->setTitle(tr::lng_unconfirmed_auth_denied_title( - lt_count, - rpl::single(count))); - Ui::InformBox(box, { - .text = TextWithEntities() - .append(messageText) - .append('\n') - .append( - tr::lng_unconfirmed_auth_denied_warning( - tr::now, - tr::bold)), - .confirmText = tr::lng_archive_hint_button(tr::now), - }); - })); + controller->show(Box(ShowAuthDeniedBox, count, messageText)); } } } diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp index ac59323a92..b88b8886d7 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp @@ -10,8 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/call_delayed.h" #include "data/data_authorization.h" #include "lang/lang_keys.h" -#include "ui/rect.h" +#include "lottie/lottie_icon.h" +#include "settings/settings_common.h" +#include "ui/effects/animation_value.h" +#include "ui/layers/generic_box.h" +#include "ui/painter.h" #include "ui/power_saving.h" +#include "ui/rect.h" #include "ui/text/format_values.h" #include "ui/text/text_custom_emoji.h" #include "ui/ui_rpl_filter.h" @@ -25,11 +30,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" #include "styles/style_boxes.h" -#include "styles/style_chat.h" #include "styles/style_chat_helpers.h" +#include "styles/style_chat.h" #include "styles/style_dialogs.h" -#include "styles/style_settings.h" #include "styles/style_layers.h" +#include "styles/style_premium.h" +#include "styles/style_settings.h" namespace Dialogs { @@ -156,6 +162,143 @@ not_null*> CreateUnconfirmedAuthContent( return wrap; } +void ShowAuthDeniedBox( + not_null box, + float64 count, + const QString &messageText) { + box->setStyle(st::showOrBox); + box->setWidth(st::boxWideWidth); + const auto buttonPadding = QMargins( + st::showOrBox.buttonPadding.left(), + 0, + st::showOrBox.buttonPadding.right(), + 0); + auto icon = Settings::CreateLottieIcon( + box, + { + .name = u"ban"_q, + .sizeOverride = st::dialogsSuggestionDeniedAuthLottie, + }, + st::dialogsSuggestionDeniedAuthLottieMargins); + Settings::AddLottieIconWithCircle( + box->verticalLayout(), + std::move(icon.widget), + st::settingsBlockedListIconPadding, + st::dialogsSuggestionDeniedAuthLottieCircle); + box->setShowFinishedCallback([=, animate = std::move(icon.animate)] { + animate(anim::repeat::once); + }); + Ui::AddSkip(box->verticalLayout()); + box->addRow( + object_ptr( + box, + tr::lng_unconfirmed_auth_denied_title( + lt_count, + rpl::single(count)), + st::boostCenteredTitle), + st::showOrTitlePadding + buttonPadding, + style::al_top); + Ui::AddSkip(box->verticalLayout()); + box->addRow( + object_ptr( + box, + messageText, + st::boostText), + st::showOrAboutPadding + buttonPadding, + style::al_top); + Ui::AddSkip(box->verticalLayout()); + const auto warning = box->addRow( + object_ptr( + box, + tr::lng_unconfirmed_auth_denied_warning(tr::bold), + st::boostText), + st::showOrAboutPadding + buttonPadding + + QMargins(st::boostTextSkip, 0, st::boostTextSkip, 0), + style::al_top); + warning->setTextColorOverride(st::attentionButtonFg->c); + const auto warningBg = Ui::CreateChild( + box->verticalLayout()); + warning->geometryValue() | rpl::on_next([=](QRect r) { + warningBg->setGeometry(r + Margins(st::boostTextSkip)); + }, warningBg->lifetime()); + warningBg->paintOn([=](QPainter &p) { + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(st::attentionButtonBgOver); + p.drawRoundedRect( + warningBg->rect(), + st::buttonRadius, + st::buttonRadius); + }); + warningBg->show(); + warning->raise(); + warningBg->stackUnder(warning); + const auto confirm = box->addButton( + object_ptr( + box, + rpl::single(QString()), + st::defaultActiveButton)); + confirm->setClickedCallback([=] { + box->closeBox(); + }); + confirm->resize( + st::showOrShowButton.width, + st::showOrShowButton.height); + + const auto textLabel = Ui::CreateChild( + confirm, + tr::lng_archive_hint_button(), + st::defaultSubsectionTitle); + textLabel->setTextColorOverride(st::defaultActiveButton.textFg->c); + textLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + + const auto timerLabel = Ui::CreateChild( + confirm, + rpl::single(QString()), + st::defaultSubsectionTitle); + timerLabel->setTextColorOverride( + anim::with_alpha(st::defaultActiveButton.textFg->c, 0.75)); + timerLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + + constexpr auto kTimer = 5; + const auto remaining = confirm->lifetime().make_state(kTimer); + const auto timerLifetime + = confirm->lifetime().make_state(); + const auto timer = timerLifetime->make_state([=] { + if ((*remaining) > 0) { + timerLabel->setText(QString::number((*remaining)--)); + } else { + timerLabel->hide(); + confirm->setAttribute(Qt::WA_TransparentForMouseEvents, false); + box->setCloseByEscape(true); + box->setCloseByOutsideClick(true); + timerLifetime->destroy(); + } + }); + box->setCloseByEscape(false); + box->setCloseByOutsideClick(false); + confirm->setAttribute(Qt::WA_TransparentForMouseEvents, true); + timerLabel->setText(QString::number((*remaining))); + timer->callEach(1000); + + rpl::combine( + confirm->sizeValue(), + textLabel->sizeValue(), + timerLabel->sizeValue(), + timerLabel->shownValue() + ) | rpl::on_next([=](QSize btn, QSize text, QSize timer, bool shown) { + const auto skip = st::normalFont->spacew; + const auto totalWidth = shown + ? (text.width() + skip + timer.width()) + : text.width(); + const auto left = (btn.width() - totalWidth) / 2; + textLabel->moveToLeft(left, (btn.height() - text.height()) / 2); + timerLabel->moveToLeft( + left + text.width() + skip, + (btn.height() - timer.height()) / 2); + }, confirm->lifetime()); +} + TopBarSuggestionContent::TopBarSuggestionContent( not_null parent, Fn emojiPaused) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h index 1d3fead439..6e5d824da5 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class DynamicImage; +class GenericBox; class IconButton; class VerticalLayout; template @@ -32,6 +33,11 @@ not_null*> CreateUnconfirmedAuthContent( const std::vector &list, Fn callback); +void ShowAuthDeniedBox( + not_null box, + float64 count, + const QString &messageText); + class TopBarSuggestionContent : public Ui::RippleButton { public: enum class RightIcon {