Update API scheme to layer 168. Giveaways.
This commit is contained in:
		
							parent
							
								
									f5b59c9456
								
							
						
					
					
						commit
						e135f8954f
					
				
					 10 changed files with 258 additions and 58 deletions
				
			
		|  | @ -2170,6 +2170,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| "lng_giveaway_maximum_users_error#other" = "You can select maximum {count} users."; | "lng_giveaway_maximum_users_error#other" = "You can select maximum {count} users."; | ||||||
| "lng_giveaway_channels_confirm_title" = "Channel is Private"; | "lng_giveaway_channels_confirm_title" = "Channel is Private"; | ||||||
| "lng_giveaway_channels_confirm_about" = "Are you sure you want to add a private channel? Users won't be able to join it without an invite link."; | "lng_giveaway_channels_confirm_about" = "Are you sure you want to add a private channel? Users won't be able to join it without an invite link."; | ||||||
|  | "lng_giveaway_additional_prizes" = "Additional prizes"; | ||||||
|  | "lng_giveaway_additional_about" = "Turn this on if you want to give the winners your own prizes in addition to Premium subscriptions."; | ||||||
|  | "lng_giveaway_additional_prizes_ph" = "Enter your prize"; | ||||||
|  | "lng_giveaway_prizes_just_premium#one" = "All prizes: **{count}** Telegram Premium subscription {duration}."; | ||||||
|  | "lng_giveaway_prizes_just_premium#other" = "All prizes: **{count}** Telegram Premium subscriptions {duration}."; | ||||||
|  | "lng_giveaway_prizes_additional#one" = "All prizes: **{count}** {prize} with Telegram Premium subscription {duration}."; | ||||||
|  | "lng_giveaway_prizes_additional#other" = "All prizes: **{count}** {prize} with Telegram Premium subscriptions {duration}."; | ||||||
|  | "lng_giveaway_show_winners" = "Show winners"; | ||||||
|  | "lng_giveaway_show_winners_about" = "Choose whether to make the list of winners public when the giveaway ends."; | ||||||
| 
 | 
 | ||||||
| "lng_giveaway_created_title" = "Giveaway created"; | "lng_giveaway_created_title" = "Giveaway created"; | ||||||
| "lng_giveaway_created_body" = "Check your channels' {link} to see how this giveaway boosted your channel."; | "lng_giveaway_created_body" = "Check your channels' {link} to see how this giveaway boosted your channel."; | ||||||
|  |  | ||||||
|  | @ -420,6 +420,8 @@ const std::vector<int> &PremiumGiftCodeOptions::availablePresets() const { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [[nodiscard]] int PremiumGiftCodeOptions::monthsFromPreset(int monthsIndex) { | [[nodiscard]] int PremiumGiftCodeOptions::monthsFromPreset(int monthsIndex) { | ||||||
|  | 	Expects(monthsIndex >= 0 && monthsIndex < _availablePresets.size()); | ||||||
|  | 
 | ||||||
| 	return _optionsForOnePerson.months[monthsIndex]; | 	return _optionsForOnePerson.months[monthsIndex]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -221,11 +221,11 @@ void ApiWrap::setupSupportMode() { | ||||||
| void ApiWrap::requestChangelog( | void ApiWrap::requestChangelog( | ||||||
| 		const QString &sinceVersion, | 		const QString &sinceVersion, | ||||||
| 		Fn<void(const MTPUpdates &result)> callback) { | 		Fn<void(const MTPUpdates &result)> callback) { | ||||||
| 	request(MTPhelp_GetAppChangelog( | 	//request(MTPhelp_GetAppChangelog(
 | ||||||
| 		MTP_string(sinceVersion) | 	//	MTP_string(sinceVersion)
 | ||||||
| 	)).done( | 	//)).done(
 | ||||||
| 		callback | 	//	callback
 | ||||||
| 	).send(); | 	//).send();
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ApiWrap::refreshTopPromotion() { | void ApiWrap::refreshTopPromotion() { | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| #include "ui/toast/toast.h" | #include "ui/toast/toast.h" | ||||||
| #include "ui/widgets/checkbox.h" | #include "ui/widgets/checkbox.h" | ||||||
| #include "ui/widgets/continuous_sliders.h" | #include "ui/widgets/continuous_sliders.h" | ||||||
|  | #include "ui/widgets/fields/input_field.h" | ||||||
| #include "ui/widgets/labels.h" | #include "ui/widgets/labels.h" | ||||||
| #include "ui/wrap/slide_wrap.h" | #include "ui/wrap/slide_wrap.h" | ||||||
| #include "styles/style_giveaway.h" | #include "styles/style_giveaway.h" | ||||||
|  | @ -48,6 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| namespace { | namespace { | ||||||
| 
 | 
 | ||||||
| constexpr auto kDoneTooltipDuration = 5 * crl::time(1000); | constexpr auto kDoneTooltipDuration = 5 * crl::time(1000); | ||||||
|  | constexpr auto kAdditionalPrizeLengthMax = 128; | ||||||
| 
 | 
 | ||||||
| [[nodiscard]] QDateTime ThreeDaysAfterToday() { | [[nodiscard]] QDateTime ThreeDaysAfterToday() { | ||||||
| 	auto dateNow = QDateTime::currentDateTime(); | 	auto dateNow = QDateTime::currentDateTime(); | ||||||
|  | @ -257,6 +259,10 @@ void CreateGiveawayBox( | ||||||
| 		rpl::variable<TimeId> dateValue; | 		rpl::variable<TimeId> dateValue; | ||||||
| 		rpl::variable<std::vector<QString>> countriesValue; | 		rpl::variable<std::vector<QString>> countriesValue; | ||||||
| 
 | 
 | ||||||
|  | 		rpl::variable<QString> additionalPrize; | ||||||
|  | 		rpl::variable<int> chosenMonths; | ||||||
|  | 		rpl::variable<bool> showWinners; | ||||||
|  | 
 | ||||||
| 		rpl::variable<bool> confirmButtonBusy = true; | 		rpl::variable<bool> confirmButtonBusy = true; | ||||||
| 	}; | 	}; | ||||||
| 	const auto state = box->lifetime().make_state<State>(peer); | 	const auto state = box->lifetime().make_state<State>(peer); | ||||||
|  | @ -669,6 +675,182 @@ void CreateGiveawayBox( | ||||||
| 		c->add(std::move(terms)); | 		c->add(std::move(terms)); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	const auto durationGroup = std::make_shared<Ui::RadiobuttonGroup>(0); | ||||||
|  | 	durationGroup->setChangedCallback([=](int value) { | ||||||
|  | 		state->chosenMonths = state->apiOptions.monthsFromPreset(value); | ||||||
|  | 	}); | ||||||
|  | 	const auto listOptionsRandom = randomWrap->entity()->add( | ||||||
|  | 		object_ptr<Ui::VerticalLayout>(box)); | ||||||
|  | 	const auto listOptionsSpecific = contentWrap->entity()->add( | ||||||
|  | 		object_ptr<Ui::VerticalLayout>(box)); | ||||||
|  | 	const auto rebuildListOptions = [=](GiveawayType type, int usersCount) { | ||||||
|  | 		if (prepaid) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		while (listOptionsRandom->count()) { | ||||||
|  | 			delete listOptionsRandom->widgetAt(0); | ||||||
|  | 		} | ||||||
|  | 		while (listOptionsSpecific->count()) { | ||||||
|  | 			delete listOptionsSpecific->widgetAt(0); | ||||||
|  | 		} | ||||||
|  | 		const auto listOptions = (type == GiveawayType::SpecificUsers) | ||||||
|  | 			? listOptionsSpecific | ||||||
|  | 			: listOptionsRandom; | ||||||
|  | 		Ui::AddSubsectionTitle( | ||||||
|  | 			listOptions, | ||||||
|  | 			tr::lng_giveaway_duration_title( | ||||||
|  | 				lt_count, | ||||||
|  | 				rpl::single(usersCount) | tr::to_count()), | ||||||
|  | 			st::giveawayGiftCodeChannelsSubsectionPadding); | ||||||
|  | 		Ui::Premium::AddGiftOptions( | ||||||
|  | 			listOptions, | ||||||
|  | 			durationGroup, | ||||||
|  | 			state->apiOptions.options(usersCount), | ||||||
|  | 			st::giveawayGiftCodeGiftOption, | ||||||
|  | 			true); | ||||||
|  | 
 | ||||||
|  | 		Ui::AddSkip(listOptions); | ||||||
|  | 
 | ||||||
|  | 		auto termsContainer = object_ptr<Ui::VerticalLayout>(listOptions); | ||||||
|  | 		addTerms(termsContainer.data()); | ||||||
|  | 		listOptions->add(object_ptr<Ui::DividerLabel>( | ||||||
|  | 			listOptions, | ||||||
|  | 			std::move(termsContainer), | ||||||
|  | 			st::defaultBoxDividerLabelPadding)); | ||||||
|  | 
 | ||||||
|  | 		Ui::AddSkip(listOptions); | ||||||
|  | 
 | ||||||
|  | 		box->verticalLayout()->resizeToWidth(box->width()); | ||||||
|  | 	}; | ||||||
|  | 	if (!prepaid) { | ||||||
|  | 		rpl::combine( | ||||||
|  | 			state->sliderValue.value(), | ||||||
|  | 			state->typeValue.value() | ||||||
|  | 		) | rpl::start_with_next([=](int users, GiveawayType type) { | ||||||
|  | 			typeGroup->setValue(type); | ||||||
|  | 			rebuildListOptions(type, (type == GiveawayType::SpecificUsers) | ||||||
|  | 				? state->selectedToAward.size() | ||||||
|  | 				: users); | ||||||
|  | 		}, box->lifetime()); | ||||||
|  | 	} else { | ||||||
|  | 		typeGroup->setValue(GiveawayType::Random); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	{ | ||||||
|  | 		const auto additionalWrap = randomWrap->entity()->add( | ||||||
|  | 			object_ptr<Ui::VerticalLayout>(randomWrap)); | ||||||
|  | 		const auto additionalToggle = additionalWrap->add( | ||||||
|  | 			object_ptr<Ui::SettingsButton>( | ||||||
|  | 				additionalWrap, | ||||||
|  | 				tr::lng_giveaway_additional_prizes(), | ||||||
|  | 				st::defaultSettingsButton)); | ||||||
|  | 		const auto additionalInner = additionalWrap->add( | ||||||
|  | 			object_ptr<Ui::SlideWrap<Ui::InputField>>( | ||||||
|  | 				additionalWrap, | ||||||
|  | 				object_ptr<Ui::InputField>( | ||||||
|  | 					additionalWrap, | ||||||
|  | 					st::giveawayGiftCodeAdditionalField, | ||||||
|  | 					Ui::InputField::Mode::SingleLine, | ||||||
|  | 					tr::lng_giveaway_additional_prizes_ph()), | ||||||
|  | 				st::giveawayGiftCodeAdditionalPaddingMin)); | ||||||
|  | 		const auto additionalPadded = additionalInner->wrapped(); | ||||||
|  | 		const auto additional = additionalInner->entity(); | ||||||
|  | 		additionalInner->hide(anim::type::instant); | ||||||
|  | 		additional->setMaxLength(kAdditionalPrizeLengthMax); | ||||||
|  | 		const auto fillAdditionalPrizeValue = [=] { | ||||||
|  | 			state->additionalPrize = additional->getLastText().trimmed(); | ||||||
|  | 		}; | ||||||
|  | 		additionalToggle->toggleOn(rpl::single(false))->toggledChanges( | ||||||
|  | 		) | rpl::start_with_next([=](bool toggled) { | ||||||
|  | 			if (!toggled && Ui::InFocusChain(additional)) { | ||||||
|  | 				additionalWrap->setFocus(); | ||||||
|  | 				state->additionalPrize = QString(); | ||||||
|  | 			} | ||||||
|  | 			additionalInner->toggle(toggled, anim::type::normal); | ||||||
|  | 			if (toggled) { | ||||||
|  | 				additional->setFocusFast(); | ||||||
|  | 				fillAdditionalPrizeValue(); | ||||||
|  | 			} | ||||||
|  | 		}, additionalInner->lifetime()); | ||||||
|  | 		additionalInner->finishAnimating(); | ||||||
|  | 
 | ||||||
|  | 		additional->changes() | rpl::filter([=] { | ||||||
|  | 			return additionalInner->toggled(); | ||||||
|  | 		}) | rpl::start_with_next( | ||||||
|  | 			fillAdditionalPrizeValue, | ||||||
|  | 			additional->lifetime()); | ||||||
|  | 
 | ||||||
|  | 		Ui::AddSkip(additionalWrap); | ||||||
|  | 
 | ||||||
|  | 		auto monthsValue = prepaid | ||||||
|  | 			? (rpl::single(prepaid->months) | rpl::type_erased()) | ||||||
|  | 			: state->chosenMonths.value(); | ||||||
|  | 		const auto usersCountByType = [=](GiveawayType type) { | ||||||
|  | 			if (type != GiveawayType::SpecificUsers) { | ||||||
|  | 				return state->sliderValue.value() | rpl::type_erased(); | ||||||
|  | 			} | ||||||
|  | 			return state->toAwardAmountChanged.events_starting_with_copy( | ||||||
|  | 				rpl::empty | ||||||
|  | 			) | rpl::map([=] { | ||||||
|  | 				return int(state->selectedToAward.size()); | ||||||
|  | 			}) | rpl::type_erased(); | ||||||
|  | 		}; | ||||||
|  | 		auto usersCountValue = prepaid | ||||||
|  | 			? (rpl::single(prepaid->quantity) | rpl::type_erased()) | ||||||
|  | 			: state->typeValue.value( | ||||||
|  | 			) | rpl::map(usersCountByType) | rpl::flatten_latest(); | ||||||
|  | 
 | ||||||
|  | 		const auto additionalLabel = Ui::CreateChild<Ui::FlatLabel>( | ||||||
|  | 			additionalInner, | ||||||
|  | 			rpl::duplicate(usersCountValue) | rpl::map([](int count) { | ||||||
|  | 				return QString::number(count); | ||||||
|  | 			}), | ||||||
|  | 			st::giveawayGiftCodeAdditionalLabel); | ||||||
|  | 		additionalLabel->widthValue() | rpl::start_with_next([=](int width) { | ||||||
|  | 			const auto min = st::giveawayGiftCodeAdditionalPaddingMin; | ||||||
|  | 			const auto skip = st::giveawayGiftCodeAdditionalLabelSkip; | ||||||
|  | 			const auto added = std::max(width + skip - min.left(), 0); | ||||||
|  | 			const auto &field = st::giveawayGiftCodeAdditionalField; | ||||||
|  | 			const auto top = field.textMargins.top(); | ||||||
|  | 			additionalLabel->moveToLeft(min.right(), min.top() + top); | ||||||
|  | 			additionalPadded->setPadding(min + QMargins(added, 0, 0, 0)); | ||||||
|  | 		}, additionalLabel->lifetime()); | ||||||
|  | 
 | ||||||
|  | 		auto additionalAbout = rpl::combine( | ||||||
|  | 			state->additionalPrize.value(), | ||||||
|  | 			std::move(monthsValue), | ||||||
|  | 			std::move(usersCountValue) | ||||||
|  | 		) | rpl::map([=](QString prize, int months, int users) { | ||||||
|  | 			const auto duration = ((months >= 12) | ||||||
|  | 				? tr::lng_premium_gift_duration_years | ||||||
|  | 				: tr::lng_premium_gift_duration_months)( | ||||||
|  | 					tr::now, | ||||||
|  | 					lt_count, | ||||||
|  | 					(months >= 12) ? (months / 12) : months); | ||||||
|  | 			if (prize.isEmpty()) { | ||||||
|  | 				return tr::lng_giveaway_prizes_just_premium( | ||||||
|  | 					tr::now, | ||||||
|  | 					lt_count, | ||||||
|  | 					users, | ||||||
|  | 					lt_duration, | ||||||
|  | 					TextWithEntities{ duration }, | ||||||
|  | 					Ui::Text::RichLangValue); | ||||||
|  | 			} | ||||||
|  | 			return tr::lng_giveaway_prizes_additional( | ||||||
|  | 				tr::now, | ||||||
|  | 				lt_count, | ||||||
|  | 				users, | ||||||
|  | 				lt_prize, | ||||||
|  | 				TextWithEntities{ prize }, | ||||||
|  | 				lt_duration, | ||||||
|  | 				TextWithEntities{ duration }, | ||||||
|  | 				Ui::Text::RichLangValue); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		Ui::AddDividerText(additionalWrap, std::move(additionalAbout)); | ||||||
|  | 		Ui::AddSkip(additionalWrap); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	{ | 	{ | ||||||
| 		const auto dateContainer = randomWrap->entity()->add( | 		const auto dateContainer = randomWrap->entity()->add( | ||||||
| 			object_ptr<Ui::VerticalLayout>(randomWrap)); | 			object_ptr<Ui::VerticalLayout>(randomWrap)); | ||||||
|  | @ -699,7 +881,7 @@ void CreateGiveawayBox( | ||||||
| 					.time = state->dateValue.current(), | 					.time = state->dateValue.current(), | ||||||
| 					.max = [=] { | 					.max = [=] { | ||||||
| 						return QDateTime::currentSecsSinceEpoch() | 						return QDateTime::currentSecsSinceEpoch() | ||||||
| 							+ state->apiOptions.giveawayPeriodMax();; | 							+ state->apiOptions.giveawayPeriodMax(); | ||||||
| 					}, | 					}, | ||||||
| 				}); | 				}); | ||||||
| 			})); | 			})); | ||||||
|  | @ -721,6 +903,7 @@ void CreateGiveawayBox( | ||||||
| 				dateContainer, | 				dateContainer, | ||||||
| 				std::move(terms), | 				std::move(terms), | ||||||
| 				st::defaultBoxDividerLabelPadding)); | 				st::defaultBoxDividerLabelPadding)); | ||||||
|  | 			Ui::AddSkip(dateContainer); | ||||||
| 		} else { | 		} else { | ||||||
| 			Ui::AddDividerText( | 			Ui::AddDividerText( | ||||||
| 				dateContainer, | 				dateContainer, | ||||||
|  | @ -731,53 +914,24 @@ void CreateGiveawayBox( | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const auto durationGroup = std::make_shared<Ui::RadiobuttonGroup>(0); | 	{ | ||||||
| 	const auto listOptions = contentWrap->entity()->add( | 		const auto winnersWrap = randomWrap->entity()->add( | ||||||
| 		object_ptr<Ui::VerticalLayout>(box)); | 			object_ptr<Ui::VerticalLayout>(randomWrap)); | ||||||
| 	const auto rebuildListOptions = [=](int amountUsers) { | 		const auto winnersToggle = winnersWrap->add( | ||||||
| 		if (prepaid) { | 			object_ptr<Ui::SettingsButton>( | ||||||
| 			return; | 				winnersWrap, | ||||||
| 		} | 				tr::lng_giveaway_show_winners(), | ||||||
| 		while (listOptions->count()) { | 				st::defaultSettingsButton)); | ||||||
| 			delete listOptions->widgetAt(0); | 		state->showWinners = winnersToggle->toggleOn( | ||||||
| 		} | 			rpl::single(false) | ||||||
| 		Ui::AddSubsectionTitle( | 		)->toggledValue(); | ||||||
| 			listOptions, | 		Ui::AddSkip(winnersWrap); | ||||||
| 			tr::lng_giveaway_duration_title( |  | ||||||
| 				lt_count, |  | ||||||
| 				rpl::single(amountUsers) | tr::to_count()), |  | ||||||
| 			st::giveawayGiftCodeChannelsSubsectionPadding); |  | ||||||
| 		Ui::Premium::AddGiftOptions( |  | ||||||
| 			listOptions, |  | ||||||
| 			durationGroup, |  | ||||||
| 			state->apiOptions.options(amountUsers), |  | ||||||
| 			st::giveawayGiftCodeGiftOption, |  | ||||||
| 			true); |  | ||||||
| 
 | 
 | ||||||
| 		Ui::AddSkip(listOptions); | 		Ui::AddDividerText( | ||||||
| 
 | 			winnersWrap, | ||||||
| 		auto termsContainer = object_ptr<Ui::VerticalLayout>(listOptions); | 			tr::lng_giveaway_show_winners_about()); | ||||||
| 		addTerms(termsContainer.data()); |  | ||||||
| 		listOptions->add(object_ptr<Ui::DividerLabel>( |  | ||||||
| 			listOptions, |  | ||||||
| 			std::move(termsContainer), |  | ||||||
| 			st::defaultBoxDividerLabelPadding)); |  | ||||||
| 
 |  | ||||||
| 		box->verticalLayout()->resizeToWidth(box->width()); |  | ||||||
| 	}; |  | ||||||
| 	if (!prepaid) { |  | ||||||
| 		rpl::combine( |  | ||||||
| 			state->sliderValue.value(), |  | ||||||
| 			state->typeValue.value() |  | ||||||
| 		) | rpl::start_with_next([=](int users, GiveawayType type) { |  | ||||||
| 			typeGroup->setValue(type); |  | ||||||
| 			rebuildListOptions((type == GiveawayType::SpecificUsers) |  | ||||||
| 				? state->selectedToAward.size() |  | ||||||
| 				: users); |  | ||||||
| 		}, box->lifetime()); |  | ||||||
| 	} else { |  | ||||||
| 		typeGroup->setValue(GiveawayType::Random); |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	{ | 	{ | ||||||
| 		using namespace Info::Statistics; | 		using namespace Info::Statistics; | ||||||
| 		const auto &stButton = st::startGiveawayBox; | 		const auto &stButton = st::startGiveawayBox; | ||||||
|  | @ -862,9 +1016,11 @@ void CreateGiveawayBox( | ||||||
| 						return not_null{ p->asChannel() }; | 						return not_null{ p->asChannel() }; | ||||||
| 					}) | ranges::to_vector, | 					}) | ranges::to_vector, | ||||||
| 					.countries = state->countriesValue.current(), | 					.countries = state->countriesValue.current(), | ||||||
|  | 					.additionalPrize = state->additionalPrize.current(), | ||||||
| 					.untilDate = state->dateValue.current(), | 					.untilDate = state->dateValue.current(), | ||||||
| 					.onlyNewSubscribers = (membersGroup->value() | 					.onlyNewSubscribers = (membersGroup->value() | ||||||
| 						== GiveawayType::OnlyNewMembers), | 						== GiveawayType::OnlyNewMembers), | ||||||
|  | 					.showWinners = state->showWinners.current(), | ||||||
| 				}; | 				}; | ||||||
| 			} | 			} | ||||||
| 			state->confirmButtonBusy = true; | 			state->confirmButtonBusy = true; | ||||||
|  | @ -960,7 +1116,10 @@ void CreateGiveawayBox( | ||||||
| 			loading->toggle(false, anim::type::instant); | 			loading->toggle(false, anim::type::instant); | ||||||
| 			state->confirmButtonBusy = false; | 			state->confirmButtonBusy = false; | ||||||
| 			fillSliderContainer(); | 			fillSliderContainer(); | ||||||
| 			rebuildListOptions(1); | 			if (!prepaid) { | ||||||
|  | 				state->chosenMonths = state->apiOptions.monthsFromPreset(0); | ||||||
|  | 			} | ||||||
|  | 			rebuildListOptions(state->typeValue.current(), 1); | ||||||
| 			contentWrap->toggle(true, anim::type::instant); | 			contentWrap->toggle(true, anim::type::instant); | ||||||
| 			contentWrap->resizeToWidth(box->width()); | 			contentWrap->resizeToWidth(box->width()); | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
|  | @ -121,6 +121,13 @@ giveawayGiftCodeTypeDividerPadding: margins(0px, 7px, 0px, 5px); | ||||||
| giveawayGiftCodeSliderPadding: margins(0px, 24px, 0px, 10px); | giveawayGiftCodeSliderPadding: margins(0px, 24px, 0px, 10px); | ||||||
| giveawayGiftCodeSliderFloatSkip: 6px; | giveawayGiftCodeSliderFloatSkip: 6px; | ||||||
| giveawayGiftCodeChannelsSubsectionPadding: margins(0px, -1px, 0px, -4px); | giveawayGiftCodeChannelsSubsectionPadding: margins(0px, -1px, 0px, -4px); | ||||||
|  | giveawayGiftCodeAdditionalPaddingMin: margins(50px, 4px, 22px, 0px); | ||||||
|  | giveawayGiftCodeAdditionalField: InputField(defaultMultiSelectSearchField) { | ||||||
|  | } | ||||||
|  | giveawayGiftCodeAdditionalLabel: FlatLabel(defaultFlatLabel) { | ||||||
|  | 	style: semiboldTextStyle; | ||||||
|  | } | ||||||
|  | giveawayGiftCodeAdditionalLabelSkip: 12px; | ||||||
| 
 | 
 | ||||||
| giveawayGiftCodeChannelsPeerList: PeerList(boostsListBox) { | giveawayGiftCodeChannelsPeerList: PeerList(boostsListBox) { | ||||||
| 	padding: margins(0px, 7px, 0px, 0px); | 	padding: margins(0px, 7px, 0px, 0px); | ||||||
|  |  | ||||||
|  | @ -131,7 +131,7 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int | ||||||
| messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; | messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; | ||||||
| messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; | messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; | ||||||
| messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; | messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; | ||||||
| messageMediaGiveaway#58260664 flags:# only_new_subscribers:flags.0?true channels:Vector<long> countries_iso2:flags.1?Vector<string> quantity:int months:int until_date:int = MessageMedia; | messageMediaGiveaway#daad85b0 flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector<long> countries_iso2:flags.1?Vector<string> prize_description:flags.3?string quantity:int months:int until_date:int = MessageMedia; | ||||||
| 
 | 
 | ||||||
| messageActionEmpty#b6aef7b0 = MessageAction; | messageActionEmpty#b6aef7b0 = MessageAction; | ||||||
| messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction; | messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction; | ||||||
|  | @ -1426,7 +1426,7 @@ help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEnti | ||||||
| inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose; | inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose; | ||||||
| inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; | inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; | ||||||
| inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose; | inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose; | ||||||
| inputStorePaymentPremiumGiveaway#7c9375e6 flags:# only_new_subscribers:flags.0?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; | inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; | ||||||
| 
 | 
 | ||||||
| premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; | premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; | ||||||
| 
 | 
 | ||||||
|  | @ -1583,7 +1583,7 @@ premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags. | ||||||
| payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode; | payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode; | ||||||
| 
 | 
 | ||||||
| payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; | payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; | ||||||
| payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo; | payments.giveawayInfoResults#8ac7e167 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int winners:flags.2?Vector<User> = payments.GiveawayInfo; | ||||||
| 
 | 
 | ||||||
| prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway; | prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway; | ||||||
| 
 | 
 | ||||||
|  | @ -1619,6 +1619,10 @@ help.peerColorOption#135bd42f flags:# hidden:flags.0?true color_id:int colors:fl | ||||||
| help.peerColorsNotModified#2ba1f5ce = help.PeerColors; | help.peerColorsNotModified#2ba1f5ce = help.PeerColors; | ||||||
| help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors; | help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors; | ||||||
| 
 | 
 | ||||||
|  | storyPeerReaction#7decc433 peer_id:Peer date:int reaction:Reaction = StoryPeerReaction; | ||||||
|  | 
 | ||||||
|  | stories.storyReactionsList#d86c162a flags:# count:int reactions:Vector<StoryPeerReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList; | ||||||
|  | 
 | ||||||
| ---functions--- | ---functions--- | ||||||
| 
 | 
 | ||||||
| invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; | invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; | ||||||
|  | @ -1986,7 +1990,6 @@ help.getNearestDc#1fb33026 = NearestDc; | ||||||
| help.getAppUpdate#522d5a7d source:string = help.AppUpdate; | help.getAppUpdate#522d5a7d source:string = help.AppUpdate; | ||||||
| help.getInviteText#4d392343 = help.InviteText; | help.getInviteText#4d392343 = help.InviteText; | ||||||
| help.getSupport#9cdf08cd = help.Support; | help.getSupport#9cdf08cd = help.Support; | ||||||
| help.getAppChangelog#9010ef6f prev_app_version:string = Updates; |  | ||||||
| help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; | help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; | ||||||
| help.getCdnConfig#52029342 = CdnConfig; | help.getCdnConfig#52029342 = CdnConfig; | ||||||
| help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; | help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; | ||||||
|  | @ -2195,6 +2198,7 @@ stories.getAllReadPeerStories#9b5ae7f9 = Updates; | ||||||
| stories.getPeerMaxIDs#535983c3 id:Vector<InputPeer> = Vector<int>; | stories.getPeerMaxIDs#535983c3 id:Vector<InputPeer> = Vector<int>; | ||||||
| stories.getChatsToSend#a56a8b60 = messages.Chats; | stories.getChatsToSend#a56a8b60 = messages.Chats; | ||||||
| stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; | stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; | ||||||
|  | stories.getStoryReactionsList#b9b2881f flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList; | ||||||
| 
 | 
 | ||||||
| premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; | premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; | ||||||
| premium.getMyBoosts#be77b4a = premium.MyBoosts; | premium.getMyBoosts#be77b4a = premium.MyBoosts; | ||||||
|  | @ -2202,4 +2206,4 @@ premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector<int> peer:InputPeer = p | ||||||
| premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus; | premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus; | ||||||
| premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList; | premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList; | ||||||
| 
 | 
 | ||||||
| // LAYER 167 | // LAYER 168 | ||||||
|  |  | ||||||
|  | @ -145,7 +145,13 @@ MTPinputStorePaymentPurpose InvoicePremiumGiftCodeGiveawayToTL( | ||||||
| 				: Flag::f_additional_peers) | 				: Flag::f_additional_peers) | ||||||
| 			| (giveaway.countries.empty() | 			| (giveaway.countries.empty() | ||||||
| 				? Flag() | 				? Flag() | ||||||
| 				: Flag::f_countries_iso2)), | 				: Flag::f_countries_iso2) | ||||||
|  | 			| (giveaway.showWinners | ||||||
|  | 				? Flag::f_winners_are_visible | ||||||
|  | 				: Flag()) | ||||||
|  | 			| (giveaway.additionalPrize.isEmpty() | ||||||
|  | 				? Flag() | ||||||
|  | 				: Flag::f_prize_description)), | ||||||
| 		giveaway.boostPeer->input, | 		giveaway.boostPeer->input, | ||||||
| 		MTP_vector_from_range(ranges::views::all( | 		MTP_vector_from_range(ranges::views::all( | ||||||
| 			giveaway.additionalChannels | 			giveaway.additionalChannels | ||||||
|  | @ -157,6 +163,7 @@ MTPinputStorePaymentPurpose InvoicePremiumGiftCodeGiveawayToTL( | ||||||
| 		) | ranges::views::transform([](QString value) { | 		) | ranges::views::transform([](QString value) { | ||||||
| 			return MTP_string(value); | 			return MTP_string(value); | ||||||
| 		})), | 		})), | ||||||
|  | 		MTP_string(giveaway.additionalPrize), | ||||||
| 		MTP_long(invoice.randomId), | 		MTP_long(invoice.randomId), | ||||||
| 		MTP_int(giveaway.untilDate), | 		MTP_int(giveaway.untilDate), | ||||||
| 		MTP_string(invoice.currency), | 		MTP_string(invoice.currency), | ||||||
|  |  | ||||||
|  | @ -190,8 +190,10 @@ struct InvoicePremiumGiftCodeGiveaway { | ||||||
| 	not_null<ChannelData*> boostPeer; | 	not_null<ChannelData*> boostPeer; | ||||||
| 	std::vector<not_null<ChannelData*>> additionalChannels; | 	std::vector<not_null<ChannelData*>> additionalChannels; | ||||||
| 	std::vector<QString> countries; | 	std::vector<QString> countries; | ||||||
|  | 	QString additionalPrize; | ||||||
| 	TimeId untilDate = 0; | 	TimeId untilDate = 0; | ||||||
| 	bool onlyNewSubscribers = false; | 	bool onlyNewSubscribers = false; | ||||||
|  | 	bool showWinners = false; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct InvoicePremiumGiftCodeUsers { | struct InvoicePremiumGiftCodeUsers { | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| */ | */ | ||||||
| #include "ui/vertical_list.h" | #include "ui/vertical_list.h" | ||||||
| 
 | 
 | ||||||
|  | #include "ui/text/text_utilities.h" | ||||||
| #include "ui/widgets/box_content_divider.h" | #include "ui/widgets/box_content_divider.h" | ||||||
| #include "ui/widgets/labels.h" | #include "ui/widgets/labels.h" | ||||||
| #include "ui/wrap/padding_wrap.h" | #include "ui/wrap/padding_wrap.h" | ||||||
|  | @ -30,6 +31,12 @@ void AddDivider(not_null<Ui::VerticalLayout*> container) { | ||||||
| void AddDividerText( | void AddDividerText( | ||||||
| 		not_null<Ui::VerticalLayout*> container, | 		not_null<Ui::VerticalLayout*> container, | ||||||
| 		rpl::producer<QString> text) { | 		rpl::producer<QString> text) { | ||||||
|  | 	AddDividerText(container, std::move(text) | Ui::Text::ToWithEntities()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AddDividerText( | ||||||
|  | 		not_null<Ui::VerticalLayout*> container, | ||||||
|  | 		rpl::producer<TextWithEntities> text) { | ||||||
| 	container->add(object_ptr<Ui::DividerLabel>( | 	container->add(object_ptr<Ui::DividerLabel>( | ||||||
| 		container, | 		container, | ||||||
| 		object_ptr<Ui::FlatLabel>( | 		object_ptr<Ui::FlatLabel>( | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ void AddDivider(not_null<Ui::VerticalLayout*> container); | ||||||
| void AddDividerText( | void AddDividerText( | ||||||
| 	not_null<Ui::VerticalLayout*> container, | 	not_null<Ui::VerticalLayout*> container, | ||||||
| 	rpl::producer<QString> text); | 	rpl::producer<QString> text); | ||||||
|  | void AddDividerText( | ||||||
|  | 	not_null<Ui::VerticalLayout*> container, | ||||||
|  | 	rpl::producer<TextWithEntities> text); | ||||||
| not_null<Ui::FlatLabel*> AddSubsectionTitle( | not_null<Ui::FlatLabel*> AddSubsectionTitle( | ||||||
| 	not_null<Ui::VerticalLayout*> container, | 	not_null<Ui::VerticalLayout*> container, | ||||||
| 	rpl::producer<QString> text, | 	rpl::producer<QString> text, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 John Preston
						John Preston