From 5718789d537c41e2454079e795c339c90e14892e Mon Sep 17 00:00:00 2001
From: 23rd <23rd@vivaldi.net>
Date: Sun, 27 Feb 2022 11:23:20 +0300
Subject: [PATCH] Replaced Ui::InformBox and Ui::ConfirmBox with GenericBox.

---
 Telegram/Resources/langs/lang.strings         |   2 +-
 .../SourceFiles/api/api_attached_stickers.cpp |   4 +-
 Telegram/SourceFiles/api/api_bot.cpp          |   2 +-
 Telegram/SourceFiles/api/api_chat_invite.cpp  |   3 +-
 .../SourceFiles/api/api_confirm_phone.cpp     |   4 +-
 Telegram/SourceFiles/api/api_editing.cpp      |   3 +-
 Telegram/SourceFiles/api/api_updates.cpp      |   2 +-
 Telegram/SourceFiles/apiwrap.cpp              |  17 +--
 Telegram/SourceFiles/boxes/about_box.cpp      |   7 +-
 .../SourceFiles/boxes/add_contact_box.cpp     |  30 ++--
 Telegram/SourceFiles/boxes/add_contact_box.h  |   1 -
 Telegram/SourceFiles/boxes/background_box.cpp |  10 +-
 .../boxes/background_preview_box.cpp          |   6 +-
 .../SourceFiles/boxes/change_phone_box.cpp    |  12 +-
 Telegram/SourceFiles/boxes/connection_box.cpp |  11 +-
 Telegram/SourceFiles/boxes/passcode_box.cpp   | 117 +++++++--------
 .../boxes/peer_list_controllers.cpp           |   9 +-
 .../boxes/peers/add_participants_box.cpp      |  63 +++++----
 .../boxes/peers/edit_linked_chat_box.cpp      |  18 +--
 .../boxes/peers/edit_participant_box.cpp      |  11 +-
 .../boxes/peers/edit_participants_box.cpp     |  20 +--
 .../boxes/peers/edit_peer_info_box.cpp        |  11 +-
 .../boxes/peers/edit_peer_invite_link.cpp     |  54 +++----
 .../boxes/peers/edit_peer_invite_links.cpp    |  19 +--
 .../SourceFiles/boxes/phone_banned_box.cpp    |  16 ++-
 Telegram/SourceFiles/boxes/sessions_box.cpp   |  13 +-
 Telegram/SourceFiles/boxes/share_box.cpp      |  10 +-
 .../SourceFiles/boxes/sticker_set_box.cpp     |   2 +-
 Telegram/SourceFiles/boxes/sticker_set_box.h  |   1 -
 Telegram/SourceFiles/boxes/stickers_box.h     |   1 -
 Telegram/SourceFiles/calls/calls_call.cpp     |   4 +-
 Telegram/SourceFiles/calls/calls_instance.cpp |  13 +-
 .../calls/group/calls_group_rtmp.cpp          |  26 ++--
 .../chat_helpers/stickers_list_widget.cpp     | 133 +++++++++---------
 Telegram/SourceFiles/core/application.cpp     |  29 ++--
 .../SourceFiles/core/click_handler_types.cpp  |  18 +--
 .../SourceFiles/core/local_url_handlers.cpp   |  11 +-
 .../SourceFiles/data/data_cloud_themes.cpp    |   6 +-
 Telegram/SourceFiles/data/data_document.cpp   |   7 +-
 .../data/stickers/data_stickers.cpp           |   2 +-
 Telegram/SourceFiles/editor/editor_paint.cpp  |   2 +-
 .../editor/photo_editor_layer_widget.cpp      |   2 +-
 .../view/export_view_panel_controller.cpp     |  13 +-
 Telegram/SourceFiles/facades.cpp              |  14 +-
 .../admin_log/history_admin_log_inner.cpp     |   2 +-
 .../admin_log/history_admin_log_section.cpp   |   6 +-
 .../SourceFiles/history/history_message.cpp   |   2 +-
 .../SourceFiles/history/history_widget.cpp    |  54 ++++---
 .../history_view_compose_controls.cpp         |   8 +-
 .../history_view_voice_record_bar.cpp         |  13 +-
 .../view/history_view_contact_status.cpp      |  24 ++--
 .../view/history_view_context_menu.cpp        |  11 +-
 .../view/history_view_replies_section.cpp     |  15 +-
 .../view/history_view_scheduled_section.cpp   |  15 +-
 .../info/media/info_media_list_widget.cpp     |  11 +-
 Telegram/SourceFiles/intro/intro_code.cpp     |   9 +-
 .../intro/intro_password_check.cpp            |  27 ++--
 Telegram/SourceFiles/intro/intro_phone.cpp    |   2 +-
 Telegram/SourceFiles/intro/intro_qr.cpp       |   9 +-
 Telegram/SourceFiles/intro/intro_signup.cpp   |   2 +-
 Telegram/SourceFiles/intro/intro_step.cpp     |   2 +-
 Telegram/SourceFiles/intro/intro_widget.cpp   |  19 +--
 .../SourceFiles/lang/lang_cloud_manager.cpp   |  40 +++---
 Telegram/SourceFiles/mainwidget.cpp           |  20 ++-
 Telegram/SourceFiles/mainwindow.cpp           |   2 +-
 .../media/view/media_view_overlay_widget.cpp  |  11 +-
 .../passport/passport_form_controller.cpp     |  31 ++--
 .../passport/passport_panel_controller.cpp    |  66 +++++----
 .../mac/touchbar/items/mac_scrubber_item.mm   |   2 +-
 .../SourceFiles/platform/win/specific_win.cpp |  12 +-
 .../profile/profile_block_group_members.cpp   |   9 +-
 .../settings/settings_advanced.cpp            |  24 ++--
 .../SourceFiles/settings/settings_calls.cpp   |  11 +-
 .../SourceFiles/settings/settings_chat.cpp    |   8 +-
 .../SourceFiles/settings/settings_codes.cpp   |  22 +--
 .../settings/settings_experimental.cpp        |  11 +-
 .../SourceFiles/settings/settings_main.cpp    |  26 ++--
 .../settings/settings_privacy_controllers.cpp |  10 +-
 .../settings/settings_privacy_security.cpp    |  20 +--
 .../SourceFiles/storage/localimageloader.cpp  |   4 +-
 .../window/themes/window_theme.cpp            |   9 +-
 .../window/themes/window_theme_editor.cpp     |  21 ++-
 .../window/themes/window_theme_editor_box.cpp |   2 +-
 .../themes/window_themes_cloud_list.cpp       |   9 +-
 .../SourceFiles/window/window_controller.cpp  |  22 +--
 .../window/window_filters_menu.cpp            |   9 +-
 .../SourceFiles/window/window_main_menu.cpp   |  15 +-
 .../SourceFiles/window/window_peer_menu.cpp   |  94 ++++++++-----
 .../window/window_session_controller.cpp      |  29 ++--
 89 files changed, 796 insertions(+), 733 deletions(-)

diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 3f8fe10b0..838462741 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -2392,7 +2392,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_group_call_rtmp_key_subtitle" = "Stream Key";
 "lng_group_call_rtmp_key_copy" = "Copy Stream Key";
 "lng_group_call_rtmp_key_copied" = "Stream Key copied to clipboard.";
-"lng_group_call_rtmp_key_warn" = "Never share your Stream Key with anyone or show it on stream!";
+"lng_group_call_rtmp_key_warning" = "**Never share your Stream Key with anyone or show it on stream!**";
 "lng_group_call_rtmp_info" = "To stream video with another app, enter these Server URL and Stream Key in your streaming app.\n\nOnce you start broadcasting in your streaming app, tap Start Streaming below";
 "lng_group_call_rtmp_start" = "Start Streaming";
 "lng_group_call_rtmp_revoke_sure" = "Are you sure you want to revoke your Server URL and Stream Key?";
diff --git a/Telegram/SourceFiles/api/api_attached_stickers.cpp b/Telegram/SourceFiles/api/api_attached_stickers.cpp
index 1aa455963..e80e03e6e 100644
--- a/Telegram/SourceFiles/api/api_attached_stickers.cpp
+++ b/Telegram/SourceFiles/api/api_attached_stickers.cpp
@@ -37,7 +37,7 @@ void AttachedStickers::request(
 		}
 		if (result.v.isEmpty()) {
 			strongController->show(
-				Box<Ui::InformBox>(tr::lng_stickers_not_found(tr::now)));
+				Ui::MakeInformBox(tr::lng_stickers_not_found()));
 			return;
 		} else if (result.v.size() > 1) {
 			strongController->show(
@@ -63,7 +63,7 @@ void AttachedStickers::request(
 		_requestId = 0;
 		if (const auto strongController = weak.get()) {
 			strongController->show(
-				Box<Ui::InformBox>(tr::lng_stickers_not_found(tr::now)));
+				Ui::MakeInformBox(tr::lng_stickers_not_found()));
 		}
 	}).send();
 }
diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp
index 4bf5b79fb..80bec3cf8 100644
--- a/Telegram/SourceFiles/api/api_bot.cpp
+++ b/Telegram/SourceFiles/api/api_bot.cpp
@@ -100,7 +100,7 @@ void SendBotCallbackData(
 
 		if (!message.isEmpty()) {
 			if (showAlert) {
-				Ui::show(Box<Ui::InformBox>(message));
+				Ui::show(Ui::MakeInformBox(message));
 			} else {
 				if (withPassword) {
 					Ui::hideLayer();
diff --git a/Telegram/SourceFiles/api/api_chat_invite.cpp b/Telegram/SourceFiles/api/api_chat_invite.cpp
index dc3e557bc..69e01639c 100644
--- a/Telegram/SourceFiles/api/api_chat_invite.cpp
+++ b/Telegram/SourceFiles/api/api_chat_invite.cpp
@@ -86,8 +86,7 @@ void CheckChatInvite(
 		}
 		Core::App().hideMediaView();
 		if (const auto strong = weak.get()) {
-			strong->show(
-				Box<Ui::InformBox>(tr::lng_group_invite_bad_link(tr::now)));
+			strong->show(Ui::MakeInformBox(tr::lng_group_invite_bad_link()));
 		}
 	});
 }
diff --git a/Telegram/SourceFiles/api/api_confirm_phone.cpp b/Telegram/SourceFiles/api/api_confirm_phone.cpp
index 0db192021..224f06b4f 100644
--- a/Telegram/SourceFiles/api/api_confirm_phone.cpp
+++ b/Telegram/SourceFiles/api/api_confirm_phone.cpp
@@ -86,7 +86,7 @@ void ConfirmPhone::resolve(
 				)).done([=] {
 					_checkRequestId = 0;
 					controller->show(
-						Box<Ui::InformBox>(
+						Ui::MakeInformBox(
 							tr::lng_confirm_phone_success(
 								tr::now,
 								lt_phone,
@@ -120,7 +120,7 @@ void ConfirmPhone::resolve(
 			? tr::lng_confirm_phone_link_invalid(tr::now)
 			: Lang::Hard::ServerError();
 		controller->show(
-			Box<Ui::InformBox>(errorText),
+			Ui::MakeInformBox(errorText),
 			Ui::LayerOption::CloseOther);
 	}).handleFloodErrors().send();
 }
diff --git a/Telegram/SourceFiles/api/api_editing.cpp b/Telegram/SourceFiles/api/api_editing.cpp
index 46a120c54..b529eca4c 100644
--- a/Telegram/SourceFiles/api/api_editing.cpp
+++ b/Telegram/SourceFiles/api/api_editing.cpp
@@ -149,8 +149,7 @@ void EditMessageWithUploadedMedia(
 			session->data().sendHistoryChangeNotifications();
 			if (mediaInvalid) {
 				Ui::show(
-					Box<Ui::InformBox>(
-						tr::lng_edit_media_invalid_file(tr::now)),
+					Ui::MakeInformBox(tr::lng_edit_media_invalid_file()),
 					Ui::LayerOption::KeepOther);
 			}
 		} else {
diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp
index 7bb3faa0a..e2370360e 100644
--- a/Telegram/SourceFiles/api/api_updates.cpp
+++ b/Telegram/SourceFiles/api/api_updates.cpp
@@ -2021,7 +2021,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
 		} else if (d.is_popup()) {
 			const auto &windows = session().windows();
 			if (!windows.empty()) {
-				windows.front()->window().show(Box<Ui::InformBox>(text));
+				windows.front()->window().show(Ui::MakeInformBox(text));
 			}
 		} else {
 			session().data().serviceNotification(text, d.vmedia());
diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp
index ef7e7fd11..59d9e3e32 100644
--- a/Telegram/SourceFiles/apiwrap.cpp
+++ b/Telegram/SourceFiles/apiwrap.cpp
@@ -466,17 +466,18 @@ void ApiWrap::sendMessageFail(
 		uint64 randomId,
 		FullMsgId itemId) {
 	if (error.type() == qstr("PEER_FLOOD")) {
-		Ui::show(Box<Ui::InformBox>(
+		Ui::show(Ui::MakeInformBox(
 			PeerFloodErrorText(&session(), PeerFloodType::Send)));
 	} else if (error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
 		const auto link = Ui::Text::Link(
 			tr::lng_cant_more_info(tr::now),
 			session().createInternalLinkFull(qsl("spambot")));
-		Ui::show(Box<Ui::InformBox>(tr::lng_error_public_groups_denied(
-			tr::now,
-			lt_more_info,
-			link,
-			Ui::Text::WithEntities)));
+		Ui::show(Ui::MakeInformBox(
+			tr::lng_error_public_groups_denied(
+				tr::now,
+				lt_more_info,
+				link,
+				Ui::Text::WithEntities)));
 	} else if (error.type().startsWith(qstr("SLOWMODE_WAIT_"))) {
 		const auto chop = qstr("SLOWMODE_WAIT_").size();
 		const auto left = base::StringViewMid(error.type(), chop).toInt();
@@ -494,7 +495,7 @@ void ApiWrap::sendMessageFail(
 		Assert(peer->isUser());
 		if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) {
 			scheduled.removeSending(item);
-			Ui::show(Box<Ui::InformBox>(tr::lng_cant_do_this(tr::now)));
+			Ui::show(Ui::MakeInformBox(tr::lng_cant_do_this()));
 		}
 	} else if (error.type() == qstr("CHAT_FORWARDS_RESTRICTED")) {
 		Ui::ShowMultilineToast({ .text = { peer->isBroadcast()
@@ -1275,7 +1276,7 @@ void ApiWrap::migrateDone(
 
 void ApiWrap::migrateFail(not_null<PeerData*> peer, const QString &error) {
 	if (error == u"CHANNELS_TOO_MUCH"_q) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_migrate_error(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_migrate_error()));
 	}
 	if (auto handlers = _migrateCallbacks.take(peer)) {
 		for (auto &handler : *handlers) {
diff --git a/Telegram/SourceFiles/boxes/about_box.cpp b/Telegram/SourceFiles/boxes/about_box.cpp
index 7e97faa85..51b85471e 100644
--- a/Telegram/SourceFiles/boxes/about_box.cpp
+++ b/Telegram/SourceFiles/boxes/about_box.cpp
@@ -110,8 +110,11 @@ void AboutBox::showVersionHistory() {
 
 		QGuiApplication::clipboard()->setText(url);
 
-		Ui::show(Box<Ui::InformBox>("The link to the current private alpha "
-			"version of Telegram Desktop was copied to the clipboard."));
+		getDelegate()->show(
+			Ui::MakeInformBox(
+				"The link to the current private alpha "
+				"version of Telegram Desktop was copied to the clipboard."),
+			Ui::LayerOption::CloseOther);
 	} else {
 		UrlClickHandler::Open(Core::App().changelogLink());
 	}
diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp
index 73623d4f0..947ca2794 100644
--- a/Telegram/SourceFiles/boxes/add_contact_box.cpp
+++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp
@@ -161,11 +161,11 @@ void ShowAddParticipantsError(
 				*weak = Ui::show(std::move(box));
 			};
 			Ui::show(
-				Box<Ui::ConfirmBox>(
-					tr::lng_cant_invite_offer_admin(tr::now),
-					tr::lng_cant_invite_make_admin(tr::now),
-					tr::lng_cancel(tr::now),
-					makeAdmin),
+				Ui::MakeConfirmBox({
+					.text = tr::lng_cant_invite_offer_admin(),
+					.confirmed = makeAdmin,
+					.confirmText = tr::lng_cant_invite_make_admin(),
+				}),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -176,7 +176,7 @@ void ShowAddParticipantsError(
 			? PeerFloodType::InviteGroup
 			: PeerFloodType::InviteChannel;
 		const auto text = PeerFloodErrorText(&chat->session(), type);
-		Ui::show(Box<Ui::InformBox>(text), Ui::LayerOption::KeepOther);
+		Ui::show(Ui::MakeInformBox(text), Ui::LayerOption::KeepOther);
 		return;
 	}
 	const auto text = [&] {
@@ -203,7 +203,7 @@ void ShowAddParticipantsError(
 		}
 		return tr::lng_failed_add_participant(tr::now);
 	}();
-	Ui::show(Box<Ui::InformBox>(text), Ui::LayerOption::KeepOther);
+	Ui::show(Ui::MakeInformBox(text), Ui::LayerOption::KeepOther);
 }
 
 class RevokePublicLinkBox::Inner : public TWidget {
@@ -656,18 +656,18 @@ void GroupInfoBox::createGroup(
 			}
 		} else if (type == u"USERS_TOO_FEW"_q) {
 			controller->show(
-				Box<Ui::InformBox>(tr::lng_cant_invite_privacy(tr::now)),
+				Ui::MakeInformBox(tr::lng_cant_invite_privacy()),
 				Ui::LayerOption::KeepOther);
 		} else if (type == u"PEER_FLOOD"_q) {
 			controller->show(
-				Box<Ui::InformBox>(
+				Ui::MakeInformBox(
 					PeerFloodErrorText(
 						&_navigation->session(),
 						PeerFloodType::InviteGroup)),
 				Ui::LayerOption::KeepOther);
 		} else if (type == u"USER_RESTRICTED"_q) {
 			controller->show(
-				Box<Ui::InformBox>(tr::lng_cant_do_this(tr::now)),
+				Ui::MakeInformBox(tr::lng_cant_do_this()),
 				Ui::LayerOption::KeepOther);
 		}
 	}).send();
@@ -778,11 +778,11 @@ void GroupInfoBox::createChannel(
 			_title->showError();
 		} else if (type == u"USER_RESTRICTED"_q) {
 			controller->show(
-				Box<Ui::InformBox>(tr::lng_cant_do_this(tr::now)),
+				Ui::MakeInformBox(tr::lng_cant_do_this()),
 				Ui::LayerOption::CloseOther);
 		} else if (type == u"CHANNELS_TOO_MUCH"_q) {
 			controller->show(
-				Box<Ui::InformBox>(tr::lng_cant_do_this(tr::now)),
+				Ui::MakeInformBox(tr::lng_cant_do_this()),
 				Ui::LayerOption::CloseOther); // TODO
 		}
 	}).send();
@@ -1649,7 +1649,11 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
 			}).send();
 		});
 		Ui::show(
-			Box<Ui::ConfirmBox>(text, confirmText, std::move(callback)),
+			Ui::MakeConfirmBox({
+				.text = text,
+				.confirmed = std::move(callback),
+				.confirmText = confirmText,
+			}),
 			Ui::LayerOption::KeepOther);
 	}
 }
diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h
index 92ff1ab46..35bd39bf2 100644
--- a/Telegram/SourceFiles/boxes/add_contact_box.h
+++ b/Telegram/SourceFiles/boxes/add_contact_box.h
@@ -22,7 +22,6 @@ class Session;
 } // namespace Main
 
 namespace Ui {
-class ConfirmBox;
 class FlatLabel;
 class InputField;
 class PhoneInput;
diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp
index 3695f4a6c..e5c749b1f 100644
--- a/Telegram/SourceFiles/boxes/background_box.cpp
+++ b/Telegram/SourceFiles/boxes/background_box.cpp
@@ -176,11 +176,11 @@ void BackgroundBox::removePaper(const Data::WallPaper &paper) {
 		)).send();
 	};
 	_controller->show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_background_sure_delete(tr::now),
-			tr::lng_selected_delete(tr::now),
-			tr::lng_cancel(tr::now),
-			remove),
+		Ui::MakeConfirmBox({
+			.text = tr::lng_background_sure_delete(),
+			.confirmed = remove,
+			.confirmText = tr::lng_selected_delete(),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp
index f527483fc..52bb145ac 100644
--- a/Telegram/SourceFiles/boxes/background_preview_box.cpp
+++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp
@@ -779,8 +779,7 @@ bool BackgroundPreviewBox::Start(
 		return true;
 	}
 	if (!IsValidWallPaperSlug(slug)) {
-		controller->show(
-			Box<Ui::InformBox>(tr::lng_background_bad_link(tr::now)));
+		controller->show(Ui::MakeInformBox(tr::lng_background_bad_link()));
 		return false;
 	}
 	controller->session().api().requestWallPaper(slug, crl::guard(controller, [=](
@@ -789,8 +788,7 @@ bool BackgroundPreviewBox::Start(
 			controller,
 			result.withUrlParams(params)));
 	}), crl::guard(controller, [=](const MTP::Error &error) {
-		controller->show(
-			Box<Ui::InformBox>(tr::lng_background_bad_link(tr::now)));
+		controller->show(Ui::MakeInformBox(tr::lng_background_bad_link()));
 	}));
 	return true;
 }
diff --git a/Telegram/SourceFiles/boxes/change_phone_box.cpp b/Telegram/SourceFiles/boxes/change_phone_box.cpp
index 2a589ddde..3033a2e93 100644
--- a/Telegram/SourceFiles/boxes/change_phone_box.cpp
+++ b/Telegram/SourceFiles/boxes/change_phone_box.cpp
@@ -266,12 +266,11 @@ void ChangePhoneBox::EnterPhone::sendPhoneFail(
 		Ui::ShowPhoneBannedError(&_controller->window(), phoneNumber);
 	} else if (error.type() == qstr("PHONE_NUMBER_OCCUPIED")) {
 		_controller->show(
-			Box<Ui::InformBox>(
+			Ui::MakeInformBox(
 				tr::lng_change_phone_occupied(
 					tr::now,
 					lt_phone,
-					Ui::FormatPhone(phoneNumber)),
-				tr::lng_box_ok(tr::now)),
+					Ui::FormatPhone(phoneNumber))),
 			Ui::LayerOption::CloseOther);
 	} else {
 		showError(Lang::Hard::ServerError());
@@ -443,9 +442,10 @@ void ChangePhoneBox::prepare() {
 				Ui::LayerOption::CloseOther);
 		};
 		controller->show(
-			Box<Ui::ConfirmBox>(
-				tr::lng_change_phone_warning(tr::now),
-				std::move(callback)),
+			Ui::MakeConfirmBox({
+				.text = tr::lng_change_phone_warning(),
+				.confirmed = std::move(callback),
+			}),
 			Ui::LayerOption::CloseOther);
 	});
 	addButton(tr::lng_cancel(), [this] {
diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp
index ce96ed6d6..89466f98a 100644
--- a/Telegram/SourceFiles/boxes/connection_box.cpp
+++ b/Telegram/SourceFiles/boxes/connection_box.cpp
@@ -1139,13 +1139,14 @@ void ProxiesBoxController::ShowApplyConfirmation(
 			close();
 		};
 		Ui::show(
-			Box<Ui::ConfirmBox>(
-				text,
-				tr::lng_sure_enable(tr::now),
-				std::move(callback)),
+			Ui::MakeConfirmBox({
+				.text = text,
+				.confirmed = std::move(callback),
+				.confirmText = tr::lng_sure_enable(),
+			}),
 			Ui::LayerOption::KeepOther);
 	} else {
-		Ui::show(Box<Ui::InformBox>(
+		Ui::show(Ui::MakeInformBox(
 			(proxy.status() == ProxyData::Status::Unsupported
 				? tr::lng_proxy_unsupported(tr::now)
 				: tr::lng_proxy_invalid(tr::now))));
diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp
index f04d8be49..910eeef33 100644
--- a/Telegram/SourceFiles/boxes/passcode_box.cpp
+++ b/Telegram/SourceFiles/boxes/passcode_box.cpp
@@ -108,7 +108,7 @@ void StartPendingReset(
 	auto finish = [=](const QString &message) mutable {
 		if (const auto strong = weak.data()) {
 			if (!message.isEmpty()) {
-				strong->getDelegate()->show(Box<Ui::InformBox>(message));
+				strong->getDelegate()->show(Ui::MakeInformBox(message));
 			}
 			strong->closeBox();
 		}
@@ -139,7 +139,7 @@ void StartPendingReset(
 				lt_count,
 				minutes);
 		if (const auto strong = weak.data()) {
-			strong->getDelegate()->show(Box<Ui::InformBox>(
+			strong->getDelegate()->show(Ui::MakeInformBox(
 				tr::lng_cloud_password_reset_later(
 					tr::now,
 					lt_duration,
@@ -441,8 +441,8 @@ void PasscodeBox::recoverPasswordDone(
 	if (weak) {
 		_newPasswordSet.fire_copy(newPasswordBytes);
 		if (weak) {
-			getDelegate()->show(Box<Ui::InformBox>(
-				tr::lng_cloud_password_updated(tr::now)));
+			getDelegate()->show(Ui::MakeInformBox(
+				tr::lng_cloud_password_updated()));
 			if (weak) {
 				closeBox();
 			}
@@ -458,12 +458,12 @@ void PasscodeBox::setPasswordDone(const QByteArray &newPasswordBytes) {
 	const auto weak = Ui::MakeWeak(this);
 	_newPasswordSet.fire_copy(newPasswordBytes);
 	if (weak) {
-		const auto text = _reenterPasscode->isHidden()
-			? tr::lng_cloud_password_removed(tr::now)
+		auto text = _reenterPasscode->isHidden()
+			? tr::lng_cloud_password_removed()
 			: _oldPasscode->isHidden()
-			? tr::lng_cloud_password_was_set(tr::now)
-			: tr::lng_cloud_password_updated(tr::now);
-		getDelegate()->show(Box<Ui::InformBox>(text));
+			? tr::lng_cloud_password_was_set()
+			: tr::lng_cloud_password_updated();
+		getDelegate()->show(Ui::MakeInformBox(std::move(text)));
 		if (weak) {
 			closeBox();
 		}
@@ -559,8 +559,9 @@ void PasscodeBox::validateEmail(
 				const auto weak = Ui::MakeWeak(this);
 				_clearUnconfirmedPassword.fire({});
 				if (weak) {
-					auto box = Box<Ui::InformBox>(
-						Lang::Hard::EmailConfirmationExpired());
+					auto box = Ui::MakeInformBox({
+						Lang::Hard::EmailConfirmationExpired()
+					});
 					weak->getDelegate()->show(
 						std::move(box),
 						Ui::LayerOption::CloseOther);
@@ -685,12 +686,12 @@ void PasscodeBox::save(bool force) {
 		}
 		if (!onlyCheck && !_recoverEmail->isHidden() && email.isEmpty() && !force) {
 			_skipEmailWarning = true;
-			_replacedBy = getDelegate()->show(
-				Box<Ui::ConfirmBox>(
-					tr::lng_cloud_password_about_recover(tr::now),
-					tr::lng_cloud_password_skip_email(tr::now),
-					st::attentionBoxButton,
-					crl::guard(this, [this] { save(true); })));
+			_replacedBy = getDelegate()->show(Ui::MakeConfirmBox({
+				.text = { tr::lng_cloud_password_about_recover() },
+				.confirmed = crl::guard(this, [this] { save(true); }),
+				.confirmText = tr::lng_cloud_password_skip_email(),
+				.confirmStyle = &st::attentionBoxButton,
+			}));
 		} else if (onlyCheck) {
 			submitOnlyCheckCloudPassword(old);
 		} else if (_oldPasscode->isHidden()) {
@@ -719,14 +720,11 @@ void PasscodeBox::submitOnlyCheckCloudPassword(const QString &oldPassword) {
 	if (_cloudFields.turningOff && _cloudFields.notEmptyPassport) {
 		Assert(!_cloudFields.customCheckCallback);
 
-		const auto confirmed = [=](Fn<void()> &&close) {
-			send();
-			close();
-		};
-		getDelegate()->show(Box<Ui::ConfirmBox>(
-			tr::lng_cloud_password_passport_losing(tr::now),
-			tr::lng_continue(tr::now),
-			confirmed));
+		getDelegate()->show(Ui::MakeConfirmBox({
+			.text = tr::lng_cloud_password_passport_losing(),
+			.confirmed = [=](Fn<void()> &&close) { send(); close(); },
+			.confirmText = tr::lng_continue(),
+		}));
 	} else {
 		send();
 	}
@@ -794,7 +792,7 @@ void PasscodeBox::requestPasswordData() {
 }
 
 void PasscodeBox::serverError() {
-	getDelegate()->show(Box<Ui::InformBox>(Lang::Hard::ServerError()));
+	getDelegate()->show(Ui::MakeInformBox(Lang::Hard::ServerError()));
 	closeBox();
 }
 
@@ -949,10 +947,11 @@ void PasscodeBox::suggestSecretReset(const QString &newPassword) {
 			resetSecret(check, newPassword, std::move(close));
 		});
 	};
-	getDelegate()->show(Box<Ui::ConfirmBox>(
-		Lang::Hard::PassportCorruptedChange(),
-		Lang::Hard::PassportCorruptedReset(),
-		std::move(resetSecretAndSave)));
+	getDelegate()->show(Ui::MakeConfirmBox({
+		.text = { Lang::Hard::PassportCorruptedChange() },
+		.confirmed = std::move(resetSecretAndSave),
+		.confirmText = Lang::Hard::PassportCorruptedReset(),
+	}));
 }
 
 void PasscodeBox::resetSecret(
@@ -1074,18 +1073,14 @@ void PasscodeBox::recoverByEmail() {
 	if (!_cloudFields.hasRecovery) {
 		Assert(_session != nullptr);
 		const auto session = _session;
-		const auto confirmBox = std::make_shared<QPointer<BoxContent>>();
-		const auto reset = crl::guard(this, [=] {
-			StartPendingReset(session, this, [=] {
-				if (const auto box = *confirmBox) {
-					box->closeBox();
-				}
-			});
+		const auto reset = crl::guard(this, [=](Fn<void()> &&close) {
+			StartPendingReset(session, this, std::move(close));
 		});
-		*confirmBox = getDelegate()->show(Box<Ui::ConfirmBox>(
-			tr::lng_cloud_password_reset_no_email(tr::now),
-			tr::lng_cloud_password_reset_ok(tr::now),
-			reset));
+		getDelegate()->show(Ui::MakeConfirmBox({
+			.text = tr::lng_cloud_password_reset_no_email(tr::now),
+			.confirmed = reset,
+			.confirmText = tr::lng_cloud_password_reset_ok(tr::now),
+		}));
 	} else if (_pattern.isEmpty()) {
 		_pattern = "-";
 		_api.request(MTPauth_RequestPasswordRecovery(
@@ -1155,22 +1150,20 @@ RecoverBox::RecoverBox(
 		_noEmailAccess.destroy();
 	} else {
 		_noEmailAccess->setClickedCallback([=] {
-			const auto confirmBox = std::make_shared<QPointer<BoxContent>>();
-			const auto reset = crl::guard(this, [=] {
+			const auto reset = crl::guard(this, [=](Fn<void()> &&close) {
 				const auto closeParent = _closeParent;
-				StartPendingReset(session, this, [=] {
+				StartPendingReset(session, this, [=, c = std::move(close)] {
 					if (closeParent) {
 						closeParent();
 					}
-					if (const auto box = *confirmBox) {
-						box->closeBox();
-					}
+					c();
 				});
 			});
-			*confirmBox = getDelegate()->show(Box<Ui::ConfirmBox>(
-				tr::lng_cloud_password_reset_with_email(tr::now),
-				tr::lng_cloud_password_reset_ok(tr::now),
-				reset));
+			getDelegate()->show(Ui::MakeConfirmBox({
+				.text = tr::lng_cloud_password_reset_with_email(),
+				.confirmed = reset,
+				.confirmText = tr::lng_cloud_password_reset_ok(),
+			}));
 		});
 	}
 }
@@ -1265,14 +1258,11 @@ void RecoverBox::submit() {
 		}
 	});
 	if (_cloudFields.notEmptyPassport) {
-		const auto confirmed = [=](Fn<void()> &&close) {
-			send();
-			close();
-		};
-		getDelegate()->show(Box<Ui::ConfirmBox>(
-			tr::lng_cloud_password_passport_losing(tr::now),
-			tr::lng_continue(tr::now),
-			confirmed));
+		getDelegate()->show(Ui::MakeConfirmBox({
+			.text = tr::lng_cloud_password_passport_losing(),
+			.confirmed = [=](Fn<void()> &&close) { send(); close(); },
+			.confirmText = tr::lng_continue(),
+		}));
 	} else {
 		send();
 	}
@@ -1294,7 +1284,7 @@ void RecoverBox::proceedToClear() {
 	_submitRequest = 0;
 	_newPasswordSet.fire({});
 	getDelegate()->show(
-		Box<Ui::InformBox>(tr::lng_cloud_password_removed(tr::now)),
+		Ui::MakeInformBox(tr::lng_cloud_password_removed()),
 		Ui::LayerOption::CloseOther);
 }
 
@@ -1342,7 +1332,7 @@ void RecoverBox::checkSubmitFail(const MTP::Error &error) {
 	if (err == qstr("PASSWORD_EMPTY")) {
 		_newPasswordSet.fire(QByteArray());
 		getDelegate()->show(
-			Box<Ui::InformBox>(tr::lng_cloud_password_removed(tr::now)),
+			Ui::MakeInformBox(tr::lng_cloud_password_removed()),
 			Ui::LayerOption::CloseOther);
 	} else if (err == qstr("PASSWORD_RECOVERY_NA")) {
 		closeBox();
@@ -1383,8 +1373,7 @@ RecoveryEmailValidation ConfirmRecoveryEmail(
 			reloads->fire({});
 			if (*weak) {
 				(*weak)->getDelegate()->show(
-					Box<Ui::InformBox>(
-						tr::lng_cloud_password_was_set(tr::now)),
+					Ui::MakeInformBox(tr::lng_cloud_password_was_set()),
 					Ui::LayerOption::CloseOther);
 			}
 		}).fail([=](const MTP::Error &error) {
@@ -1396,7 +1385,7 @@ RecoveryEmailValidation ConfirmRecoveryEmail(
 			} else if (error.type() == qstr("EMAIL_HASH_EXPIRED")) {
 				cancels->fire({});
 				if (*weak) {
-					auto box = Box<Ui::InformBox>(
+					auto box = Ui::MakeInformBox(
 						Lang::Hard::EmailConfirmationExpired());
 					(*weak)->getDelegate()->show(
 						std::move(box),
diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp
index 6dbc9c95e..4980b0455 100644
--- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp
+++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp
@@ -564,7 +564,10 @@ void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
 		return tr::lng_bot_sure_share_game_group(tr::now, lt_group, chat->name);
 	}();
 	Ui::show(
-		Box<Ui::ConfirmBox>(confirmText, std::move(send)),
+		Ui::MakeConfirmBox({
+			.text = confirmText,
+			.confirmed = std::move(send),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
@@ -572,7 +575,7 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
 	if (const auto megagroup = chat->asMegagroup()) {
 		if (!megagroup->canAddMembers()) {
 			Ui::show(
-				Box<Ui::InformBox>(tr::lng_error_cant_add_member(tr::now)),
+				Ui::MakeInformBox(tr::lng_error_cant_add_member()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -582,7 +585,7 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
 	});
 	auto confirmText = tr::lng_bot_sure_invite(tr::now, lt_group, chat->name);
 	Ui::show(
-		Box<Ui::ConfirmBox>(confirmText, send),
+		Ui::MakeConfirmBox({ confirmText, send }),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp
index 1c70ee885..e69f83294 100644
--- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp
@@ -107,8 +107,7 @@ void AddParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
 	} else if (count >= serverConfig.chatSizeMax
 		&& count < serverConfig.megagroupSizeMax) {
 		Ui::show(
-			Box<Ui::InformBox>(
-				tr::lng_profile_add_more_after_create(tr::now)),
+			Ui::MakeInformBox(tr::lng_profile_add_more_after_create()),
 			Ui::LayerOption::KeepOther);
 	}
 }
@@ -570,21 +569,22 @@ void AddSpecialBoxController::showAdmin(
 			if (canBanMembers) {
 				if (!sure) {
 					_editBox = Ui::show(
-						Box<Ui::ConfirmBox>(
-							tr::lng_sure_add_admin_unremove(tr::now),
-							showAdminSure),
+						Ui::MakeConfirmBox({
+							tr::lng_sure_add_admin_unremove(),
+							showAdminSure
+						}),
 						Ui::LayerOption::KeepOther);
 					return;
 				}
 			} else {
-				Ui::show(Box<Ui::InformBox>(
-					tr::lng_error_cant_add_admin_unban(tr::now)),
+				Ui::show(
+					Ui::MakeInformBox(tr::lng_error_cant_add_admin_unban()),
 					Ui::LayerOption::KeepOther);
 				return;
 			}
 		} else {
-			Ui::show(Box<Ui::InformBox>(
-				tr::lng_error_cant_add_admin_invite(tr::now)),
+			Ui::show(
+				Ui::MakeInformBox(tr::lng_error_cant_add_admin_invite()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -593,15 +593,16 @@ void AddSpecialBoxController::showAdmin(
 		if (canBanMembers) {
 			if (!sure) {
 				_editBox = Ui::show(
-					Box<Ui::ConfirmBox>(
-						tr::lng_sure_add_admin_unremove(tr::now),
-						showAdminSure),
+					Ui::MakeConfirmBox({
+						tr::lng_sure_add_admin_unremove(),
+						showAdminSure
+					}),
 					Ui::LayerOption::KeepOther);
 				return;
 			}
 		} else {
-			Ui::show(Box<Ui::InformBox>(
-				tr::lng_error_cant_add_admin_unban(tr::now)),
+			Ui::show(
+				Ui::MakeInformBox(tr::lng_error_cant_add_admin_unban()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -609,20 +610,20 @@ void AddSpecialBoxController::showAdmin(
 		// The user is not in the group yet.
 		if (canAddMembers) {
 			if (!sure) {
-				const auto text = ((_peer->isChat() || _peer->isMegagroup())
+				auto text = ((_peer->isChat() || _peer->isMegagroup())
 					? tr::lng_sure_add_admin_invite
-					: tr::lng_sure_add_admin_invite_channel)(tr::now);
+					: tr::lng_sure_add_admin_invite_channel)();
 				_editBox = Ui::show(
-					Box<Ui::ConfirmBox>(
-						text,
-						showAdminSure),
+					Ui::MakeConfirmBox({
+						std::move(text),
+						showAdminSure
+					}),
 					Ui::LayerOption::KeepOther);
 				return;
 			}
 		} else {
 			Ui::show(
-				Box<Ui::InformBox>(
-					tr::lng_error_cant_add_admin_invite(tr::now)),
+				Ui::MakeInformBox(tr::lng_error_cant_add_admin_invite()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -692,15 +693,16 @@ void AddSpecialBoxController::showRestricted(
 		if (!_additional.isCreator(user) && _additional.canEditAdmin(user)) {
 			if (!sure) {
 				_editBox = Ui::show(
-					Box<Ui::ConfirmBox>(
-						tr::lng_sure_ban_admin(tr::now),
-						showRestrictedSure),
+					Ui::MakeConfirmBox({
+						tr::lng_sure_ban_admin(),
+						showRestrictedSure
+					}),
 					Ui::LayerOption::KeepOther);
 				return;
 			}
 		} else {
 			Ui::show(
-				Box<Ui::InformBox>(tr::lng_error_cant_ban_admin(tr::now)),
+				Ui::MakeInformBox(tr::lng_error_cant_ban_admin()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -763,15 +765,16 @@ void AddSpecialBoxController::kickUser(
 		if (!_additional.isCreator(user) && _additional.canEditAdmin(user)) {
 			if (!sure) {
 				_editBox = Ui::show(
-					Box<Ui::ConfirmBox>(
-						tr::lng_sure_ban_admin(tr::now),
-						kickUserSure),
+					Ui::MakeConfirmBox({
+						tr::lng_sure_ban_admin(),
+						kickUserSure
+					}),
 					Ui::LayerOption::KeepOther);
 				return;
 			}
 		} else {
 			Ui::show(
-				Box<Ui::InformBox>(tr::lng_error_cant_ban_admin(tr::now)),
+				Ui::MakeInformBox(tr::lng_error_cant_ban_admin()),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -786,7 +789,7 @@ void AddSpecialBoxController::kickUser(
 				lt_user,
 				participant->name);
 		_editBox = Ui::show(
-			Box<Ui::ConfirmBox>(text, kickUserSure),
+			Ui::MakeConfirmBox({ text, kickUserSure }),
 			Ui::LayerOption::KeepOther);
 		return;
 	}
diff --git a/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp
index 8a9ed5409..95761ffbd 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp
@@ -153,10 +153,11 @@ void Controller::choose(not_null<ChannelData*> chat) {
 		onstack(chat);
 	};
 	Ui::show(
-		Box<Ui::ConfirmBox>(
-			text,
-			tr::lng_manage_discussion_group_link(tr::now),
-			sure),
+		Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = sure,
+			.confirmText = tr::lng_manage_discussion_group_link(tr::now),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
@@ -185,10 +186,11 @@ void Controller::choose(not_null<ChatData*> chat) {
 		chat->session().api().migrateChat(chat, crl::guard(this, done));
 	};
 	Ui::show(
-		Box<Ui::ConfirmBox>(
-			text,
-			tr::lng_manage_discussion_group_link(tr::now),
-			sure),
+		Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = sure,
+			.confirmText = tr::lng_manage_discussion_group_link(tr::now),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
index c59f8ed59..6a9c81d5b 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
@@ -456,16 +456,17 @@ void EditAdminBox::transferOwnership() {
 				transferOwnershipChecked();
 				close();
 			});
-			getDelegate()->show(Box<Ui::ConfirmBox>(
-				tr::lng_rights_transfer_about(
+			getDelegate()->show(Ui::MakeConfirmBox({
+				.text = tr::lng_rights_transfer_about(
 					tr::now,
 					lt_group,
 					Ui::Text::Bold(peer()->name),
 					lt_user,
 					Ui::Text::Bold(user()->shortName()),
 					Ui::Text::RichLangValue),
-				tr::lng_rights_transfer_sure(tr::now),
-				callback));
+				.confirmed = callback,
+				.confirmText = tr::lng_rights_transfer_sure(),
+			}));
 		}
 	}).send();
 }
@@ -573,7 +574,7 @@ void EditAdminBox::sendTransferRequestFrom(
 				|| (type == qstr("SESSION_TOO_FRESH_XXX"));
 		}();
 		const auto weak = Ui::MakeWeak(this);
-		getDelegate()->show(Box<Ui::InformBox>(problem));
+		getDelegate()->show(Ui::MakeInformBox(problem));
 		if (box) {
 			box->closeBox();
 		}
diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp
index c979d01fc..9179d46d7 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp
@@ -1718,10 +1718,13 @@ void ParticipantsBoxController::kickParticipant(not_null<PeerData*> participant)
 			lt_user,
 			user ? user->firstName : participant->name);
 	_editBox = Ui::show(
-		Box<Ui::ConfirmBox>(
-			text,
-			tr::lng_box_remove(tr::now),
-			crl::guard(this, [=] { kickParticipantSure(participant); })),
+		Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = crl::guard(this, [=] {
+				kickParticipantSure(participant);
+			}),
+			.confirmText = tr::lng_box_remove(),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
@@ -1760,13 +1763,14 @@ void ParticipantsBoxController::kickParticipantSure(
 
 void ParticipantsBoxController::removeAdmin(not_null<UserData*> user) {
 	_editBox = Ui::show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_profile_sure_remove_admin(
+		Ui::MakeConfirmBox({
+			.text = tr::lng_profile_sure_remove_admin(
 				tr::now,
 				lt_user,
 				user->firstName),
-			tr::lng_box_remove(tr::now),
-			crl::guard(this, [=] { removeAdminSure(user); })),
+			.confirmed = crl::guard(this, [=] { removeAdminSure(user); }),
+			.confirmText = tr::lng_box_remove(),
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
index ad8a1f0be..5586689f3 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
@@ -1606,11 +1606,12 @@ void Controller::deleteWithConfirmation() {
 		deleteChannel();
 	});
 	_navigation->parentController()->show(
-		Box<Ui::ConfirmBox>(
-			text,
-			tr::lng_box_delete(tr::now),
-			st::attentionBoxButton,
-			deleteCallback),
+		Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = deleteCallback,
+			.confirmText = tr::lng_box_delete(),
+			.confirmStyle = &st::attentionBoxButton,
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp
index d5590e840..c8ecd8fc5 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp
@@ -943,23 +943,18 @@ void AddPermanentLinkBlock(
 		}
 	});
 	const auto revokeLink = crl::guard(weak, [=] {
-		const auto box = std::make_shared<QPointer<Ui::ConfirmBox>>();
-		const auto done = crl::guard(weak, [=] {
-			const auto close = [=] {
-				if (*box) {
-					(*box)->closeBox();
-				}
-			};
+		const auto done = crl::guard(weak, [=](Fn<void()> &&close) {
 			peer->session().api().inviteLinks().revokePermanent(
 				peer,
 				admin,
 				value->current().link,
-				close);
+				std::move(close));
 		});
-		*box = Ui::show(
-			Box<Ui::ConfirmBox>(
+		Ui::show(
+			Ui::MakeConfirmBox({
 				tr::lng_group_invite_about_new(tr::now),
-				done),
+				done
+			}),
 			Ui::LayerOption::KeepOther);
 	});
 
@@ -1143,7 +1138,7 @@ void ShareInviteLinkBox(not_null<PeerData*> peer, const QString &link) {
 			}
 			text.append(error.first);
 			Ui::show(
-				Box<Ui::InformBox>(text),
+				Ui::MakeInformBox(text),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
@@ -1252,19 +1247,17 @@ void RevokeLink(
 		not_null<PeerData*> peer,
 		not_null<UserData*> admin,
 		const QString &link) {
-	const auto box = std::make_shared<QPointer<Ui::ConfirmBox>>();
-	const auto revoke = [=] {
-		const auto done = [=](const LinkData &data) {
-			if (*box) {
-				(*box)->closeBox();
-			}
+	const auto revoke = [=](Fn<void()> &&close) {
+		const auto done = [close = std::move(close)](const LinkData &data) {
+			close();
 		};
 		peer->session().api().inviteLinks().revoke(peer, admin, link, done);
 	};
-	*box = Ui::show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_group_invite_revoke_about(tr::now),
-			revoke),
+	Ui::show(
+		Ui::MakeConfirmBox({
+			tr::lng_group_invite_revoke_about(),
+			revoke
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
@@ -1272,21 +1265,18 @@ void DeleteLink(
 		not_null<PeerData*> peer,
 		not_null<UserData*> admin,
 		const QString &link) {
-	const auto box = std::make_shared<QPointer<Ui::ConfirmBox>>();
-	const auto sure = [=] {
-		const auto finish = [=] {
-			if (*box) {
-				(*box)->closeBox();
-			}
-		};
+	const auto sure = [=](Fn<void()> &&close) {
 		peer->session().api().inviteLinks().destroy(
 			peer,
 			admin,
 			link,
-			finish);
+			std::move(close));
 	};
-	*box = Ui::show(
-		Box<Ui::ConfirmBox>(tr::lng_group_invite_delete_sure(tr::now), sure),
+	Ui::show(
+		Ui::MakeConfirmBox({
+			tr::lng_group_invite_delete_sure(),
+			sure
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp
index 91f592a66..68ce8d859 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp
@@ -208,22 +208,17 @@ private:
 void DeleteAllRevoked(
 		not_null<PeerData*> peer,
 		not_null<UserData*> admin) {
-	const auto box = std::make_shared<QPointer<Ui::ConfirmBox>>();
-	const auto sure = [=] {
-		const auto finish = [=] {
-			if (*box) {
-				(*box)->closeBox();
-			}
-		};
+	const auto sure = [=](Fn<void()> &&close) {
 		peer->session().api().inviteLinks().destroyAllRevoked(
 			peer,
 			admin,
-			finish);
+			std::move(close));
 	};
-	*box = Ui::show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_group_invite_delete_all_sure(tr::now),
-			sure),
+	Ui::show(
+		Ui::MakeConfirmBox({
+			tr::lng_group_invite_delete_all_sure(),
+			sure
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/phone_banned_box.cpp b/Telegram/SourceFiles/boxes/phone_banned_box.cpp
index cf57a1e16..b29388e96 100644
--- a/Telegram/SourceFiles/boxes/phone_banned_box.cpp
+++ b/Telegram/SourceFiles/boxes/phone_banned_box.cpp
@@ -56,12 +56,16 @@ void ShowPhoneBannedError(
 		}
 	};
 	*box = controller->show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_signin_banned_text(tr::now),
-			tr::lng_box_ok(tr::now),
-			tr::lng_signin_banned_help(tr::now),
-			close,
-			[=] { SendToBannedHelp(phone); close(); }),
+		Ui::MakeConfirmBox({
+			.text = tr::lng_signin_banned_text(),
+			.cancelled = [=](Fn<void()> &&close) {
+				SendToBannedHelp(phone);
+				close();
+			},
+			.confirmText = tr::lng_box_ok(),
+			.cancelText = tr::lng_signin_banned_help(),
+			.strictCancel = true,
+		}),
 		Ui::LayerOption::CloseOther);
 }
 
diff --git a/Telegram/SourceFiles/boxes/sessions_box.cpp b/Telegram/SourceFiles/boxes/sessions_box.cpp
index 54c62e086..6af1aaf57 100644
--- a/Telegram/SourceFiles/boxes/sessions_box.cpp
+++ b/Telegram/SourceFiles/boxes/sessions_box.cpp
@@ -636,7 +636,7 @@ private:
 	Full _data;
 
 	object_ptr<Inner> _inner;
-	QPointer<Ui::ConfirmBox> _terminateBox;
+	QPointer<Ui::BoxContent> _terminateBox;
 
 	base::Timer _shortPollTimer;
 
@@ -823,11 +823,12 @@ void SessionsContent::terminate(Fn<void()> terminateRequest, QString message) {
 		}
 		terminateRequest();
 	});
-	auto box = Box<Ui::ConfirmBox>(
-		message,
-		tr::lng_settings_reset_button(tr::now),
-		st::attentionBoxButton,
-		callback);
+	auto box = Ui::MakeConfirmBox({
+		.text = message,
+		.confirmed = callback,
+		.confirmText = tr::lng_settings_reset_button(),
+		.confirmStyle = &st::attentionBoxButton,
+	});
 	_terminateBox = Ui::MakeWeak(box.data());
 	_controller->show(std::move(box), Ui::LayerOption::KeepOther);
 }
diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp
index cea7aa99b..b411968c5 100644
--- a/Telegram/SourceFiles/boxes/share_box.cpp
+++ b/Telegram/SourceFiles/boxes/share_box.cpp
@@ -1257,7 +1257,7 @@ void ShareGameScoreByHash(
 	auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
 	if (hashEncrypted.size() <= key128Size || (hashEncrypted.size() != key128Size + 0x20)) {
 		controller->show(
-			Box<Ui::InformBox>(tr::lng_confirm_phone_link_invalid(tr::now)),
+			Ui::MakeInformBox(tr::lng_confirm_phone_link_invalid()),
 			Ui::LayerOption::CloseOther);
 		return;
 	}
@@ -1285,7 +1285,7 @@ void ShareGameScoreByHash(
 	// Check 128 bits of SHA1() of data.
 	if (memcmp(dataSha1, hashEncrypted.constData(), key128Size) != 0) {
 		controller->show(
-			Box<Ui::InformBox>(tr::lng_share_wrong_user(tr::now)),
+			Ui::MakeInformBox(tr::lng_share_wrong_user()),
 			Ui::LayerOption::CloseOther);
 		return;
 	}
@@ -1293,7 +1293,7 @@ void ShareGameScoreByHash(
 	auto hashDataInts = reinterpret_cast<uint64*>(hashData.data());
 	if (hashDataInts[0] != session.userId().bare) {
 		controller->show(
-			Box<Ui::InformBox>(tr::lng_share_wrong_user(tr::now)),
+			Ui::MakeInformBox(tr::lng_share_wrong_user()),
 			Ui::LayerOption::CloseOther);
 		return;
 	}
@@ -1303,7 +1303,7 @@ void ShareGameScoreByHash(
 	if (!peerIsChannel(peerId) && channelAccessHash) {
 		// If there is no channel id, there should be no channel access_hash.
 		controller->show(
-			Box<Ui::InformBox>(tr::lng_share_wrong_user(tr::now)),
+			Ui::MakeInformBox(tr::lng_share_wrong_user()),
 			Ui::LayerOption::CloseOther);
 		return;
 	}
@@ -1323,7 +1323,7 @@ void ShareGameScoreByHash(
 					FastShareMessage(item);
 				} else {
 					weak->show(
-						Box<Ui::InformBox>(tr::lng_edit_deleted(tr::now)),
+						Ui::MakeInformBox(tr::lng_edit_deleted()),
 						Ui::LayerOption::CloseOther);
 				}
 			});
diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp
index db49e252c..6c50eff87 100644
--- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp
+++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp
@@ -288,7 +288,7 @@ void StickerSetBox::handleError(Error error) {
 	switch (error) {
 	case Error::NotFound:
 		_controller->show(
-			Box<Ui::InformBox>(tr::lng_stickers_not_found(tr::now)));
+			Ui::MakeInformBox(tr::lng_stickers_not_found(tr::now)));
 		break;
 	default: Unexpected("Error in StickerSetBox::handleError.");
 	}
diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h
index 2dbd37730..a4be4c680 100644
--- a/Telegram/SourceFiles/boxes/sticker_set_box.h
+++ b/Telegram/SourceFiles/boxes/sticker_set_box.h
@@ -16,7 +16,6 @@ class SessionController;
 } // namespace Window
 
 namespace Ui {
-class ConfirmBox;
 class PlainShadow;
 } // namespace Ui
 
diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h
index cde86ec27..213cf279d 100644
--- a/Telegram/SourceFiles/boxes/stickers_box.h
+++ b/Telegram/SourceFiles/boxes/stickers_box.h
@@ -19,7 +19,6 @@ struct RippleAnimation;
 } // namespace style
 
 namespace Ui {
-class ConfirmBox;
 class PlainShadow;
 class RippleAnimation;
 class SettingsSlider;
diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp
index f8f5846f4..dd075f82d 100644
--- a/Telegram/SourceFiles/calls/calls_call.cpp
+++ b/Telegram/SourceFiles/calls/calls_call.cpp
@@ -1234,7 +1234,7 @@ void Call::handleRequestError(const QString &error) {
 		? Lang::Hard::CallErrorIncompatible().replace("{user}", _user->name)
 		: QString();
 	if (!inform.isEmpty()) {
-		Ui::show(Box<Ui::InformBox>(inform));
+		Ui::show(Ui::MakeInformBox(inform));
 	}
 	finish(FinishType::Failed);
 }
@@ -1246,7 +1246,7 @@ void Call::handleControllerError(const QString &error) {
 		? tr::lng_call_error_audio_io(tr::now)
 		: QString();
 	if (!inform.isEmpty()) {
-		Ui::show(Box<Ui::InformBox>(inform));
+		Ui::show(Ui::MakeInformBox(inform));
 	}
 	finish(FinishType::Failed);
 }
diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp
index 229aec683..04fdb1da7 100644
--- a/Telegram/SourceFiles/calls/calls_instance.cpp
+++ b/Telegram/SourceFiles/calls/calls_instance.cpp
@@ -191,7 +191,7 @@ void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
 	if (user->callsStatus() == UserData::CallsStatus::Private) {
 		// Request full user once more to refresh the setting in case it was changed.
 		user->session().api().requestFullPeer(user);
-		Ui::show(Box<Ui::InformBox>(
+		Ui::show(Ui::MakeInformBox(
 			tr::lng_call_error_not_available(tr::now, lt_user, user->name)));
 		return;
 	}
@@ -714,13 +714,14 @@ void Instance::requestPermissionOrFail(Platform::PermissionType type, Fn<void()>
 		if (inGroupCall()) {
 			_currentGroupCall->hangup();
 		}
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_no_mic_permission(tr::now),
-			tr::lng_menu_settings(tr::now),
-			crl::guard(this, [=] {
+		Ui::show(Ui::MakeConfirmBox({
+			.text = tr::lng_no_mic_permission(),
+			.confirmed = crl::guard(this, [=] {
 				Platform::OpenSystemSettingsForPermission(type);
 				Ui::hideLayer();
-			})));
+			}),
+			.confirmText = tr::lng_menu_settings(),
+		}));
 	}
 }
 
diff --git a/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp b/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp
index 88e607a46..56d0623e7 100644
--- a/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp
+++ b/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp
@@ -143,15 +143,18 @@ void StartWithBox(
 	}, box->lifetime());
 	streamKeyButton->addClickHandler([=] {
 		if (!state->warned && state->hidden.current()) {
-			showBox(Box<Ui::ConfirmBox>(
-				tr::lng_group_call_rtmp_key_warn(tr::now),
-				tr::lng_from_request_understand(tr::now),
-				tr::lng_close(tr::now),
-				[=](Fn<void()> &&close) {
+			showBox(Ui::MakeConfirmBox({
+				.text = tr::lng_group_call_rtmp_key_warning(
+					Ui::Text::RichLangValue),
+				.confirmed = [=](Fn<void()> &&close) {
 					state->warned = true;
 					state->hidden = !state->hidden.current();
 					close();
-				}));
+				},
+				.confirmText = tr::lng_from_request_understand(),
+				.cancelText = tr::lng_close(),
+				.confirmStyle = &st::attentionBoxButton,
+			}));
 		} else {
 			state->hidden = !state->hidden.current();
 		}
@@ -269,13 +272,14 @@ void StartRtmpProcess::createBox() {
 	};
 	auto revoke = [=] {
 		const auto guard = base::make_weak(&_request->guard);
-		_request->showBox(Box<Ui::ConfirmBox>(
-			tr::lng_group_call_rtmp_revoke_sure(tr::now),
-			tr::lng_group_invite_context_revoke(tr::now),
-			crl::guard(guard, [=](Fn<void()> &&close) {
+		_request->showBox(Ui::MakeConfirmBox({
+			.text = tr::lng_group_call_rtmp_revoke_sure(),
+			.confirmed = crl::guard(guard, [=](Fn<void()> &&close) {
 				requestUrl(true);
 				close();
-			})));
+			}),
+			.confirmText = tr::lng_group_invite_context_revoke(),
+		}));
 	};
 	auto object = Box(
 		StartWithBox,
diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp
index 82cd8ce72..a444240fc 100644
--- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp
+++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp
@@ -3512,9 +3512,9 @@ void StickersListWidget::removeMegagroupSet(bool locally) {
 		return;
 	}
 	_removingSetId = Data::Stickers::MegagroupSetId;
-	controller()->show(Box<Ui::ConfirmBox>(
-		tr::lng_stickers_remove_group_set(tr::now),
-		crl::guard(this, [this, group = _megagroupSet] {
+	controller()->show(Ui::MakeConfirmBox({
+		.text = tr::lng_stickers_remove_group_set(),
+		.confirmed = crl::guard(this, [this, group = _megagroupSet] {
 			Expects(group->mgInfo != nullptr);
 
 			if (group->mgInfo->stickerSet) {
@@ -3523,10 +3523,12 @@ void StickersListWidget::removeMegagroupSet(bool locally) {
 			Ui::hideLayer();
 			_removingSetId = 0;
 			_checkForHide.fire({});
-		}), crl::guard(this, [this] {
+		}),
+		.cancelled = crl::guard(this, [this] {
 			_removingSetId = 0;
 			_checkForHide.fire({});
-		})));
+		}),
+	}));
 }
 
 void StickersListWidget::removeSet(uint64 setId) {
@@ -3541,67 +3543,70 @@ void StickersListWidget::removeSet(uint64 setId) {
 		tr::now,
 		lt_sticker_pack,
 		set->title);
-	const auto confirm = tr::lng_stickers_remove_pack_confirm(tr::now);
-	controller()->show(Box<Ui::ConfirmBox>(text, confirm, crl::guard(this, [=](
-			Fn<void()> &&close) {
-		close();
-		const auto &sets = session().data().stickers().sets();
-		const auto it = sets.find(_removingSetId);
-		if (it != sets.cend()) {
-			const auto set = it->second.get();
-			if (set->id && set->accessHash) {
-				_api.request(MTPmessages_UninstallStickerSet(
-					MTP_inputStickerSetID(
-						MTP_long(set->id),
-						MTP_long(set->accessHash)))
-				).send();
-			} else if (!set->shortName.isEmpty()) {
-				_api.request(MTPmessages_UninstallStickerSet(
-					MTP_inputStickerSetShortName(
-						MTP_string(set->shortName)))
-				).send();
-			}
-			auto writeRecent = false;
-			auto &recent = session().data().stickers().getRecentPack();
-			for (auto i = recent.begin(); i != recent.cend();) {
-				if (set->stickers.indexOf(i->first) >= 0) {
-					i = recent.erase(i);
-					writeRecent = true;
-				} else {
-					++i;
+	controller()->show(Ui::MakeConfirmBox({
+		.text = text,
+		.confirmed = crl::guard(this, [=](Fn<void()> &&close) {
+			close();
+			const auto &sets = session().data().stickers().sets();
+			const auto it = sets.find(_removingSetId);
+			if (it != sets.cend()) {
+				const auto set = it->second.get();
+				if (set->id && set->accessHash) {
+					_api.request(MTPmessages_UninstallStickerSet(
+						MTP_inputStickerSetID(
+							MTP_long(set->id),
+							MTP_long(set->accessHash)))
+					).send();
+				} else if (!set->shortName.isEmpty()) {
+					_api.request(MTPmessages_UninstallStickerSet(
+						MTP_inputStickerSetShortName(
+							MTP_string(set->shortName)))
+					).send();
 				}
+				auto writeRecent = false;
+				auto &recent = session().data().stickers().getRecentPack();
+				for (auto i = recent.begin(); i != recent.cend();) {
+					if (set->stickers.indexOf(i->first) >= 0) {
+						i = recent.erase(i);
+						writeRecent = true;
+					} else {
+						++i;
+					}
+				}
+				set->flags &= ~SetFlag::Installed;
+				set->installDate = TimeId(0);
+				//
+				// Set can be in search results.
+				//
+				//if (!(set->flags & SetFlag::Featured)
+				//	&& !(set->flags & SetFlag::Special)) {
+				//	sets.erase(it);
+				//}
+				const auto removeIndex = defaultSetsOrder().indexOf(
+					_removingSetId);
+				if (removeIndex >= 0) {
+					defaultSetsOrderRef().removeAt(removeIndex);
+				}
+				refreshStickers();
+				if (set->flags & SetFlag::Masks) {
+					session().local().writeInstalledMasks();
+				} else {
+					session().local().writeInstalledStickers();
+				}
+				if (writeRecent) {
+					session().saveSettings();
+				}
+				session().data().stickers().notifyUpdated();
 			}
-			set->flags &= ~SetFlag::Installed;
-			set->installDate = TimeId(0);
-			//
-			// Set can be in search results.
-			//
-			//if (!(set->flags & SetFlag::Featured)
-			//	&& !(set->flags & SetFlag::Special)) {
-			//	sets.erase(it);
-			//}
-			const auto removeIndex = defaultSetsOrder().indexOf(
-				_removingSetId);
-			if (removeIndex >= 0) {
-				defaultSetsOrderRef().removeAt(removeIndex);
-			}
-			refreshStickers();
-			if (set->flags & SetFlag::Masks) {
-				session().local().writeInstalledMasks();
-			} else {
-				session().local().writeInstalledStickers();
-			}
-			if (writeRecent) {
-				session().saveSettings();
-			}
-			session().data().stickers().notifyUpdated();
-		}
-		_removingSetId = 0;
-		_checkForHide.fire({});
-	}), crl::guard(this, [=] {
-		_removingSetId = 0;
-		_checkForHide.fire({});
-	})), Ui::LayerOption::KeepOther);
+			_removingSetId = 0;
+			_checkForHide.fire({});
+		}),
+		.cancelled = crl::guard(this, [=] {
+			_removingSetId = 0;
+			_checkForHide.fire({});
+		}),
+		.confirmText = tr::lng_stickers_remove_pack_confirm(),
+	}), Ui::LayerOption::KeepOther);
 }
 
 const Data::StickersSetsOrder &StickersListWidget::defaultSetsOrder() const {
diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp
index 1732d5446..3dadb44b3 100644
--- a/Telegram/SourceFiles/core/application.cpp
+++ b/Telegram/SourceFiles/core/application.cpp
@@ -352,15 +352,17 @@ void Application::showOpenGLCrashNotification() {
 		Core::App().settings().setDisableOpenGL(true);
 		Local::writeSettings();
 	};
-	_primaryWindow->show(Box<Ui::ConfirmBox>(
+	_primaryWindow->show(Ui::MakeConfirmBox({
+		.text = ""
 		"There may be a problem with your graphics drivers and OpenGL. "
 		"Try updating your drivers.\n\n"
 		"OpenGL has been disabled. You can try to enable it again "
 		"or keep it disabled if crashes continue.",
-		"Enable",
-		"Keep Disabled",
-		enable,
-		keepDisabled));
+		.confirmed = enable,
+		.cancelled = keepDisabled,
+		.confirmText = "Enable",
+		.cancelText = "Keep Disabled",
+	}));
 }
 
 void Application::startDomain() {
@@ -547,9 +549,12 @@ void Application::badMtprotoConfigurationError() {
 				settings().proxy().selected(),
 				MTP::ProxyData::Settings::System);
 		};
-		_badProxyDisableBox = Ui::show(Box<Ui::InformBox>(
-			Lang::Hard::ProxyConfigError(),
-			disableCallback));
+		_badProxyDisableBox = Ui::show(
+			Ui::MakeInformBox(Lang::Hard::ProxyConfigError()));
+		_badProxyDisableBox->boxClosing(
+		) | rpl::start_with_next(
+			disableCallback,
+			_badProxyDisableBox->lifetime());
 	}
 }
 
@@ -664,9 +669,11 @@ void Application::logoutWithChecks(Main::Account *account) {
 void Application::forceLogOut(
 		not_null<Main::Account*> account,
 		const TextWithEntities &explanation) {
-	const auto box = Ui::show(Box<Ui::InformBox>(
-		explanation,
-		tr::lng_passcode_logout(tr::now)));
+	const auto box = Ui::show(Ui::MakeConfirmBox({
+		.text = explanation,
+		.confirmText = tr::lng_passcode_logout(tr::now),
+		.inform = true,
+	}));
 	box->setCloseByEscape(false);
 	box->setCloseByOutsideClick(false);
 	const auto weak = base::make_weak(account.get());
diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp
index 4d75788cf..f11d771d9 100644
--- a/Telegram/SourceFiles/core/click_handler_types.cpp
+++ b/Telegram/SourceFiles/core/click_handler_types.cpp
@@ -117,12 +117,13 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) {
 				? QString::fromUtf8(parsedUrl.toEncoded())
 				: ShowEncoded(displayed);
 			Ui::show(
-				Box<Ui::ConfirmBox>(
-					(tr::lng_open_this_link(tr::now)
+				Ui::MakeConfirmBox({
+					.text = (tr::lng_open_this_link(tr::now)
 						+ qsl("\n\n")
 						+ displayUrl),
-					tr::lng_open_link(tr::now),
-					[=] { Ui::hideLayer(); open(); }),
+					.confirmed = [=] { Ui::hideLayer(); open(); },
+					.confirmText = tr::lng_open_link(),
+				}),
 				Ui::LayerOption::KeepOther);
 		} else {
 			open();
@@ -151,10 +152,11 @@ void BotGameUrlClickHandler::onClick(ClickContext context) const {
 			bot->session().local().markBotTrustedOpenGame(bot->id);
 			open();
 		};
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_allow_bot_pass(tr::now, lt_bot_name, _bot->name),
-			tr::lng_allow_bot(tr::now),
-			callback));
+		Ui::show(Ui::MakeConfirmBox({
+			.text = tr::lng_allow_bot_pass(tr::now, lt_bot_name, _bot->name),
+			.confirmed = callback,
+			.confirmText = tr::lng_allow_bot(),
+		}));
 	}
 }
 
diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp
index b80a16923..667a54f37 100644
--- a/Telegram/SourceFiles/core/local_url_handlers.cpp
+++ b/Telegram/SourceFiles/core/local_url_handlers.cpp
@@ -412,12 +412,13 @@ bool HandleUnknown(
 				Core::UpdateApplication();
 				close();
 			};
-			controller->show(Box<Ui::ConfirmBox>(
-				text,
-				tr::lng_menu_update(tr::now),
-				callback));
+			controller->show(Ui::MakeConfirmBox({
+				.text = text,
+				.confirmed = callback,
+				.confirmText = tr::lng_menu_update(),
+			}));
 		} else {
-			controller->show(Box<Ui::InformBox>(text));
+			controller->show(Ui::MakeInformBox(text));
 		}
 	});
 	controller->session().api().requestDeepLinkInfo(request, callback);
diff --git a/Telegram/SourceFiles/data/data_cloud_themes.cpp b/Telegram/SourceFiles/data/data_cloud_themes.cpp
index 15e07a476..620939249 100644
--- a/Telegram/SourceFiles/data/data_cloud_themes.cpp
+++ b/Telegram/SourceFiles/data/data_cloud_themes.cpp
@@ -224,8 +224,7 @@ void CloudThemes::resolve(
 		showPreview(controller, result);
 	}).fail([=](const MTP::Error &error) {
 		if (error.type() == qstr("THEME_FORMAT_INVALID")) {
-			controller->show(Box<Ui::InformBox>(
-				tr::lng_theme_no_desktop(tr::now)));
+			controller->show(Ui::MakeInformBox(tr::lng_theme_no_desktop()));
 		}
 	}).send();
 }
@@ -249,8 +248,7 @@ void CloudThemes::showPreview(
 			controller,
 			cloud));
 	} else {
-		controller->show(Box<Ui::InformBox>(
-			tr::lng_theme_no_desktop(tr::now)));
+		controller->show(Ui::MakeInformBox(tr::lng_theme_no_desktop()));
 	}
 }
 
diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index ef5e08ac8..40633a30a 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -934,9 +934,10 @@ void DocumentData::handleLoaderUpdates() {
 				Ui::hideLayer();
 				save(origin, failedFileName);
 			};
-			Ui::show(Box<Ui::ConfirmBox>(
-				tr::lng_download_finish_failed(tr::now),
-				crl::guard(&session(), retry)));
+			Ui::show(Ui::MakeConfirmBox({
+				tr::lng_download_finish_failed(),
+				crl::guard(&session(), retry)
+			}));
 		} else {
 			// Sometimes we have LOCATION_INVALID error in documents / stickers.
 			// Sometimes FILE_REFERENCE_EXPIRED could not be handled.
diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp
index 591b1c9ff..5c790ab21 100644
--- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp
+++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp
@@ -402,7 +402,7 @@ void Stickers::undoInstallLocally(uint64 setId) {
 	notifyUpdated();
 
 	Ui::show(
-		Box<Ui::InformBox>(tr::lng_stickers_not_found(tr::now)),
+		Ui::MakeInformBox(tr::lng_stickers_not_found()),
 		Ui::LayerOption::KeepOther);
 }
 
diff --git a/Telegram/SourceFiles/editor/editor_paint.cpp b/Telegram/SourceFiles/editor/editor_paint.cpp
index a943318e7..76f716a0d 100644
--- a/Telegram/SourceFiles/editor/editor_paint.cpp
+++ b/Telegram/SourceFiles/editor/editor_paint.cpp
@@ -195,7 +195,7 @@ void Paint::handleMimeData(const QMimeData *data) {
 		}
 		if (!Ui::ValidateThumbDimensions(image.width(), image.height())) {
 			_controllers->showBox(
-				Box<Ui::InformBox>(tr::lng_edit_media_invalid_file(tr::now)));
+				Ui::MakeInformBox(tr::lng_edit_media_invalid_file()));
 			return;
 		}
 
diff --git a/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp
index 76c5dd1c8..45b7ff471 100644
--- a/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp
+++ b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp
@@ -87,7 +87,7 @@ void PrepareProfilePhoto(
 		if (image.isNull()
 			|| (image.width() > (10 * image.height()))
 			|| (image.height() > (10 * image.width()))) {
-			controller->show(Box<Ui::InformBox>(tr::lng_bad_photo(tr::now)));
+			controller->show(Ui::MakeInformBox(tr::lng_bad_photo()));
 			return;
 		}
 		image = resizeToMinSize(
diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
index 8a9baaaaa..5dee830bd 100644
--- a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
+++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
@@ -273,7 +273,7 @@ void PanelController::showCriticalError(const QString &text) {
 }
 
 void PanelController::showError(const QString &text) {
-	auto box = Box<Ui::InformBox>(text);
+	auto box = Ui::MakeInformBox(text);
 	const auto weak = Ui::MakeWeak(box.data());
 	const auto hidden = _panel->isHidden();
 	_panel->showBox(
@@ -349,11 +349,12 @@ void PanelController::stopWithConfirmation(Fn<void()> callback) {
 	};
 	const auto hidden = _panel->isHidden();
 	const auto old = _confirmStopBox;
-	auto box = Box<Ui::ConfirmBox>(
-		tr::lng_export_sure_stop(tr::now),
-		tr::lng_export_stop(tr::now),
-		st::attentionBoxButton,
-		std::move(stop));
+	auto box = Ui::MakeConfirmBox({
+		.text = tr::lng_export_sure_stop(),
+		.confirmed = std::move(stop),
+		.confirmText = tr::lng_export_stop(),
+		.confirmStyle = &st::attentionBoxButton,
+	});
 	_confirmStopBox = box.data();
 	_panel->showBox(
 		std::move(box),
diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp
index 4f12da3bd..f79655a0d 100644
--- a/Telegram/SourceFiles/facades.cpp
+++ b/Telegram/SourceFiles/facades.cpp
@@ -140,18 +140,16 @@ void activateBotCommand(
 
 	case ButtonType::RequestLocation: {
 		hideSingleUseKeyboard(msg);
-		Ui::show(Box<Ui::InformBox>(
-			tr::lng_bot_share_location_unavailable(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_bot_share_location_unavailable()));
 	} break;
 
 	case ButtonType::RequestPhone: {
 		hideSingleUseKeyboard(msg);
 		const auto msgId = msg->id;
 		const auto history = msg->history();
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_bot_share_phone(tr::now),
-			tr::lng_bot_share_phone_confirm(tr::now),
-			[=] {
+		Ui::show(Ui::MakeConfirmBox({
+			.text = tr::lng_bot_share_phone(),
+			.confirmed = [=] {
 				Ui::showPeerHistory(history, ShowAtTheEndMsgId);
 				auto action = Api::SendAction(history);
 				action.clearDraft = false;
@@ -159,7 +157,9 @@ void activateBotCommand(
 				history->session().api().shareContact(
 					history->session().user(),
 					action);
-			}));
+			},
+			.confirmText = tr::lng_bot_share_phone_confirm(),
+		}));
 	} break;
 
 	case ButtonType::RequestPoll: {
diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp
index e310b7499..d329bad78 100644
--- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp
+++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp
@@ -1431,7 +1431,7 @@ void InnerWidget::suggestRestrictParticipant(
 					(*weakBox)->closeBox();
 				}
 			});
-			*weakBox = _controller->show(Box<Ui::ConfirmBox>(text, sure));
+			*weakBox = _controller->show(Ui::MakeConfirmBox({ text, sure }));
 		} else if (base::contains(_admins, user)) {
 			editRestrictions(true, ChatRestrictionsInfo());
 		} else {
diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_section.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_section.cpp
index b8c9e76dc..774f4ee03 100644
--- a/Telegram/SourceFiles/history/admin_log/history_admin_log_section.cpp
+++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_section.cpp
@@ -328,9 +328,9 @@ Widget::Widget(
 	}, lifetime());
 
 	_whatIsThis->setClickedCallback([=] {
-		controller->show(Box<Ui::InformBox>(channel->isMegagroup()
-			? tr::lng_admin_log_about_text(tr::now)
-			: tr::lng_admin_log_about_text_channel(tr::now)));
+		controller->show(Ui::MakeInformBox(channel->isMegagroup()
+			? tr::lng_admin_log_about_text()
+			: tr::lng_admin_log_about_text_channel()));
 	});
 
 	setupShortcuts();
diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp
index 1e044f944..6280ee91c 100644
--- a/Telegram/SourceFiles/history/history_message.cpp
+++ b/Telegram/SourceFiles/history/history_message.cpp
@@ -278,7 +278,7 @@ void FastShareMessage(not_null<HistoryItem*> item) {
 			}
 			text.append(error.first);
 			Ui::show(
-				Box<Ui::InformBox>(text),
+				Ui::MakeInformBox(text),
 				Ui::LayerOption::KeepOther);
 			return;
 		}
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index dbf13c51c..39f2ea80d 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -707,7 +707,7 @@ HistoryWidget::HistoryWidget(
 			const auto unavailable = _peer->computeUnavailableReason();
 			if (!unavailable.isEmpty()) {
 				controller->showBackFromStack();
-				controller->show(Box<Ui::InformBox>(unavailable));
+				controller->show(Ui::MakeInformBox(unavailable));
 				return;
 			}
 		}
@@ -896,7 +896,7 @@ void HistoryWidget::initVoiceRecordBar() {
 			? Data::RestrictionError(_peer, ChatRestriction::SendMedia)
 			: std::nullopt;
 		if (error) {
-			controller()->show(Box<Ui::InformBox>(*error));
+			controller()->show(Ui::MakeInformBox(*error));
 			return true;
 		} else if (showSlowmodeError()) {
 			return true;
@@ -3528,8 +3528,7 @@ void HistoryWidget::saveEditMsg() {
 			Box<DeleteMessagesBox>(item, suggestModerateActions));
 		return;
 	} else if (!left.text.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(
-			tr::lng_edit_too_long(tr::now)));
+		controller()->show(Ui::MakeInformBox(tr::lng_edit_too_long()));
 		return;
 	}
 
@@ -3563,16 +3562,14 @@ void HistoryWidget::saveEditMsg() {
 			}
 			const auto &err = error.type();
 			if (ranges::contains(Api::kDefaultEditMessagesErrors, err)) {
-				controller()->show(
-					Box<Ui::InformBox>(tr::lng_edit_error(tr::now)));
+				controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 			} else if (err == u"MESSAGE_NOT_MODIFIED"_q) {
 				cancelEdit();
 			} else if (err == u"MESSAGE_EMPTY"_q) {
 				_field->selectAll();
 				_field->setFocus();
 			} else {
-				controller()->show(
-					Box<Ui::InformBox>(tr::lng_edit_error(tr::now)));
+				controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 			}
 			update();
 		})();
@@ -3964,8 +3961,7 @@ void HistoryWidget::cornerButtonsAnimationFinish() {
 
 void HistoryWidget::chooseAttach() {
 	if (_editMsgId) {
-		controller()->show(
-			Box<Ui::InformBox>(tr::lng_edit_caption_attach(tr::now)));
+		controller()->show(Ui::MakeInformBox(tr::lng_edit_caption_attach()));
 		return;
 	}
 
@@ -4793,8 +4789,7 @@ bool HistoryWidget::confirmSendingFiles(
 		return false;
 	}
 	if (_editMsgId) {
-		controller()->show(
-			Box<Ui::InformBox>(tr::lng_edit_caption_attach(tr::now)));
+		controller()->show(Ui::MakeInformBox(tr::lng_edit_caption_attach()));
 		return false;
 	}
 
@@ -6047,7 +6042,7 @@ void HistoryWidget::sendInlineResult(InlineBots::ResultSelected result) {
 
 	auto errorText = result.result->getErrorOnSend(_history);
 	if (!errorText.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(errorText));
+		controller()->show(Ui::MakeInformBox(errorText));
 		return;
 	}
 
@@ -6433,7 +6428,7 @@ bool HistoryWidget::sendExistingDocument(
 		: std::nullopt;
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	} else if (!_peer || !_peer->canWrite()) {
@@ -6469,7 +6464,7 @@ bool HistoryWidget::sendExistingPhoto(
 		: std::nullopt;
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	} else if (!_peer || !_peer->canWrite()) {
@@ -6552,19 +6547,19 @@ void HistoryWidget::replyToMessage(not_null<HistoryItem*> item) {
 		return;
 	} else if (item->history() == _migrated) {
 		if (item->isService()) {
-			controller()->show(Box<Ui::InformBox>(
-				tr::lng_reply_cant(tr::now)));
+			controller()->show(Ui::MakeInformBox(tr::lng_reply_cant()));
 		} else {
 			const auto itemId = item->fullId();
 			controller()->show(
-				Box<Ui::ConfirmBox>(
-					tr::lng_reply_cant_forward(tr::now),
-					tr::lng_selected_forward(tr::now),
-					crl::guard(this, [=] {
+				Ui::MakeConfirmBox({
+					.text = tr::lng_reply_cant_forward(),
+					.confirmed = crl::guard(this, [=] {
 						controller()->content()->setForwardDraft(
 							_peer->id,
 							{ .ids = { 1, itemId } });
-					})));
+					}),
+					.confirmText = tr::lng_selected_forward(),
+				}));
 		}
 		return;
 	}
@@ -6615,7 +6610,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
 		toggleChooseChatTheme(_peer);
 	} else if (_voiceRecordBar->isActive()) {
 		controller()->show(
-			Box<Ui::InformBox>(tr::lng_edit_caption_voice(tr::now)));
+			Ui::MakeInformBox(tr::lng_edit_caption_voice()));
 		return;
 	}
 
@@ -7070,16 +7065,17 @@ void HistoryWidget::escape() {
 	} else if (_editMsgId) {
 		if (_replyEditMsg
 			&& PrepareEditText(_replyEditMsg) != _field->getTextWithTags()) {
-			controller()->show(Box<Ui::ConfirmBox>(
-				tr::lng_cancel_edit_post_sure(tr::now),
-				tr::lng_cancel_edit_post_yes(tr::now),
-				tr::lng_cancel_edit_post_no(tr::now),
-				crl::guard(this, [this] {
+			controller()->show(Ui::MakeConfirmBox({
+				.text = tr::lng_cancel_edit_post_sure(),
+				.confirmed = crl::guard(this, [this] {
 					if (_editMsgId) {
 						cancelEdit();
 						Ui::hideLayer();
 					}
-				})));
+				}),
+				.confirmText = tr::lng_cancel_edit_post_yes(),
+				.cancelText = tr::lng_cancel_edit_post_no(),
+			}));
 		} else {
 			cancelEdit();
 		}
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
index a8c2ec6c8..c448d35a0 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
+++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
@@ -811,8 +811,7 @@ rpl::producer<> ComposeControls::attachRequests() const {
 		_attachRequests.events()
 	) | rpl::filter([=] {
 		if (isEditingMessage()) {
-			_window->show(
-				Box<Ui::InformBox>(tr::lng_edit_caption_attach(tr::now)));
+			_window->show(Ui::MakeInformBox(tr::lng_edit_caption_attach()));
 			return false;
 		}
 		return true;
@@ -1753,7 +1752,7 @@ void ComposeControls::initVoiceRecordBar() {
 				ChatRestriction::SendMedia)
 			: std::nullopt;
 		if (error) {
-			_window->show(Box<Ui::InformBox>(*error));
+			_window->show(Ui::MakeInformBox(*error));
 			return true;
 		} else if (_showSlowmodeError && _showSlowmodeError()) {
 			return true;
@@ -2083,8 +2082,7 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
 	Expects(draftKeyCurrent() != Data::DraftKey::None());
 
 	if (_voiceRecordBar->isActive()) {
-		_window->show(Box<Ui::InformBox>(
-			tr::lng_edit_caption_voice(tr::now)));
+		_window->show(Ui::MakeInformBox(tr::lng_edit_caption_voice()));
 		return;
 	}
 
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
index 72d04cb96..642de93a3 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
+++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
@@ -1650,13 +1650,14 @@ void VoiceRecordBar::showDiscardBox(
 			callback();
 		}
 	};
-	_controller->show(Box<Ui::ConfirmBox>(
-		(isListenState()
+	_controller->show(Ui::MakeConfirmBox({
+		.text = (isListenState()
 			? tr::lng_record_listen_cancel_sure
-			: tr::lng_record_lock_cancel_sure)(tr::now),
-		tr::lng_record_lock_discard(tr::now),
-		st::attentionBoxButton,
-		std::move(sure)));
+			: tr::lng_record_lock_cancel_sure)(),
+		.confirmed = std::move(sure),
+		.confirmText = tr::lng_record_lock_discard(),
+		.confirmStyle = &st::attentionBoxButton,
+	}));
 	_warningShown = true;
 }
 
diff --git a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp
index bb385ac3a..8f44c2b25 100644
--- a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp
@@ -454,8 +454,8 @@ void ContactStatus::setupShareHandler(not_null<UserData*> user) {
 			}).send();
 			close();
 		};
-		_controller->window().show(Box<Ui::ConfirmBox>(
-			tr::lng_new_contact_share_sure(
+		_controller->window().show(Ui::MakeConfirmBox({
+			.text = tr::lng_new_contact_share_sure(
 				tr::now,
 				lt_phone,
 				Ui::Text::WithEntities(
@@ -463,8 +463,9 @@ void ContactStatus::setupShareHandler(not_null<UserData*> user) {
 				lt_user,
 				Ui::Text::Bold(user->name),
 				Ui::Text::WithEntities),
-			tr::lng_box_ok(tr::now),
-			share));
+			.confirmed = share,
+			.confirmText = tr::lng_box_ok(),
+		}));
 	}, _bar.lifetime());
 }
 
@@ -509,14 +510,15 @@ void ContactStatus::setupReportHandler(not_null<PeerData*> peer) {
 		if (const auto user = peer->asUser()) {
 			peer->session().api().blockedPeers().block(user);
 		}
-		const auto text = ((peer->isChat() || peer->isMegagroup())
+		auto text = ((peer->isChat() || peer->isMegagroup())
 			? tr::lng_report_spam_sure_group
-			: tr::lng_report_spam_sure_channel)(tr::now);
-		_controller->window().show(Box<Ui::ConfirmBox>(
-			text,
-			tr::lng_report_spam_ok(tr::now),
-			st::attentionBoxButton,
-			callback));
+			: tr::lng_report_spam_sure_channel)();
+		_controller->window().show(Ui::MakeConfirmBox({
+			.text= std::move(text),
+			.confirmed = callback,
+			.confirmText = tr::lng_report_spam_ok(),
+			.confirmStyle = &st::attentionBoxButton,
+		}));
 	}, _bar.lifetime());
 }
 
diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
index 6c2a6a9c1..cbc027573 100644
--- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
@@ -1036,11 +1036,12 @@ void StopPoll(not_null<Main::Session*> session, FullMsgId itemId) {
 			session->api().polls().close(item);
 		}
 	};
-	Ui::show(Box<Ui::ConfirmBox>(
-		tr::lng_polls_stop_warning(tr::now),
-		tr::lng_polls_stop_sure(tr::now),
-		tr::lng_cancel(tr::now),
-		stop));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = tr::lng_polls_stop_warning(),
+		.confirmed = stop,
+		.confirmText = tr::lng_polls_stop_sure(),
+		.cancelText = tr::lng_cancel(),
+	}));
 }
 
 void AddPollActions(
diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp
index e488db7ef..2f5946bf0 100644
--- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp
@@ -1017,8 +1017,7 @@ void RepliesWidget::edit(
 		}
 		return;
 	} else if (!left.text.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(
-			tr::lng_edit_too_long(tr::now)));
+		controller()->show(Ui::MakeInformBox(tr::lng_edit_too_long()));
 		return;
 	}
 
@@ -1043,15 +1042,13 @@ void RepliesWidget::edit(
 
 		const auto &err = error.type();
 		if (ranges::contains(Api::kDefaultEditMessagesErrors, err)) {
-			controller()->show(Box<Ui::InformBox>(
-				tr::lng_edit_error(tr::now)));
+			controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 		} else if (err == u"MESSAGE_NOT_MODIFIED"_q) {
 			_composeControls->cancelEditMessage();
 		} else if (err == u"MESSAGE_EMPTY"_q) {
 			doSetInnerFocus();
 		} else {
-			controller()->show(Box<Ui::InformBox>(
-				tr::lng_edit_error(tr::now)));
+			controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 		}
 		update();
 		return true;
@@ -1089,7 +1086,7 @@ bool RepliesWidget::sendExistingDocument(
 		ChatRestriction::SendStickers);
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	} else if (showSlowmodeError()) {
@@ -1125,7 +1122,7 @@ bool RepliesWidget::sendExistingPhoto(
 		ChatRestriction::SendMedia);
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	} else if (showSlowmodeError()) {
@@ -1146,7 +1143,7 @@ void RepliesWidget::sendInlineResult(
 		not_null<UserData*> bot) {
 	const auto errorText = result->getErrorOnSend(_history);
 	if (!errorText.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(errorText));
+		controller()->show(Ui::MakeInformBox(errorText));
 		return;
 	}
 	sendInlineResult(result, bot, {}, std::nullopt);
diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
index c4e284381..122769f27 100644
--- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp
@@ -616,8 +616,7 @@ void ScheduledWidget::edit(
 		}
 		return;
 	} else if (!left.text.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(
-			tr::lng_edit_too_long(tr::now)));
+		controller()->show(Ui::MakeInformBox(tr::lng_edit_too_long()));
 		return;
 	}
 
@@ -642,15 +641,13 @@ void ScheduledWidget::edit(
 
 		const auto &err = error.type();
 		if (ranges::contains(Api::kDefaultEditMessagesErrors, err)) {
-			controller()->show(Box<Ui::InformBox>(
-				tr::lng_edit_error(tr::now)));
+			controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 		} else if (err == u"MESSAGE_NOT_MODIFIED"_q) {
 			_composeControls->cancelEditMessage();
 		} else if (err == u"MESSAGE_EMPTY"_q) {
 			_composeControls->focus();
 		} else {
-			controller()->show(Box<Ui::InformBox>(
-				tr::lng_edit_error(tr::now)));
+			controller()->show(Ui::MakeInformBox(tr::lng_edit_error()));
 		}
 		update();
 		return true;
@@ -685,7 +682,7 @@ bool ScheduledWidget::sendExistingDocument(
 		ChatRestriction::SendStickers);
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	}
@@ -716,7 +713,7 @@ bool ScheduledWidget::sendExistingPhoto(
 		ChatRestriction::SendMedia);
 	if (error) {
 		controller()->show(
-			Box<Ui::InformBox>(*error),
+			Ui::MakeInformBox(*error),
 			Ui::LayerOption::KeepOther);
 		return false;
 	}
@@ -735,7 +732,7 @@ void ScheduledWidget::sendInlineResult(
 		not_null<UserData*> bot) {
 	const auto errorText = result->getErrorOnSend(_history);
 	if (!errorText.isEmpty()) {
-		controller()->show(Box<Ui::InformBox>(errorText));
+		controller()->show(Ui::MakeInformBox(errorText));
 		return;
 	}
 	const auto callback = [=](Api::SendOptions options) {
diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp
index 0c1da4beb..e1c4de3c2 100644
--- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp
+++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp
@@ -1093,11 +1093,12 @@ void ListWidget::deleteItems(SelectedItems &&items, Fn<void()> confirmed) {
 				confirmed();
 			}
 		};
-		setActionBoxWeak(window->show(Box<Ui::ConfirmBox>(
-			phrase,
-			tr::lng_box_delete(tr::now),
-			st::attentionBoxButton,
-			deleteSure)));
+		setActionBoxWeak(window->show(Ui::MakeConfirmBox({
+			.text = phrase,
+			.confirmed = deleteSure,
+			.confirmText = tr::lng_box_delete(tr::now),
+			.confirmStyle = &st::attentionBoxButton,
+		})));
 	} else if (auto list = collectSelectedIds(items); !list.empty()) {
 		auto box = Box<DeleteMessagesBox>(
 			&_controller->session(),
diff --git a/Telegram/SourceFiles/intro/intro_code.cpp b/Telegram/SourceFiles/intro/intro_code.cpp
index c38770e34..f7c91adcc 100644
--- a/Telegram/SourceFiles/intro/intro_code.cpp
+++ b/Telegram/SourceFiles/intro/intro_code.cpp
@@ -351,10 +351,11 @@ void CodeWidget::gotPassword(const MTPaccount_Password &result) {
 			Core::UpdateApplication();
 			close();
 		};
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_passport_app_out_of_date(tr::now),
-			tr::lng_menu_update(tr::now),
-			callback));
+		Ui::show(Ui::MakeConfirmBox({
+			.text = tr::lng_passport_app_out_of_date(),
+			.confirmed = callback,
+			.confirmText = tr::lng_menu_update(),
+		}));
 		return;
 	}
 	goReplace<PasswordCheckWidget>(Animate::Forward);
diff --git a/Telegram/SourceFiles/intro/intro_password_check.cpp b/Telegram/SourceFiles/intro/intro_password_check.cpp
index 6c3cc5126..256facf57 100644
--- a/Telegram/SourceFiles/intro/intro_password_check.cpp
+++ b/Telegram/SourceFiles/intro/intro_password_check.cpp
@@ -311,16 +311,22 @@ void PasswordCheckWidget::toRecover() {
 			}).send();
 		}
 	} else {
-		Ui::show(Box<Ui::InformBox>(
-			tr::lng_signin_no_email_forgot(tr::now),
-			[=] { showReset(); }));
+		const auto box = Ui::show(
+			Ui::MakeInformBox(tr::lng_signin_no_email_forgot()));
+		box->boxClosing(
+		) | rpl::start_with_next([=] {
+			showReset();
+		}, box->lifetime());
 	}
 }
 
 void PasswordCheckWidget::toPassword() {
-	Ui::show(Box<Ui::InformBox>(
-		tr::lng_signin_cant_email_forgot(tr::now),
-		[=] { showReset(); }));
+	const auto box = Ui::show(
+		Ui::MakeInformBox(tr::lng_signin_cant_email_forgot()));
+	box->boxClosing(
+	) | rpl::start_with_next([=] {
+		showReset();
+	}, box->lifetime());
 }
 
 void PasswordCheckWidget::showReset() {
@@ -372,10 +378,11 @@ void PasswordCheckWidget::submit() {
 				send();
 				close();
 			};
-			Ui::show(Box<Ui::ConfirmBox>(
-				tr::lng_cloud_password_passport_losing(tr::now),
-				tr::lng_continue(tr::now),
-				confirmed));
+			Ui::show(Ui::MakeConfirmBox({
+				.text = tr::lng_cloud_password_passport_losing(),
+				.confirmed = confirmed,
+				.confirmText = tr::lng_continue(),
+			}));
 		} else {
 			send();
 		}
diff --git a/Telegram/SourceFiles/intro/intro_phone.cpp b/Telegram/SourceFiles/intro/intro_phone.cpp
index adb9c55a7..706f2a1f8 100644
--- a/Telegram/SourceFiles/intro/intro_phone.cpp
+++ b/Telegram/SourceFiles/intro/intro_phone.cpp
@@ -240,7 +240,7 @@ void PhoneWidget::phoneSubmitFail(const MTP::Error &error) {
 	_sentRequest = 0;
 	auto &err = error.type();
 	if (err == qstr("PHONE_NUMBER_FLOOD")) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_error_phone_flood(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_error_phone_flood()));
 	} else if (err == qstr("PHONE_NUMBER_INVALID")) { // show error
 		showPhoneError(tr::lng_bad_phone());
 	} else if (err == qstr("PHONE_NUMBER_BANNED")) {
diff --git a/Telegram/SourceFiles/intro/intro_qr.cpp b/Telegram/SourceFiles/intro/intro_qr.cpp
index 5426051b1..8774ebadf 100644
--- a/Telegram/SourceFiles/intro/intro_qr.cpp
+++ b/Telegram/SourceFiles/intro/intro_qr.cpp
@@ -401,10 +401,11 @@ void QrWidget::sendCheckPasswordRequest() {
 					Core::UpdateApplication();
 					close();
 				};
-				Ui::show(Box<Ui::ConfirmBox>(
-					tr::lng_passport_app_out_of_date(tr::now),
-					tr::lng_menu_update(tr::now),
-					callback));
+				Ui::show(Ui::MakeConfirmBox({
+					.text = tr::lng_passport_app_out_of_date(),
+					.confirmed = callback,
+					.confirmText = tr::lng_menu_update(),
+				}));
 				return;
 			}
 			goReplace<PasswordCheckWidget>(Animate::Forward);
diff --git a/Telegram/SourceFiles/intro/intro_signup.cpp b/Telegram/SourceFiles/intro/intro_signup.cpp
index 2114b5893..1609fdfa3 100644
--- a/Telegram/SourceFiles/intro/intro_signup.cpp
+++ b/Telegram/SourceFiles/intro/intro_signup.cpp
@@ -130,7 +130,7 @@ void SignupWidget::nameSubmitFail(const MTP::Error &error) {
 
 	auto &err = error.type();
 	if (err == qstr("PHONE_NUMBER_FLOOD")) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_error_phone_flood(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_error_phone_flood()));
 	} else if (err == qstr("PHONE_NUMBER_INVALID")
 		|| err == qstr("PHONE_NUMBER_BANNED")
 		|| err == qstr("PHONE_CODE_EXPIRED")
diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp
index c626ea867..a744c8402 100644
--- a/Telegram/SourceFiles/intro/intro_step.cpp
+++ b/Telegram/SourceFiles/intro/intro_step.cpp
@@ -142,7 +142,7 @@ void Step::finish(const MTPUser &user, QImage &&photo) {
 		|| !user.c_user().vid().v) {
 		// No idea what to do here.
 		// We could've reset intro and MTP, but this really should not happen.
-		Ui::show(Box<Ui::InformBox>(
+		Ui::show(Ui::MakeInformBox(
 			"Internal error: bad user.is_self() after sign in."));
 		return;
 	}
diff --git a/Telegram/SourceFiles/intro/intro_widget.cpp b/Telegram/SourceFiles/intro/intro_widget.cpp
index ca6ff3b28..138a1cf56 100644
--- a/Telegram/SourceFiles/intro/intro_widget.cpp
+++ b/Telegram/SourceFiles/intro/intro_widget.cpp
@@ -237,7 +237,7 @@ void Widget::handleUpdate(const MTPUpdate &update) {
 			qs(data.vmessage()),
 			Api::EntitiesFromMTP(nullptr, data.ventities().v)
 		};
-		Ui::show(Box<Ui::InformBox>(text));
+		Ui::show(Ui::MakeInformBox(text));
 	}, [](const auto &) {});
 }
 
@@ -551,15 +551,15 @@ void Widget::resetAccount() {
 						lt_minutes_count,
 						when);
 				}
-				Ui::show(Box<Ui::InformBox>(tr::lng_signin_reset_wait(
+				Ui::show(Ui::MakeInformBox(tr::lng_signin_reset_wait(
 					tr::now,
 					lt_phone_number,
 					Ui::FormatPhone(getData()->phone),
 					lt_when,
 					when)));
 			} else if (type == qstr("2FA_RECENT_CONFIRM")) {
-				Ui::show(Box<Ui::InformBox>(
-					tr::lng_signin_reset_cancelled(tr::now)));
+				Ui::show(Ui::MakeInformBox(
+					tr::lng_signin_reset_cancelled()));
 			} else {
 				Ui::hideLayer();
 				getStep()->showError(rpl::single(Lang::Hard::ServerError()));
@@ -567,11 +567,12 @@ void Widget::resetAccount() {
 		}).send();
 	});
 
-	Ui::show(Box<Ui::ConfirmBox>(
-		tr::lng_signin_sure_reset(tr::now),
-		tr::lng_signin_reset(tr::now),
-		st::attentionBoxButton,
-		callback));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = tr::lng_signin_sure_reset(),
+		.confirmed = callback,
+		.confirmText = tr::lng_signin_reset(),
+		.confirmStyle = &st::attentionBoxButton,
+	}));
 }
 
 void Widget::getNearestDC() {
diff --git a/Telegram/SourceFiles/lang/lang_cloud_manager.cpp b/Telegram/SourceFiles/lang/lang_cloud_manager.cpp
index 41d352d2c..f568c8178 100644
--- a/Telegram/SourceFiles/lang/lang_cloud_manager.cpp
+++ b/Telegram/SourceFiles/lang/lang_cloud_manager.cpp
@@ -367,14 +367,14 @@ bool CloudManager::showOfferSwitchBox() {
 		Local::writeLangPack();
 	};
 	Ui::show(
-		Box<Ui::ConfirmBox>(
-			"Do you want to switch your language to "
+		Ui::MakeConfirmBox({
+			.text = QString("Do you want to switch your language to ")
 			+ language.nativeName
-			+ "? You can always change your language in Settings.",
-			"Change",
-			tr::lng_cancel(tr::now),
-			confirm,
-			cancel),
+			+ QString("? You can always change your language in Settings."),
+			.confirmed = confirm,
+			.cancelled = cancel,
+			.confirmText = QString("Change"),
+		}),
 		Ui::LayerOption::KeepOther);
 	return true;
 }
@@ -419,7 +419,7 @@ void CloudManager::requestLanguageAndSwitch(
 	Expects(!id.isEmpty());
 
 	if (LanguageIdOrDefault(_langpack.id()) == id) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_language_already(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_language_already()));
 		return;
 	} else if (id == qstr("#custom")) {
 		performSwitchToCustom();
@@ -464,7 +464,7 @@ void CloudManager::sendSwitchingToLanguageRequest() {
 	}).fail([=](const MTP::Error &error) {
 		_switchingToLanguageRequest = 0;
 		if (error.type() == "LANG_CODE_NOT_SUPPORTED") {
-			Ui::show(Box<Ui::InformBox>(tr::lng_language_not_found(tr::now)));
+			Ui::show(Ui::MakeInformBox(tr::lng_language_not_found()));
 		}
 	}).send();
 }
@@ -502,11 +502,11 @@ void CloudManager::switchToLanguage(const Language &data) {
 				+ "\n\n"
 				+ getValue(tr::lng_sure_save_language.base);
 			Ui::show(
-				Box<Ui::ConfirmBox>(
-					text,
-					tr::lng_box_ok(tr::now),
-					tr::lng_cancel(tr::now),
-					[=] { performSwitchAndRestart(data); }),
+				Ui::MakeConfirmBox({
+					.text = text,
+					.confirmed = [=] { performSwitchAndRestart(data); },
+					.confirmText = tr::lng_box_ok(),
+				}),
 				Ui::LayerOption::KeepOther);
 		}).fail([=] {
 			_getKeysForSwitchRequestId = 0;
@@ -550,16 +550,16 @@ void CloudManager::performSwitchToCustom() {
 					Core::Restart();
 				};
 				Ui::show(
-					Box<Ui::ConfirmBox>(
-						text,
-						tr::lng_box_ok(tr::now),
-						tr::lng_cancel(tr::now),
-						change),
+					Ui::MakeConfirmBox({
+						.text = text,
+						.confirmed = change,
+						.confirmText = tr::lng_box_ok(),
+					}),
 					Ui::LayerOption::KeepOther);
 			}
 		} else {
 			Ui::show(
-				Box<Ui::InformBox>(
+				Ui::MakeInformBox(
 					"Custom lang failed :(\n\nError: " + loader.errors()),
 				Ui::LayerOption::KeepOther);
 		}
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 4346f5bcb..12d0a8777 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -504,7 +504,7 @@ bool MainWidget::setForwardDraft(PeerId peerId, Data::ForwardDraft &&draft) {
 		session().data().idsToItems(draft.ids),
 		true);
 	if (!error.isEmpty()) {
-		Ui::show(Box<Ui::InformBox>(error), Ui::LayerOption::KeepOther);
+		Ui::show(Ui::MakeInformBox(error), Ui::LayerOption::KeepOther);
 		return false;
 	}
 
@@ -525,7 +525,7 @@ bool MainWidget::shareUrl(
 
 	const auto peer = session().data().peer(peerId);
 	if (!peer->canWrite()) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_share_cant(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_share_cant()));
 		return false;
 	}
 	TextWithTags textWithTags = {
@@ -555,7 +555,7 @@ bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) {
 
 	const auto peer = session().data().peer(peerId);
 	if (!peer->canWrite()) {
-		Ui::show(Box<Ui::InformBox>(tr::lng_inline_switch_cant(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_inline_switch_cant()));
 		return false;
 	}
 	const auto h = peer->owner().history(peer);
@@ -578,13 +578,12 @@ bool MainWidget::sendPaths(PeerId peerId) {
 
 	auto peer = session().data().peer(peerId);
 	if (!peer->canWrite()) {
-		Ui::show(Box<Ui::InformBox>(
-			tr::lng_forward_send_files_cant(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant()));
 		return false;
 	} else if (const auto error = Data::RestrictionError(
 			peer,
 			ChatRestriction::SendMedia)) {
-		Ui::show(Box<Ui::InformBox>(*error));
+		Ui::show(Ui::MakeInformBox(*error));
 		return false;
 	}
 	Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
@@ -610,8 +609,7 @@ void MainWidget::onFilesOrForwardDrop(
 	} else {
 		auto peer = session().data().peer(peerId);
 		if (!peer->canWrite()) {
-			Ui::show(Box<Ui::InformBox>(
-				tr::lng_forward_send_files_cant(tr::now)));
+			Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant()));
 			return;
 		}
 		Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
@@ -1302,7 +1300,7 @@ void MainWidget::ui_showPeerHistory(
 		const auto unavailable = peer->computeUnavailableReason();
 		if (!unavailable.isEmpty()) {
 			if (params.activation != anim::activation::background) {
-				controller()->show(Box<Ui::InformBox>(unavailable));
+				controller()->show(Ui::MakeInformBox(unavailable));
 			}
 			return;
 		}
@@ -2046,7 +2044,7 @@ void MainWidget::hideAll() {
 void MainWidget::showAll() {
 	if (cPasswordRecovered()) {
 		cSetPasswordRecovered(false);
-		Ui::show(Box<Ui::InformBox>(tr::lng_cloud_password_updated(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_cloud_password_updated()));
 	}
 	if (isOneColumn()) {
 		if (_sideShadow) {
@@ -2643,7 +2641,7 @@ void MainWidget::activate() {
 						_controller,
 						path.mid(interpret.size()));
 					if (!error.isEmpty()) {
-						Ui::show(Box<Ui::InformBox>(error));
+						Ui::show(Ui::MakeInformBox(error));
 					}
 				} else {
 					showSendPathsLayer();
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index a5edbcb43..def8e4fbe 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -743,7 +743,7 @@ bool MainWindow::skipTrayClick() const {
 void MainWindow::toggleDisplayNotifyFromTray() {
 	if (controller().locked()) {
 		if (!isActive()) showFromTray();
-		Ui::show(Box<Ui::InformBox>(tr::lng_passcode_need_unblock(tr::now)));
+		Ui::show(Ui::MakeInformBox(tr::lng_passcode_need_unblock()));
 		return;
 	}
 	if (!sessionController()) {
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
index d9c1ca17a..7a99a21f1 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
@@ -1815,13 +1815,14 @@ void OverlayWidget::deleteMedia() {
 		if (deletingPeerPhoto) {
 			if (photo) {
 				window->show(
-					Box<Ui::ConfirmBox>(
-						tr::lng_delete_photo_sure(tr::now),
-						tr::lng_box_delete(tr::now),
-						crl::guard(_widget, [=] {
+					Ui::MakeConfirmBox({
+						.text = tr::lng_delete_photo_sure(),
+						.confirmed = crl::guard(_widget, [=] {
 							session->api().peerPhoto().clear(photo);
 							Ui::hideLayer();
-						})),
+						}),
+						.confirmText = tr::lng_box_delete(),
+					}),
 					Ui::LayerOption::CloseOther);
 			}
 		} else if (message) {
diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp
index c5d99e0a9..ff1a64b83 100644
--- a/Telegram/SourceFiles/passport/passport_form_controller.cpp
+++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp
@@ -765,7 +765,7 @@ std::vector<not_null<const Value*>> FormController::submitGetErrors() {
 		} else if (AcceptErrorRequiresRestart(error.type())) {
 			suggestRestart();
 		} else {
-			_view->show(Box<Ui::InformBox>(
+			_view->show(Ui::MakeInformBox(
 				Lang::Hard::SecureAcceptError() + "\n" + error.type()));
 		}
 	}).send();
@@ -974,8 +974,7 @@ void FormController::checkSavedPasswordSettings(
 
 void FormController::recoverPassword() {
 	if (!_password.hasRecovery) {
-		_view->show(Box<Ui::InformBox>(
-			tr::lng_signin_no_email_forgot(tr::now)));
+		_view->show(Ui::MakeInformBox(tr::lng_signin_no_email_forgot()));
 		return;
 	} else if (_recoverRequestId) {
 		return;
@@ -1015,7 +1014,7 @@ void FormController::recoverPassword() {
 		}, box->lifetime());
 	}).fail([=](const MTP::Error &error) {
 		_recoverRequestId = 0;
-		_view->show(Box<Ui::InformBox>(Lang::Hard::ServerError()
+		_view->show(Ui::MakeInformBox(Lang::Hard::ServerError()
 			+ '\n'
 			+ error.type()));
 	}).send();
@@ -2245,7 +2244,7 @@ void FormController::requestPhoneCall(not_null<Value*> value) {
 void FormController::valueSaveShowError(
 		not_null<Value*> value,
 		const MTP::Error &error) {
-	_view->show(Box<Ui::InformBox>(
+	_view->show(Ui::MakeInformBox(
 		Lang::Hard::SecureSaveError() + "\n" + error.type()));
 	valueSaveFailed(value);
 }
@@ -2320,11 +2319,12 @@ void FormController::saveSecret(
 
 void FormController::suggestRestart() {
 	_suggestingRestart = true;
-	_view->show(Box<Ui::ConfirmBox>(
-		tr::lng_passport_restart_sure(tr::now),
-		tr::lng_passport_restart(tr::now),
-		[=] { _controller->showPassportForm(_request); },
-		[=] { cancel(); }));
+	_view->show(Ui::MakeConfirmBox({
+		.text = tr::lng_passport_restart_sure(),
+		.confirmed = [=] { _controller->showPassportForm(_request); },
+		.cancelled = [=] { cancel(); },
+		.confirmText = tr::lng_passport_restart(),
+	}));
 }
 
 void FormController::requestForm() {
@@ -2684,11 +2684,12 @@ bool FormController::applyPassword(PasswordSettings &&settings) {
 
 void FormController::cancel() {
 	if (!_submitSuccess && _serviceErrorText.isEmpty()) {
-		_view->show(Box<Ui::ConfirmBox>(
-			tr::lng_passport_stop_sure(tr::now),
-			tr::lng_passport_stop(tr::now),
-			[=] { cancelSure(); },
-			[=] { cancelAbort(); }));
+		_view->show(Ui::MakeConfirmBox({
+			.text = tr::lng_passport_stop_sure(),
+			.confirmed = [=] { cancelSure(); },
+			.cancelled = [=] { cancelAbort(); },
+			.confirmText = tr::lng_passport_stop(),
+		}));
 	} else {
 		cancelSure();
 	}
diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.cpp b/Telegram/SourceFiles/passport/passport_panel_controller.cpp
index 5dc252951..4bdbf4498 100644
--- a/Telegram/SourceFiles/passport/passport_panel_controller.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel_controller.cpp
@@ -710,10 +710,14 @@ void PanelController::setupPassword() {
 }
 
 void PanelController::cancelPasswordSubmit() {
-	show(Box<Ui::ConfirmBox>(
-		tr::lng_passport_stop_password_sure(tr::now),
-		tr::lng_passport_stop(tr::now),
-		[=](Fn<void()> &&close) { close(); _form->cancelPassword(); }));
+	show(Ui::MakeConfirmBox({
+		.text = tr::lng_passport_stop_password_sure(),
+		.confirmed = [=](Fn<void()> &&close) {
+			close();
+			_form->cancelPassword();
+		},
+		.confirmText = tr::lng_passport_stop(),
+	}));
 }
 
 void PanelController::validateRecoveryEmail() {
@@ -887,20 +891,22 @@ void PanelController::deleteValueSure(bool withDetails) {
 }
 
 void PanelController::suggestReset(Fn<void()> callback) {
-	_resetBox = Ui::BoxPointer(show(Box<Ui::ConfirmBox>(
-		Lang::Hard::PassportCorrupted(),
-		Lang::Hard::PassportCorruptedReset(),
-		[=] { resetPassport(callback); },
-		[=] { cancelReset(); })).data());
+	_resetBox = Ui::BoxPointer(show(Ui::MakeConfirmBox({
+		.text = Lang::Hard::PassportCorrupted(),
+		.confirmed = [=] { resetPassport(callback); },
+		.cancelled = [=] { cancelReset(); },
+		.confirmText = Lang::Hard::PassportCorruptedReset(),
+	})).data());
 }
 
 void PanelController::resetPassport(Fn<void()> callback) {
-	const auto box = show(Box<Ui::ConfirmBox>(
-		Lang::Hard::PassportCorruptedResetSure(),
-		Lang::Hard::PassportCorruptedReset(),
-		st::attentionBoxButton,
-		[=] { base::take(_resetBox); callback(); },
-		[=] { suggestReset(callback); }));
+	const auto box = show(Ui::MakeConfirmBox({
+		.text = Lang::Hard::PassportCorruptedResetSure(),
+		.confirmed = [=] { base::take(_resetBox); callback(); },
+		.cancelled = [=] { suggestReset(callback); },
+		.confirmText = Lang::Hard::PassportCorruptedReset(),
+		.confirmStyle = &st::attentionBoxButton,
+	}));
 	_resetBox = Ui::BoxPointer(box.data());
 }
 
@@ -942,11 +948,12 @@ void PanelController::showUpdateAppBox() {
 		Core::UpdateApplication();
 	};
 	show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_passport_app_out_of_date(tr::now),
-			tr::lng_menu_update(tr::now),
-			callback,
-			[=] { _form->cancelSure(); }),
+		Ui::MakeConfirmBox({
+			.text = tr::lng_passport_app_out_of_date(),
+			.confirmed = callback,
+			.cancelled = [=] { _form->cancelSure(); },
+			.confirmText = tr::lng_menu_update(),
+		}),
 		Ui::LayerOption::KeepOther,
 		anim::type::instant);
 }
@@ -1076,16 +1083,16 @@ void PanelController::editWithUpload(int index, int documentIndex) {
 }
 
 void PanelController::readScanError(ReadScanError error) {
-	show(Box<Ui::InformBox>([&] {
+	show(Ui::MakeInformBox([&] {
 		switch (error) {
 		case ReadScanError::FileTooLarge:
-			return tr::lng_passport_error_too_large(tr::now);
+			return tr::lng_passport_error_too_large();
 		case ReadScanError::BadImageSize:
-			return tr::lng_passport_error_bad_size(tr::now);
+			return tr::lng_passport_error_bad_size();
 		case ReadScanError::CantReadImage:
-			return tr::lng_passport_error_cant_read(tr::now);
+			return tr::lng_passport_error_cant_read();
 		case ReadScanError::Unknown:
-			return Lang::Hard::UnknownSecureScanError();
+			return rpl::single(Lang::Hard::UnknownSecureScanError());
 		}
 		Unexpected("Error type in PanelController::readScanError.");
 	}()));
@@ -1402,10 +1409,11 @@ void PanelController::cancelEditScope() {
 
 	if (_panelHasUnsavedChanges && _panelHasUnsavedChanges()) {
 		if (!_confirmForgetChangesBox) {
-			_confirmForgetChangesBox = show(Box<Ui::ConfirmBox>(
-				tr::lng_passport_sure_cancel(tr::now),
-				tr::lng_continue(tr::now),
-				[=] { _panel->showForm(); }));
+			_confirmForgetChangesBox = show(Ui::MakeConfirmBox({
+				.text = tr::lng_passport_sure_cancel(),
+				.confirmed = [=] { _panel->showForm(); },
+				.confirmText = tr::lng_continue(),
+			}));
 			_editScopeBoxes.emplace_back(_confirmForgetChangesBox);
 		}
 	} else {
diff --git a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm
index 899b549c6..6e2c64079 100644
--- a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm
+++ b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm
@@ -460,7 +460,7 @@ void AppendEmojiPacks(
 	auto callback = [=] {
 		if (document) {
 			if (const auto error = RestrictionToSendStickers(_controller)) {
-				_controller->show(Box<Ui::InformBox>(*error));
+				_controller->show(Ui::MakeInformBox(*error));
 				return true;
 			}
 			Api::SendExistingDocument(
diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp
index 492542d32..8c3486682 100644
--- a/Telegram/SourceFiles/platform/win/specific_win.cpp
+++ b/Telegram/SourceFiles/platform/win/specific_win.cpp
@@ -400,10 +400,14 @@ void AutostartToggle(bool enabled, Fn<void(bool)> done) {
 		if (!requested || enabled) {
 			return;
 		} else if (const auto window = Core::App().activeWindow()) {
-			window->show(Box<Ui::ConfirmBox>(
-				tr::lng_settings_auto_start_disabled_uwp(tr::now),
-				tr::lng_settings_open_system_settings(tr::now),
-				[] { AutostartTask::OpenSettings(); Ui::hideLayer(); }));
+			window->show(Ui::MakeConfirmBox({
+				.text = tr::lng_settings_auto_start_disabled_uwp(),
+				.confirmed = [] {
+					AutostartTask::OpenSettings();
+					Ui::hideLayer();
+				},
+				.confirmText = tr::lng_settings_open_system_settings(),
+			}));
 		}
 	}); };
 	AutostartTask::Toggle(
diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp
index 707143fd2..3614c8f7a 100644
--- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp
+++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp
@@ -99,10 +99,11 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
 				currentRestrictedRights);
 		}
 	};
-	Ui::show(Box<Ui::ConfirmBox>(
-		text,
-		tr::lng_box_remove(tr::now),
-		crl::guard(&peer->session(), callback)));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = text,
+		.confirmed = crl::guard(&peer->session(), callback),
+		.confirmText = tr::lng_box_remove(),
+	}));
 }
 
 void GroupMembersWidget::notifyPeerUpdated(const Data::PeerUpdate &update) {
diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp
index 04c7eebe0..d7cf10f6a 100644
--- a/Telegram/SourceFiles/settings/settings_advanced.cpp
+++ b/Telegram/SourceFiles/settings/settings_advanced.cpp
@@ -521,8 +521,8 @@ void SetupSystemIntegrationContent(
 		}) | rpl::start_with_next([=](bool checked) {
 			if (controller->session().domain().local().hasLocalPasscode()) {
 				minimized->entity()->setChecked(false);
-				controller->show(Box<Ui::InformBox>(
-					tr::lng_error_start_minimized_passcoded(tr::now)));
+				controller->show(Ui::MakeInformBox(
+					tr::lng_error_start_minimized_passcoded()));
 			} else {
 				cSetStartMinimized(checked);
 				Local::writeSettings();
@@ -638,10 +638,11 @@ void SetupANGLE(
 					}
 					Core::Restart();
 				});
-				controller->show(Box<Ui::ConfirmBox>(
-					tr::lng_settings_need_restart(tr::now),
-					tr::lng_settings_restart_now(tr::now),
-					confirmed));
+				controller->show(Ui::MakeConfirmBox({
+					.text = tr::lng_settings_need_restart(),
+					.confirmed = confirmed,
+					.confirmText = tr::lng_settings_restart_now(),
+				}));
 			};
 			SingleChoiceBox(box, {
 				.title = tr::lng_settings_angle_backend(),
@@ -680,11 +681,12 @@ void SetupOpenGL(
 		const auto cancelled = crl::guard(button, [=] {
 			toggles->fire(!enabled);
 		});
-		controller->show(Box<Ui::ConfirmBox>(
-			tr::lng_settings_need_restart(tr::now),
-			tr::lng_settings_restart_now(tr::now),
-			confirmed,
-			cancelled));
+		controller->show(Ui::MakeConfirmBox({
+			.text = tr::lng_settings_need_restart(),
+			.confirmed = confirmed,
+			.cancelled = cancelled,
+			.confirmText = tr::lng_settings_restart_now(),
+		}));
 	}, container->lifetime());
 }
 
diff --git a/Telegram/SourceFiles/settings/settings_calls.cpp b/Telegram/SourceFiles/settings/settings_calls.cpp
index fcd351d01..254f50e09 100644
--- a/Telegram/SourceFiles/settings/settings_calls.cpp
+++ b/Telegram/SourceFiles/settings/settings_calls.cpp
@@ -293,7 +293,7 @@ void Calls::setupContent() {
 			Platform::SystemSettingsType::Audio);
 		if (!opened) {
 			_controller->show(
-				Box<Ui::InformBox>(tr::lng_linux_no_audio_prefs(tr::now)));
+				Ui::MakeInformBox(tr::lng_linux_no_audio_prefs()));
 		}
 	});
 
@@ -325,10 +325,11 @@ void Calls::requestPermissionAndStartTestingMicrophone() {
 				Platform::PermissionType::Microphone);
 			Ui::hideLayer();
 		};
-		_controller->show(Box<Ui::ConfirmBox>(
-			tr::lng_no_mic_permission(tr::now),
-			tr::lng_menu_settings(tr::now),
-			showSystemSettings));
+		_controller->show(Ui::MakeConfirmBox({
+			.text = tr::lng_no_mic_permission(),
+			.confirmed = showSystemSettings,
+			.confirmText = tr::lng_menu_settings(),
+		}));
 	}
 }
 
diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp
index 20afe6ace..24d4a498e 100644
--- a/Telegram/SourceFiles/settings/settings_chat.cpp
+++ b/Telegram/SourceFiles/settings/settings_chat.cpp
@@ -1208,8 +1208,8 @@ void SetupDefaultThemes(
 			// in Window::Theme::Revert which is called by Editor.
 			//
 			// So we check here, before we change the saved accent color.
-			window->show(Box<Ui::InformBox>(
-				tr::lng_theme_editor_cant_change_theme(tr::now)));
+			window->show(Ui::MakeInformBox(
+				tr::lng_theme_editor_cant_change_theme()));
 			return;
 		}
 		const auto type = chosen();
@@ -1361,8 +1361,8 @@ void SetupAutoNightMode(
 	}) | rpl::start_with_next([=](bool checked) {
 		if (checked && Window::Theme::Background()->editingTheme()) {
 			autoNight->setChecked(false);
-			controller->show(Box<Ui::InformBox>(
-				tr::lng_theme_editor_cant_change_theme(tr::now)));
+			controller->show(Ui::MakeInformBox(
+				tr::lng_theme_editor_cant_change_theme()));
 		} else {
 			Core::App().settings().setSystemDarkModeEnabled(checked);
 			Core::App().saveSettingsDelayed();
diff --git a/Telegram/SourceFiles/settings/settings_codes.cpp b/Telegram/SourceFiles/settings/settings_codes.cpp
index 464c82bf8..ebef15287 100644
--- a/Telegram/SourceFiles/settings/settings_codes.cpp
+++ b/Telegram/SourceFiles/settings/settings_codes.cpp
@@ -78,9 +78,9 @@ auto GenerateCodes() {
 			? qsl("Do you want to disable DEBUG logs?")
 			: qsl("Do you want to enable DEBUG logs?\n\n"
 				"All network events will be logged.");
-		Ui::show(Box<Ui::ConfirmBox>(text, [] {
+		Ui::show(Ui::MakeConfirmBox({ text, [] {
 			Core::App().switchDebugMode();
-		}));
+		} }));
 	});
 	codes.emplace(qsl("viewlogs"), [](SessionController *window) {
 		File::ShowInFolder(cWorkingDir() + "log.txt");
@@ -98,11 +98,11 @@ auto GenerateCodes() {
 	});
 	codes.emplace(qsl("moderate"), [](SessionController *window) {
 		auto text = Core::App().settings().moderateModeEnabled() ? qsl("Disable moderate mode?") : qsl("Enable moderate mode?");
-		Ui::show(Box<Ui::ConfirmBox>(text, [=] {
+		Ui::show(Ui::MakeConfirmBox({ text, [=] {
 			Core::App().settings().setModerateModeEnabled(!Core::App().settings().moderateModeEnabled());
 			Core::App().saveSettingsDelayed();
 			Ui::hideLayer();
-		}));
+		} }));
 	});
 	codes.emplace(qsl("getdifference"), [](SessionController *window) {
 		if (window) {
@@ -121,11 +121,11 @@ auto GenerateCodes() {
 			return;
 		}
 		auto text = cUseExternalVideoPlayer() ? qsl("Use internal video player?") : qsl("Use external video player?");
-		Ui::show(Box<Ui::ConfirmBox>(text, [=] {
+		Ui::show(Ui::MakeConfirmBox({ text, [=] {
 			cSetUseExternalVideoPlayer(!cUseExternalVideoPlayer());
 			window->session().saveSettingsDelayed();
 			Ui::hideLayer();
-		}));
+		} }));
 	});
 	codes.emplace(qsl("endpoints"), [](SessionController *window) {
 		if (!Core::App().domain().started()) {
@@ -138,7 +138,7 @@ auto GenerateCodes() {
 			if (!result.paths.isEmpty()) {
 				const auto loadFor = [&](not_null<Main::Account*> account) {
 					if (!account->mtp().dcOptions().loadFromFile(result.paths.front())) {
-						Ui::show(Box<Ui::InformBox>("Could not load endpoints"
+						Ui::show(Ui::MakeInformBox("Could not load endpoints"
 							" :( Errors in 'log.txt'."));
 					}
 				};
@@ -188,9 +188,9 @@ auto GenerateCodes() {
 #endif // !Q_OS_WIN
 			: qsl("Switch font engine to FreeType?");
 
-		Ui::show(Box<Ui::ConfirmBox>(text, [] {
+		Ui::show(Ui::MakeConfirmBox({ text, [] {
 			Core::App().switchFreeType();
-		}));
+		} }));
 	});
 #endif // Q_OS_WIN || Q_OS_MAC
 
@@ -217,7 +217,7 @@ auto GenerateCodes() {
 					auto track = Media::Audio::Current().createTrack();
 					track->fillFromFile(result.paths.front());
 					if (track->failed()) {
-						Ui::show(Box<Ui::InformBox>(
+						Ui::show(Ui::MakeInformBox(
 							"Could not audio :( Errors in 'log.txt'."));
 					} else {
 						Core::App().settings().setSoundOverride(
@@ -232,7 +232,7 @@ auto GenerateCodes() {
 	codes.emplace(qsl("sounds_reset"), [](SessionController *window) {
 		Core::App().settings().clearSoundOverrides();
 		Core::App().saveSettingsDelayed();
-		Ui::show(Box<Ui::InformBox>("All sound overrides were reset."));
+		Ui::show(Ui::MakeInformBox("All sound overrides were reset."));
 	});
 	codes.emplace(qsl("unpacklog"), [](SessionController *window) {
 		FileDialog::GetOpenPath(Core::App().getFileDialogParent(), "Open crash log file", "Crash dump (*.txt)", [=](const FileDialog::OpenResult &result) {
diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp
index f2019f755..737f5f6e6 100644
--- a/Telegram/SourceFiles/settings/settings_experimental.cpp
+++ b/Telegram/SourceFiles/settings/settings_experimental.cpp
@@ -53,11 +53,12 @@ void AddOption(
 		: nullptr;
 	if (restarter) {
 		restarter->setCallback([=] {
-			window->show(Box<Ui::ConfirmBox>(
-				tr::lng_settings_need_restart(tr::now),
-				tr::lng_settings_restart_now(tr::now),
-				tr::lng_settings_restart_later(tr::now),
-				[] { Core::Restart(); }));
+			window->show(Ui::MakeConfirmBox({
+				.text = tr::lng_settings_need_restart(),
+				.confirmed = [] { Core::Restart(); },
+				.confirmText = tr::lng_settings_restart_now(),
+				.cancelText = tr::lng_settings_restart_later(),
+			}));
 		});
 	}
 	button->toggledChanges(
diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp
index e01dccc3a..c3127b266 100644
--- a/Telegram/SourceFiles/settings/settings_main.cpp
+++ b/Telegram/SourceFiles/settings/settings_main.cpp
@@ -400,11 +400,12 @@ void SetupInterfaceScale(
 					button,
 					[=] { repeatSetScale(cConfigScale(), repeatSetScale); });
 			});
-			window->show(Box<Ui::ConfirmBox>(
-				tr::lng_settings_need_restart(tr::now),
-				tr::lng_settings_restart_now(tr::now),
-				confirmed,
-				cancelled));
+			window->show(Ui::MakeConfirmBox({
+				.text = tr::lng_settings_need_restart(),
+				.confirmed = confirmed,
+				.cancelled = cancelled,
+				.confirmText = tr::lng_settings_restart_now(),
+			}));
 		} else if (scale != cConfigScale()) {
 			cSetConfigScale(scale);
 			Local::writeSettings();
@@ -505,13 +506,14 @@ void SetupHelp(
 				*requestId = 0;
 			}).send();
 		});
-		auto box = Box<Ui::ConfirmBox>(
-			tr::lng_settings_ask_sure(tr::now),
-			tr::lng_settings_ask_ok(tr::now),
-			tr::lng_settings_faq_button(tr::now),
-			sure,
-			OpenFaq);
-		box->setStrictCancel(true);
+		auto box = Ui::MakeConfirmBox({
+			.text = tr::lng_settings_ask_sure(),
+			.confirmed = sure,
+			.cancelled = OpenFaq,
+			.confirmText = tr::lng_settings_ask_ok(),
+			.cancelText = tr::lng_settings_faq_button(),
+			.strictCancel = true,
+		});
 		controller->show(std::move(box));
 	});
 }
diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp
index 20ef42914..7458dbe1a 100644
--- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp
+++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp
@@ -595,11 +595,11 @@ void LastSeenPrivacyController::confirmSave(
 			Core::App().settings().setLastSeenWarningSeen(true);
 			Core::App().saveSettingsDelayed();
 		};
-		auto box = Box<Ui::ConfirmBox>(
-			tr::lng_edit_privacy_lastseen_warning(tr::now),
-			tr::lng_continue(tr::now),
-			tr::lng_cancel(tr::now),
-			std::move(callback));
+		auto box = Ui::MakeConfirmBox({
+			.text = tr::lng_edit_privacy_lastseen_warning(),
+			.confirmed = std::move(callback),
+			.confirmText = tr::lng_continue(),
+		});
 		Ui::show(std::move(box), Ui::LayerOption::KeepOther);
 	} else {
 		saveCallback();
diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp
index 4404cc097..8ce6d70f9 100644
--- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp
+++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp
@@ -569,11 +569,12 @@ void SetupCloudPassword(
 					*sent = false;
 				}, container->lifetime());
 			};
-			Ui::show(Box<Ui::ConfirmBox>(
-				tr::lng_cloud_password_reset_cancel_sure(tr::now),
-				tr::lng_box_yes(tr::now),
-				tr::lng_box_no(tr::now),
-				cancel));
+			Ui::show(Ui::MakeConfirmBox({
+				.text = tr::lng_cloud_password_reset_cancel_sure(),
+				.confirmed = cancel,
+				.confirmText = tr::lng_box_yes(),
+				.cancelText = tr::lng_box_no(),
+			}));
 		}
 	});
 
@@ -931,10 +932,11 @@ object_ptr<Ui::BoxContent> CloudPasswordAppOutdatedBox() {
 		Core::UpdateApplication();
 		close();
 	};
-	return Box<Ui::ConfirmBox>(
-		tr::lng_passport_app_out_of_date(tr::now),
-		tr::lng_menu_update(tr::now),
-		callback);
+	return Ui::MakeConfirmBox({
+		.text = tr::lng_passport_app_out_of_date(),
+		.confirmed = callback,
+		.confirmText = tr::lng_menu_update(),
+	});
 }
 
 void AddPrivacyButton(
diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp
index dd63aeba8..7a369af71 100644
--- a/Telegram/SourceFiles/storage/localimageloader.cpp
+++ b/Telegram/SourceFiles/storage/localimageloader.cpp
@@ -994,13 +994,13 @@ void FileLoadTask::process(Args &&args) {
 void FileLoadTask::finish() {
 	if (!_result || !_result->filesize || _result->filesize < 0) {
 		Ui::show(
-			Box<Ui::InformBox>(
+			Ui::MakeInformBox(
 				tr::lng_send_image_empty(tr::now, lt_name, _filepath)),
 			Ui::LayerOption::KeepOther);
 		removeFromAlbum();
 	} else if (_result->filesize > kFileSizeLimit) {
 		Ui::show(
-			Box<Ui::InformBox>(
+			Ui::MakeInformBox(
 				tr::lng_send_image_too_large(tr::now, lt_name, _filepath)),
 			Ui::LayerOption::KeepOther);
 		removeFromAlbum();
diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp
index ca75be161..18738a871 100644
--- a/Telegram/SourceFiles/window/themes/window_theme.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme.cpp
@@ -1406,10 +1406,11 @@ void ToggleNightModeWithConfirmation(
 			toggle();
 			close();
 		};
-		window->show(Box<Ui::ConfirmBox>(
-			tr::lng_settings_auto_night_warning(tr::now),
-			tr::lng_settings_auto_night_disable(tr::now),
-			disableAndToggle));
+		window->show(Ui::MakeConfirmBox({
+			.text = tr::lng_settings_auto_night_warning(),
+			.confirmed = disableAndToggle,
+			.confirmText = tr::lng_settings_auto_night_disable(),
+		}));
 	}
 }
 
diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp
index a200022a1..e73c8bd3d 100644
--- a/Telegram/SourceFiles/window/themes/window_theme_editor.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme_editor.cpp
@@ -423,8 +423,8 @@ Editor::Inner::Inner(QWidget *parent, const QString &path)
 		if (update.type == BackgroundUpdate::Type::TestingTheme) {
 			Revert();
 			base::call_delayed(st::slideDuration, this, [] {
-				Ui::show(Box<Ui::InformBox>(
-					tr::lng_theme_editor_cant_change_theme(tr::now)));
+				Ui::show(Ui::MakeInformBox(
+					tr::lng_theme_editor_cant_change_theme()));
 			});
 		}
 	}, lifetime());
@@ -668,7 +668,7 @@ Editor::Editor(
 		[=] { save(); }));
 
 	_inner->setErrorCallback([=] {
-		window->show(Box<Ui::InformBox>(tr::lng_theme_editor_error(tr::now)));
+		window->show(Ui::MakeInformBox(tr::lng_theme_editor_error()));
 
 		// This could be from inner->_context observable notification.
 		// We should not destroy it while iterating in subscribers.
@@ -752,14 +752,12 @@ void Editor::exportTheme() {
 		QFile f(path);
 		if (!f.open(QIODevice::WriteOnly)) {
 			LOG(("Theme Error: could not open zip-ed theme file '%1' for writing").arg(path));
-			_window->show(
-				Box<Ui::InformBox>(tr::lng_theme_editor_error(tr::now)));
+			_window->show(Ui::MakeInformBox(tr::lng_theme_editor_error()));
 			return;
 		}
 		if (f.write(result) != result.size()) {
 			LOG(("Theme Error: could not write zip-ed theme to file '%1'").arg(path));
-			_window->show(
-				Box<Ui::InformBox>(tr::lng_theme_editor_error(tr::now)));
+			_window->show(Ui::MakeInformBox(tr::lng_theme_editor_error()));
 			return;
 		}
 		Ui::Toast::Show(tr::lng_theme_editor_done(tr::now));
@@ -906,10 +904,11 @@ void Editor::closeWithConfirmation() {
 		closeEditor();
 		close();
 	});
-	_window->show(Box<Ui::ConfirmBox>(
-		tr::lng_theme_editor_sure_close(tr::now),
-		tr::lng_close(tr::now),
-		close));
+	_window->show(Ui::MakeConfirmBox({
+		.text = tr::lng_theme_editor_sure_close(),
+		.confirmed = close,
+		.confirmText = tr::lng_close(),
+	}));
 }
 
 void Editor::closeEditor() {
diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
index 7488e16d6..afa73dac4 100644
--- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp
@@ -655,7 +655,7 @@ void StartEditor(
 		? GenerateDefaultPalette()
 		: ParseTheme(object, true).palette;
 	if (palette.isEmpty() || !CopyColorsToPalette(path, palette, cloud)) {
-		window->show(Box<Ui::InformBox>(tr::lng_theme_editor_error(tr::now)));
+		window->show(Ui::MakeInformBox(tr::lng_theme_editor_error()));
 		return;
 	}
 	if (Core::App().settings().systemDarkModeEnabled()) {
diff --git a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
index 1f0465fa1..1a1f2528d 100644
--- a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
+++ b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
@@ -622,10 +622,11 @@ void CloudList::showMenu(Element &element) {
 				_window->session().data().cloudThemes().remove(id);
 			}
 		};
-		_window->window().show(Box<Ui::ConfirmBox>(
-			tr::lng_theme_delete_sure(tr::now),
-			tr::lng_theme_delete(tr::now),
-			remove));
+		_window->window().show(Ui::MakeConfirmBox({
+			.text = tr::lng_theme_delete_sure(),
+			.confirmed = remove,
+			.confirmText = tr::lng_theme_delete(),
+		}));
 	}, &st::menuIconDelete);
 	_contextMenu->popup(QCursor::pos());
 }
diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp
index 591390bfb..f2d302c19 100644
--- a/Telegram/SourceFiles/window/window_controller.cpp
+++ b/Telegram/SourceFiles/window/window_controller.cpp
@@ -234,11 +234,12 @@ void Controller::showTermsDelete() {
 		}
 	};
 	show(
-		Box<Ui::ConfirmBox>(
-			tr::lng_terms_delete_warning(tr::now),
-			tr::lng_terms_delete_now(tr::now),
-			st::attentionBoxButton,
-			deleteByTerms),
+		Ui::MakeConfirmBox({
+			.text = tr::lng_terms_delete_warning(),
+			.confirmed = deleteByTerms,
+			.confirmText = tr::lng_terms_delete_now(),
+			.confirmStyle = &st::attentionBoxButton,
+		}),
 		Ui::LayerOption::KeepOther);
 }
 
@@ -403,11 +404,12 @@ void Controller::showLogoutConfirmation() {
 			close();
 		}
 	};
-	show(Box<Ui::ConfirmBox>(
-		tr::lng_sure_logout(tr::now),
-		tr::lng_settings_logout(tr::now),
-		st::attentionBoxButton,
-		callback));
+	show(Ui::MakeConfirmBox({
+		.text = tr::lng_sure_logout(),
+		.confirmed = callback,
+		.confirmText = tr::lng_settings_logout(),
+		.confirmStyle = &st::attentionBoxButton,
+	}));
 }
 
 Window::Adaptive &Controller::adaptive() const {
diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp
index 044268dfc..456c9ca12 100644
--- a/Telegram/SourceFiles/window/window_filters_menu.cpp
+++ b/Telegram/SourceFiles/window/window_filters_menu.cpp
@@ -345,10 +345,11 @@ void FiltersMenu::showEditBox(FilterId id) {
 }
 
 void FiltersMenu::showRemoveBox(FilterId id) {
-	_session->window().show(Box<Ui::ConfirmBox>(
-		tr::lng_filters_remove_sure(tr::now),
-		tr::lng_filters_remove_yes(tr::now),
-		[=](Fn<void()> &&close) { close(); remove(id); }));
+	_session->window().show(Ui::MakeConfirmBox({
+		.text = tr::lng_filters_remove_sure(),
+		.confirmed = [=](Fn<void()> &&close) { close(); remove(id); },
+		.confirmText = tr::lng_filters_remove_yes(),
+	}));
 }
 
 void FiltersMenu::remove(FilterId id) {
diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp
index ef6ccfdc8..fd1a033b6 100644
--- a/Telegram/SourceFiles/window/window_main_menu.cpp
+++ b/Telegram/SourceFiles/window/window_main_menu.cpp
@@ -323,11 +323,12 @@ void AddUnreadBadge(
 				close();
 				Core::App().logoutWithChecks(&session->account());
 			};
-			Ui::show(Box<Ui::ConfirmBox>(
-				tr::lng_sure_logout(tr::now),
-				tr::lng_settings_logout(tr::now),
-				st::attentionBoxButton,
-				crl::guard(session, callback)));
+			Ui::show(Ui::MakeConfirmBox({
+				.text = tr::lng_sure_logout(),
+				.confirmed = crl::guard(session, callback),
+				.confirmText = tr::lng_settings_logout(),
+				.confirmStyle = &st::attentionBoxButton,
+			}));
 		}, &st::menuIconLeave);
 		state->menu->popup(QCursor::pos());
 	}, raw->lifetime());
@@ -1034,8 +1035,8 @@ void MainMenu::setupMenu() {
 	}) | rpl::start_with_next([=](bool night) {
 		if (Window::Theme::Background()->editingTheme()) {
 			_nightThemeSwitches.fire(!night);
-			controller->show(Box<Ui::InformBox>(
-				tr::lng_theme_editor_cant_change_theme(tr::now)));
+			controller->show(Ui::MakeInformBox(
+				tr::lng_theme_editor_cant_change_theme()));
 			return;
 		}
 		const auto weak = MakeWeak(this);
diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp
index db87319d9..104dc7ecc 100644
--- a/Telegram/SourceFiles/window/window_peer_menu.cpp
+++ b/Telegram/SourceFiles/window/window_peer_menu.cpp
@@ -219,7 +219,7 @@ bool PinnedLimitReached(Dialogs::Key key, FilterId filterId) {
 				tr::now,
 				lt_count,
 				pinnedMax);
-		Ui::show(Box<Ui::InformBox>(errorText));
+		Ui::show(Ui::MakeInformBox(errorText));
 	}
 	return true;
 }
@@ -855,10 +855,11 @@ void PeerMenuDeleteContact(not_null<UserData*> user) {
 			user->session().api().applyUpdates(result);
 		}).send();
 	};
-	Ui::show(Box<Ui::ConfirmBox>(
-		text,
-		tr::lng_box_delete(tr::now),
-		deleteSure));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = text,
+		.confirmed = deleteSure,
+		.confirmText = tr::lng_box_delete(),
+	}));
 }
 
 void PeerMenuShareContactBox(
@@ -867,8 +868,8 @@ void PeerMenuShareContactBox(
 	const auto weak = std::make_shared<QPointer<PeerListBox>>();
 	auto callback = [=](not_null<PeerData*> peer) {
 		if (!peer->canWrite()) {
-			Ui::show(Box<Ui::InformBox>(
-				tr::lng_forward_share_cant(tr::now)),
+			Ui::show(
+				Ui::MakeInformBox(tr::lng_forward_share_cant()),
 				Ui::LayerOption::KeepOther);
 			return;
 		} else if (peer->isSelf()) {
@@ -884,19 +885,25 @@ void PeerMenuShareContactBox(
 		auto recipient = peer->isUser()
 			? peer->name
 			: '\xAB' + peer->name + '\xBB';
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_forward_share_contact(tr::now, lt_recipient, recipient),
-			tr::lng_forward_send(tr::now),
-			[peer, user, navigation] {
-				const auto history = peer->owner().history(peer);
-				navigation->showPeerHistory(
-					history,
-					Window::SectionShow::Way::ClearStack,
-					ShowAtTheEndMsgId);
-				auto action = Api::SendAction(history);
-				action.clearDraft = false;
-				user->session().api().shareContact(user, action);
-			}), Ui::LayerOption::KeepOther);
+		Ui::show(
+			Ui::MakeConfirmBox({
+				.text = tr::lng_forward_share_contact(
+					tr::now,
+					lt_recipient,
+					recipient),
+				.confirmed = [peer, user, navigation] {
+					const auto history = peer->owner().history(peer);
+					navigation->showPeerHistory(
+						history,
+						Window::SectionShow::Way::ClearStack,
+						ShowAtTheEndMsgId);
+					auto action = Api::SendAction(history);
+					action.clearDraft = false;
+					user->session().api().shareContact(user, action);
+				},
+				.confirmText = tr::lng_forward_send(),
+			}),
+			Ui::LayerOption::KeepOther);
 	};
 	*weak = Ui::show(Box<PeerListBox>(
 		std::make_unique<ChooseRecipientBoxController>(
@@ -1186,7 +1193,11 @@ QPointer<Ui::BoxContent> ShowSendNowMessagesBox(
 		}
 	};
 	return Ui::show(
-		Box<Ui::ConfirmBox>(text, tr::lng_send_button(tr::now), std::move(done)),
+		Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = std::move(done),
+			.confirmText = tr::lng_send_button(),
+		}),
 		Ui::LayerOption::KeepOther).data();
 }
 
@@ -1247,10 +1258,11 @@ void ToggleMessagePinned(
 				session->api().applyUpdates(result);
 			}).send();
 		});
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_pinned_unpin_sure(tr::now),
-			tr::lng_pinned_unpin(tr::now),
-			callback));
+		Ui::show(Ui::MakeConfirmBox({
+			.text = tr::lng_pinned_unpin_sure(),
+			.confirmed = callback,
+			.confirmText = tr::lng_pinned_unpin(),
+		}));
 	}
 }
 
@@ -1278,10 +1290,11 @@ void HidePinnedBar(
 			session.api().requestFullPeer(peer);
 		}
 	});
-	Ui::show(Box<Ui::ConfirmBox>(
-		tr::lng_pinned_hide_all_sure(tr::now),
-		tr::lng_pinned_hide_all_hide(tr::now),
-		callback));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = tr::lng_pinned_hide_all_sure(),
+		.confirmed = callback,
+		.confirmText = tr::lng_pinned_hide_all_hide(),
+	}));
 }
 
 void UnpinAllMessages(
@@ -1305,10 +1318,11 @@ void UnpinAllMessages(
 		};
 		sendRequest(sendRequest);
 	});
-	Ui::show(Box<Ui::ConfirmBox>(
-		tr::lng_pinned_unpin_all_sure(tr::now),
-		tr::lng_pinned_unpin(tr::now),
-		callback));
+	Ui::show(Ui::MakeConfirmBox({
+		.text = tr::lng_pinned_unpin_all_sure(),
+		.confirmed = callback,
+		.confirmText = tr::lng_pinned_unpin(),
+	}));
 }
 
 void PeerMenuAddMuteAction(
@@ -1348,9 +1362,10 @@ void MenuAddMarkAsReadAllChatsAction(
 				MarkAsReadChatList(folder->chatsList());
 			}
 		};
-		Ui::show(Box<Ui::ConfirmBox>(
-			tr::lng_context_mark_read_all_sure(tr::now),
-			std::move(boxCallback)));
+		Ui::show(Ui::MakeConfirmBox({
+			tr::lng_context_mark_read_all_sure(),
+			std::move(boxCallback)
+		}));
 	};
 	addAction(
 		tr::lng_context_mark_read_all(tr::now),
@@ -1372,9 +1387,10 @@ void MenuAddMarkAsReadChatListAction(
 				MarkAsReadChatList(list());
 				close();
 			};
-			Ui::show(Box<Ui::ConfirmBox>(
-				tr::lng_context_mark_read_sure(tr::now),
-				std::move(boxCallback)));
+			Ui::show(Ui::MakeConfirmBox({
+				tr::lng_context_mark_read_sure(),
+				std::move(boxCallback)
+			}));
 		} else {
 			MarkAsReadChatList(list());
 		}
diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp
index f8502c9ed..0c5f88d02 100644
--- a/Telegram/SourceFiles/window/window_session_controller.cpp
+++ b/Telegram/SourceFiles/window/window_session_controller.cpp
@@ -212,7 +212,7 @@ void SessionNavigation::resolveUsername(
 	}).fail([=](const MTP::Error &error) {
 		_resolveRequestId = 0;
 		if (error.code() == 400) {
-			show(Box<Ui::InformBox>(
+			show(Ui::MakeInformBox(
 				tr::lng_username_not_found(tr::now, lt_user, username)));
 		}
 	}).send();
@@ -1127,12 +1127,14 @@ void SessionController::startOrJoinGroupCall(
 	using JoinConfirm = Calls::StartGroupCallArgs::JoinConfirm;
 	auto &calls = Core::App().calls();
 	const auto askConfirmation = [&](QString text, QString button) {
-		show(Box<Ui::ConfirmBox>(text, button, crl::guard(this, [=] {
-			Ui::hideLayer();
-			startOrJoinGroupCall(
-				peer,
-				{ args.joinHash, JoinConfirm::None });
-		})));
+		show(Ui::MakeConfirmBox({
+			.text = text,
+			.confirmed = crl::guard(this, [=, hash = args.joinHash] {
+				Ui::hideLayer();
+				startOrJoinGroupCall(peer, { hash, JoinConfirm::None });
+			}),
+			.confirmText = button,
+		}));
 	};
 	if (args.confirm != JoinConfirm::None && calls.inCall()) {
 		// Do you want to leave your active voice chat
@@ -1375,12 +1377,13 @@ void SessionController::cancelUploadLayer(not_null<HistoryItem*> item) {
 		session().uploader().unpause();
 	};
 
-	show(Box<Ui::ConfirmBox>(
-		tr::lng_selected_cancel_sure_this(tr::now),
-		tr::lng_selected_upload_stop(tr::now),
-		tr::lng_continue(tr::now),
-		stopUpload,
-		continueUpload));
+	show(Ui::MakeConfirmBox({
+		.text = tr::lng_selected_cancel_sure_this(),
+		.confirmed = stopUpload,
+		.cancelled = continueUpload,
+		.confirmText = tr::lng_selected_upload_stop(),
+		.cancelText = tr::lng_continue(),
+	}));
 }
 
 void SessionController::showSection(