| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | /*
 | 
					
						
							|  |  |  | This file is part of Telegram Desktop, | 
					
						
							|  |  |  | the official desktop application for the Telegram messaging service. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For license and copyright information please follow this link: | 
					
						
							|  |  |  | https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #include "ui/boxes/edit_invite_link.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "lang/lang_keys.h"
 | 
					
						
							|  |  |  | #include "ui/boxes/choose_date_time.h"
 | 
					
						
							|  |  |  | #include "ui/widgets/labels.h"
 | 
					
						
							| 
									
										
										
										
											2023-08-31 14:21:24 +03:00
										 |  |  | #include "ui/widgets/fields/input_field.h"
 | 
					
						
							|  |  |  | #include "ui/widgets/fields/number_input.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | #include "ui/widgets/checkbox.h"
 | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | #include "ui/wrap/slide_wrap.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | #include "base/unixtime.h"
 | 
					
						
							|  |  |  | #include "styles/style_settings.h"
 | 
					
						
							|  |  |  | #include "styles/style_layers.h"
 | 
					
						
							|  |  |  | #include "styles/style_info.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Ui { | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | constexpr auto kMaxLimit = std::numeric_limits<int>::max(); | 
					
						
							|  |  |  | constexpr auto kHour = 3600; | 
					
						
							|  |  |  | constexpr auto kDay = 86400; | 
					
						
							| 
									
										
										
										
											2021-10-28 16:18:49 +04:00
										 |  |  | constexpr auto kMaxLabelLength = 32; | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[nodiscard]] QString FormatExpireDate(TimeId date) { | 
					
						
							|  |  |  | 	if (date > 0) { | 
					
						
							|  |  |  | 		return langDateTime(base::unixtime::parse(date)); | 
					
						
							|  |  |  | 	} else if (-date < kDay) { | 
					
						
							| 
									
										
										
										
											2022-03-31 19:45:11 +03:00
										 |  |  | 		return tr::lng_hours(tr::now, lt_count, (-date / kHour)); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	} else if (-date < 7 * kDay) { | 
					
						
							| 
									
										
										
										
											2022-03-31 19:45:11 +03:00
										 |  |  | 		return tr::lng_days(tr::now, lt_count, (-date / kDay)); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2022-03-31 19:45:11 +03:00
										 |  |  | 		return tr::lng_weeks(tr::now, lt_count, (-date / (7 * kDay))); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditInviteLinkBox( | 
					
						
							|  |  |  | 		not_null<GenericBox*> box, | 
					
						
							|  |  |  | 		const InviteLinkFields &data, | 
					
						
							|  |  |  | 		Fn<void(InviteLinkFields)> done) { | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	using namespace rpl::mappers; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	const auto link = data.link; | 
					
						
							| 
									
										
										
										
											2021-10-12 12:39:07 +04:00
										 |  |  | 	const auto isGroup = data.isGroup; | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 	const auto isPublic = data.isPublic; | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	box->setTitle(link.isEmpty() | 
					
						
							|  |  |  | 		? tr::lng_group_invite_new_title() | 
					
						
							|  |  |  | 		: tr::lng_group_invite_edit_title()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const auto container = box->verticalLayout(); | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	const auto addTitle = [&]( | 
					
						
							|  |  |  | 			not_null<VerticalLayout*> container, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 			rpl::producer<QString> text) { | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 		container->add( | 
					
						
							|  |  |  | 			object_ptr<FlatLabel>( | 
					
						
							|  |  |  | 				container, | 
					
						
							|  |  |  | 				std::move(text), | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 				st::defaultSubsectionTitle), | 
					
						
							|  |  |  | 			(st::defaultSubsectionTitlePadding | 
					
						
							|  |  |  | 				+ style::margins(0, st::defaultVerticalListSkip, 0, 0))); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 	const auto addDivider = [&]( | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 			not_null<VerticalLayout*> container, | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 			rpl::producer<QString> text, | 
					
						
							|  |  |  | 			style::margins margins = style::margins()) { | 
					
						
							|  |  |  | 		container->add( | 
					
						
							|  |  |  | 			object_ptr<DividerLabel>( | 
					
						
							|  |  |  | 				container, | 
					
						
							|  |  |  | 				object_ptr<FlatLabel>( | 
					
						
							|  |  |  | 					container, | 
					
						
							|  |  |  | 					std::move(text), | 
					
						
							|  |  |  | 					st::boxDividerLabel), | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 				st::defaultBoxDividerLabelPadding), | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 			margins); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-02 10:22:12 +04:00
										 |  |  | 	const auto now = base::unixtime::now(); | 
					
						
							|  |  |  | 	const auto expire = data.expireDate ? data.expireDate : kMaxLimit; | 
					
						
							|  |  |  | 	const auto expireGroup = std::make_shared<RadiobuttonGroup>(expire); | 
					
						
							|  |  |  | 	const auto usage = data.usageLimit ? data.usageLimit : kMaxLimit; | 
					
						
							|  |  |  | 	const auto usageGroup = std::make_shared<RadiobuttonGroup>(usage); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	using Buttons = base::flat_map<int, base::unique_qptr<Radiobutton>>; | 
					
						
							|  |  |  | 	struct State { | 
					
						
							|  |  |  | 		Buttons expireButtons; | 
					
						
							|  |  |  | 		Buttons usageButtons; | 
					
						
							|  |  |  | 		int expireValue = 0; | 
					
						
							|  |  |  | 		int usageValue = 0; | 
					
						
							|  |  |  | 		rpl::variable<bool> requestApproval = false; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	const auto state = box->lifetime().make_state<State>(State{ | 
					
						
							|  |  |  | 		.expireValue = expire, | 
					
						
							|  |  |  | 		.usageValue = usage, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 		.requestApproval = (data.requestApproval && !isPublic), | 
					
						
							| 
									
										
										
										
											2021-11-02 10:22:12 +04:00
										 |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 	const auto requestApproval = isPublic | 
					
						
							|  |  |  | 		? nullptr | 
					
						
							|  |  |  | 		: container->add( | 
					
						
							|  |  |  | 			object_ptr<SettingsButton>( | 
					
						
							|  |  |  | 				container, | 
					
						
							|  |  |  | 				tr::lng_group_invite_request_approve(), | 
					
						
							| 
									
										
										
										
											2022-02-13 16:30:43 +03:00
										 |  |  | 				st::settingsButtonNoIcon), | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 			style::margins{ 0, 0, 0, st::defaultVerticalListSkip }); | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 	if (requestApproval) { | 
					
						
							|  |  |  | 		requestApproval->toggleOn(state->requestApproval.value()); | 
					
						
							|  |  |  | 		state->requestApproval = requestApproval->toggledValue(); | 
					
						
							|  |  |  | 		addDivider(container, rpl::conditional( | 
					
						
							|  |  |  | 			state->requestApproval.value(), | 
					
						
							|  |  |  | 			(isGroup | 
					
						
							|  |  |  | 				? tr::lng_group_invite_about_approve() | 
					
						
							|  |  |  | 				: tr::lng_group_invite_about_approve_channel()), | 
					
						
							|  |  |  | 			(isGroup | 
					
						
							|  |  |  | 				? tr::lng_group_invite_about_no_approve() | 
					
						
							|  |  |  | 				: tr::lng_group_invite_about_no_approve_channel()))); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const auto labelField = container->add( | 
					
						
							|  |  |  | 		object_ptr<Ui::InputField>( | 
					
						
							| 
									
										
										
										
											2021-11-02 10:22:12 +04:00
										 |  |  | 			container, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 			st::defaultInputField, | 
					
						
							|  |  |  | 			tr::lng_group_invite_label_header(), | 
					
						
							|  |  |  | 			data.label), | 
					
						
							|  |  |  | 		style::margins( | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 			st::defaultSubsectionTitlePadding.left(), | 
					
						
							|  |  |  | 			st::defaultVerticalListSkip, | 
					
						
							|  |  |  | 			st::defaultSubsectionTitlePadding.right(), | 
					
						
							|  |  |  | 			st::defaultVerticalListSkip * 2)); | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 	labelField->setMaxLength(kMaxLabelLength); | 
					
						
							|  |  |  | 	addDivider(container, tr::lng_group_invite_label_about()); | 
					
						
							| 
									
										
										
										
											2021-11-02 10:22:12 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	addTitle(container, tr::lng_group_invite_expire_title()); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	const auto expiresWrap = container->add( | 
					
						
							|  |  |  | 		object_ptr<VerticalLayout>(container), | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 		style::margins(0, 0, 0, st::defaultVerticalListSkip)); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	addDivider( | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 		container, | 
					
						
							|  |  |  | 		tr::lng_group_invite_expire_about()); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	const auto usagesSlide = container->add( | 
					
						
							|  |  |  | 		object_ptr<SlideWrap<VerticalLayout>>( | 
					
						
							|  |  |  | 			container, | 
					
						
							|  |  |  | 			object_ptr<VerticalLayout>(container))); | 
					
						
							|  |  |  | 	const auto usagesInner = usagesSlide->entity(); | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 	addTitle(usagesInner, tr::lng_group_invite_usage_title()); | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	const auto usagesWrap = usagesInner->add( | 
					
						
							|  |  |  | 		object_ptr<VerticalLayout>(usagesInner), | 
					
						
							| 
									
										
										
										
											2023-11-15 03:27:13 +03:00
										 |  |  | 		style::margins(0, 0, 0, st::defaultVerticalListSkip)); | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	addDivider(usagesInner, tr::lng_group_invite_usage_about()); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	static const auto addButton = []( | 
					
						
							|  |  |  | 			not_null<VerticalLayout*> container, | 
					
						
							|  |  |  | 			const std::shared_ptr<RadiobuttonGroup> &group, | 
					
						
							|  |  |  | 			int value, | 
					
						
							|  |  |  | 			const QString &text) { | 
					
						
							|  |  |  | 		return container->add( | 
					
						
							|  |  |  | 			object_ptr<Radiobutton>( | 
					
						
							|  |  |  | 				container, | 
					
						
							|  |  |  | 				group, | 
					
						
							|  |  |  | 				value, | 
					
						
							|  |  |  | 				text), | 
					
						
							|  |  |  | 			st::inviteLinkLimitMargin); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const auto regenerate = [=] { | 
					
						
							|  |  |  | 		expireGroup->setValue(state->expireValue); | 
					
						
							|  |  |  | 		usageGroup->setValue(state->usageValue); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		auto expires = std::vector{ kMaxLimit, -kHour, -kDay, -kDay * 7, 0 }; | 
					
						
							|  |  |  | 		auto usages = std::vector{ kMaxLimit, 1, 10, 100, 0 }; | 
					
						
							|  |  |  | 		auto defaults = State(); | 
					
						
							|  |  |  | 		for (auto i = begin(expires); i != end(expires); ++i) { | 
					
						
							|  |  |  | 			if (*i == state->expireValue) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else if (*i == kMaxLimit) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} else if (!*i || (now - *i >= state->expireValue)) { | 
					
						
							|  |  |  | 				expires.insert(i, state->expireValue); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for (auto i = begin(usages); i != end(usages); ++i) { | 
					
						
							|  |  |  | 			if (*i == state->usageValue) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else if (*i == kMaxLimit) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} else if (!*i || *i > state->usageValue) { | 
					
						
							|  |  |  | 				usages.insert(i, state->usageValue); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		state->expireButtons.clear(); | 
					
						
							|  |  |  | 		state->usageButtons.clear(); | 
					
						
							|  |  |  | 		for (const auto limit : expires) { | 
					
						
							|  |  |  | 			const auto text = (limit == kMaxLimit) | 
					
						
							|  |  |  | 				? tr::lng_group_invite_expire_never(tr::now) | 
					
						
							|  |  |  | 				: !limit | 
					
						
							|  |  |  | 				? tr::lng_group_invite_expire_custom(tr::now) | 
					
						
							|  |  |  | 				: FormatExpireDate(limit); | 
					
						
							|  |  |  | 			state->expireButtons.emplace( | 
					
						
							|  |  |  | 				limit, | 
					
						
							|  |  |  | 				addButton(expiresWrap, expireGroup, limit, text)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for (const auto limit : usages) { | 
					
						
							|  |  |  | 			const auto text = (limit == kMaxLimit) | 
					
						
							|  |  |  | 				? tr::lng_group_invite_usage_any(tr::now) | 
					
						
							|  |  |  | 				: !limit | 
					
						
							|  |  |  | 				? tr::lng_group_invite_usage_custom(tr::now) | 
					
						
							| 
									
										
										
										
											2023-09-13 10:30:16 +04:00
										 |  |  | 				: Lang::FormatCountDecimal(limit); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 			state->usageButtons.emplace( | 
					
						
							|  |  |  | 				limit, | 
					
						
							|  |  |  | 				addButton(usagesWrap, usageGroup, limit, text)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const auto guard = MakeWeak(box); | 
					
						
							|  |  |  | 	expireGroup->setChangedCallback([=](int value) { | 
					
						
							|  |  |  | 		if (value) { | 
					
						
							|  |  |  | 			state->expireValue = value; | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		expireGroup->setValue(state->expireValue); | 
					
						
							|  |  |  | 		box->getDelegate()->show(Box([=](not_null<GenericBox*> box) { | 
					
						
							|  |  |  | 			const auto save = [=](TimeId result) { | 
					
						
							|  |  |  | 				if (!result) { | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (guard) { | 
					
						
							|  |  |  | 					state->expireValue = result; | 
					
						
							|  |  |  | 					regenerate(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				box->closeBox(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			const auto now = base::unixtime::now(); | 
					
						
							|  |  |  | 			const auto time = (state->expireValue == kMaxLimit) | 
					
						
							|  |  |  | 				? (now + kDay) | 
					
						
							|  |  |  | 				: (state->expireValue > now) | 
					
						
							|  |  |  | 				? state->expireValue | 
					
						
							|  |  |  | 				: (state->expireValue < 0) | 
					
						
							|  |  |  | 				? (now - state->expireValue) | 
					
						
							|  |  |  | 				: (now + kDay); | 
					
						
							| 
									
										
										
										
											2021-04-09 17:59:43 +04:00
										 |  |  | 			ChooseDateTimeBox(box, { | 
					
						
							|  |  |  | 				.title = tr::lng_group_invite_expire_after(), | 
					
						
							|  |  |  | 				.submit = tr::lng_settings_save(), | 
					
						
							|  |  |  | 				.done = save, | 
					
						
							|  |  |  | 				.time = time, | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 		})); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	usageGroup->setChangedCallback([=](int value) { | 
					
						
							|  |  |  | 		if (value) { | 
					
						
							|  |  |  | 			state->usageValue = value; | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		usageGroup->setValue(state->usageValue); | 
					
						
							|  |  |  | 		box->getDelegate()->show(Box([=](not_null<GenericBox*> box) { | 
					
						
							|  |  |  | 			const auto height = st::boxPadding.bottom() | 
					
						
							|  |  |  | 				+ st::defaultInputField.heightMin | 
					
						
							|  |  |  | 				+ st::boxPadding.bottom(); | 
					
						
							|  |  |  | 			box->setTitle(tr::lng_group_invite_expire_after()); | 
					
						
							|  |  |  | 			const auto wrap = box->addRow(object_ptr<FixedHeightWidget>( | 
					
						
							|  |  |  | 				box, | 
					
						
							|  |  |  | 				height)); | 
					
						
							|  |  |  | 			const auto input = CreateChild<NumberInput>( | 
					
						
							|  |  |  | 				wrap, | 
					
						
							|  |  |  | 				st::defaultInputField, | 
					
						
							|  |  |  | 				tr::lng_group_invite_custom_limit(), | 
					
						
							|  |  |  | 				(state->usageValue == kMaxLimit | 
					
						
							|  |  |  | 					? QString() | 
					
						
							|  |  |  | 					: QString::number(state->usageValue)), | 
					
						
							|  |  |  | 				200'000); | 
					
						
							|  |  |  | 			wrap->widthValue( | 
					
						
							|  |  |  | 			) | rpl::start_with_next([=](int width) { | 
					
						
							|  |  |  | 				input->resize(width, input->height()); | 
					
						
							|  |  |  | 				input->moveToLeft(0, st::boxPadding.bottom()); | 
					
						
							|  |  |  | 			}, input->lifetime()); | 
					
						
							|  |  |  | 			box->setFocusCallback([=] { | 
					
						
							|  |  |  | 				input->setFocusFast(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const auto save = [=] { | 
					
						
							|  |  |  | 				const auto value = input->getLastText().toInt(); | 
					
						
							|  |  |  | 				if (value <= 0) { | 
					
						
							|  |  |  | 					input->showError(); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (guard) { | 
					
						
							|  |  |  | 					state->usageValue = value; | 
					
						
							|  |  |  | 					regenerate(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				box->closeBox(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			QObject::connect(input, &NumberInput::submitted, save); | 
					
						
							|  |  |  | 			box->addButton(tr::lng_settings_save(), save); | 
					
						
							|  |  |  | 			box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); | 
					
						
							|  |  |  | 		})); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	regenerate(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 16:52:24 +04:00
										 |  |  | 	usagesSlide->toggleOn(state->requestApproval.value() | rpl::map(!_1)); | 
					
						
							|  |  |  | 	usagesSlide->finishAnimating(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 	const auto &saveLabel = link.isEmpty() | 
					
						
							|  |  |  | 		? tr::lng_formatting_link_create | 
					
						
							|  |  |  | 		: tr::lng_settings_save; | 
					
						
							|  |  |  | 	box->addButton(saveLabel(), [=] { | 
					
						
							| 
									
										
										
										
											2021-10-28 16:18:49 +04:00
										 |  |  | 		const auto label = labelField->getLastText(); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 		const auto expireDate = (state->expireValue == kMaxLimit) | 
					
						
							|  |  |  | 			? 0 | 
					
						
							|  |  |  | 			: (state->expireValue < 0) | 
					
						
							|  |  |  | 			? (base::unixtime::now() - state->expireValue) | 
					
						
							|  |  |  | 			: state->expireValue; | 
					
						
							|  |  |  | 		const auto usageLimit = (state->usageValue == kMaxLimit) | 
					
						
							|  |  |  | 			? 0 | 
					
						
							|  |  |  | 			: state->usageValue; | 
					
						
							|  |  |  | 		done(InviteLinkFields{ | 
					
						
							|  |  |  | 			.link = link, | 
					
						
							| 
									
										
										
										
											2021-10-28 16:18:49 +04:00
										 |  |  | 			.label = label, | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 			.expireDate = expireDate, | 
					
						
							| 
									
										
										
										
											2021-10-12 12:39:07 +04:00
										 |  |  | 			.usageLimit = usageLimit, | 
					
						
							|  |  |  | 			.requestApproval = state->requestApproval.current(), | 
					
						
							|  |  |  | 			.isGroup = isGroup, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 			.isPublic = isPublic, | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CreateInviteLinkBox( | 
					
						
							|  |  |  | 		not_null<GenericBox*> box, | 
					
						
							| 
									
										
										
										
											2021-10-12 12:39:07 +04:00
										 |  |  | 		bool isGroup, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 		bool isPublic, | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | 		Fn<void(InviteLinkFields)> done) { | 
					
						
							| 
									
										
										
										
											2021-10-12 12:39:07 +04:00
										 |  |  | 	EditInviteLinkBox( | 
					
						
							| 
									
										
										
										
											2021-10-12 22:44:35 +04:00
										 |  |  | 		box, | 
					
						
							| 
									
										
										
										
											2021-11-03 16:01:25 +04:00
										 |  |  | 		InviteLinkFields{ .isGroup = isGroup, .isPublic = isPublic }, | 
					
						
							| 
									
										
										
										
											2021-10-12 12:39:07 +04:00
										 |  |  | 		std::move(done)); | 
					
						
							| 
									
										
										
										
											2021-01-19 11:14:50 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace Ui
 |