diff --git a/Telegram/Resources/animations/ban.tgs b/Telegram/Resources/animations/ban.tgs new file mode 100644 index 0000000000..1ac1aaa8a4 Binary files /dev/null and b/Telegram/Resources/animations/ban.tgs differ diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 34e0b4591e..87ba31c8c9 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -51,6 +51,7 @@ ../../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 {