Stars Giveaway: Create giveaway in groups and channels (#4980)
This commit is contained in:
parent
9fa6077fc7
commit
10629eb69a
@ -82,6 +82,7 @@ export interface GramJsAppConfig extends LimitsConfig {
|
||||
upload_premium_speedup_notify_period?: number;
|
||||
upload_premium_speedup_download?: number;
|
||||
upload_premium_speedup_upload?: number;
|
||||
stars_gifts_enabled?: boolean;
|
||||
}
|
||||
|
||||
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
||||
@ -163,5 +164,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
|
||||
bandwidthPremiumDownloadSpeedup: appConfig.upload_premium_speedup_download,
|
||||
channelRestrictAdsLevelMin: appConfig.channel_restrict_sponsored_level_min,
|
||||
isChannelRevenueWithdrawalEnabled: appConfig.channel_revenue_withdrawal_enabled,
|
||||
isStarsGiftsEnabled: appConfig.stars_gifts_enabled,
|
||||
};
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ function buildGiweawayFromMedia(media: GramJs.TypeMessageMedia): ApiGiveaway | u
|
||||
|
||||
function buildGiveaway(media: GramJs.MessageMediaGiveaway): ApiGiveaway | undefined {
|
||||
const {
|
||||
channels, months, quantity, untilDate, countriesIso2, onlyNewSubscribers, prizeDescription,
|
||||
channels, months, stars, quantity, untilDate, countriesIso2, onlyNewSubscribers, prizeDescription,
|
||||
} = media;
|
||||
|
||||
const channelIds = channels.map((channel) => buildApiPeerId(channel, 'channel'));
|
||||
@ -585,6 +585,7 @@ function buildGiveaway(media: GramJs.MessageMediaGiveaway): ApiGiveaway | undefi
|
||||
mediaType: 'giveaway',
|
||||
channelIds,
|
||||
months,
|
||||
stars: stars?.toJSNumber(),
|
||||
quantity,
|
||||
untilDate,
|
||||
countries: countriesIso2,
|
||||
|
||||
@ -608,6 +608,15 @@ function buildAction(
|
||||
amount = action.winnersCount;
|
||||
pluralValue = action.winnersCount;
|
||||
}
|
||||
} else if (action instanceof GramJs.MessageActionPrizeStars) {
|
||||
type = 'prizeStars';
|
||||
isUnclaimed = Boolean(action.unclaimed);
|
||||
if (action.boostPeer) {
|
||||
targetChatId = getApiChatIdFromMtpPeer(action.boostPeer);
|
||||
}
|
||||
text = 'Notification.StarsPrize';
|
||||
stars = action.stars.toJSNumber();
|
||||
transactionId = action.transactionId;
|
||||
} else if (action instanceof GramJs.MessageActionBoostApply) {
|
||||
type = 'chatBoost';
|
||||
if (action.boosts === 1) {
|
||||
|
||||
@ -6,9 +6,20 @@ import type {
|
||||
ApiBoostsStatus,
|
||||
ApiCheckedGiftCode,
|
||||
ApiGiveawayInfo,
|
||||
ApiInvoice, ApiLabeledPrice, ApiMyBoost, ApiPaymentCredentials,
|
||||
ApiPaymentForm, ApiPaymentSavedInfo, ApiPremiumGiftCodeOption, ApiPremiumPromo, ApiPremiumSubscriptionOption,
|
||||
ApiInvoice,
|
||||
ApiLabeledPrice,
|
||||
ApiMyBoost,
|
||||
ApiPaymentCredentials,
|
||||
ApiPaymentForm,
|
||||
ApiPaymentSavedInfo,
|
||||
ApiPremiumGiftCodeOption,
|
||||
ApiPremiumPromo,
|
||||
ApiPremiumSubscriptionOption,
|
||||
ApiPrepaidGiveaway,
|
||||
ApiPrepaidStarsGiveaway,
|
||||
ApiReceipt,
|
||||
ApiStarGiveawayOption,
|
||||
ApiStarsGiveawayWinnerOption,
|
||||
ApiStarsTransaction,
|
||||
ApiStarsTransactionPeer,
|
||||
ApiStarTopupOption,
|
||||
@ -20,7 +31,7 @@ import { buildApiMessageEntity } from './common';
|
||||
import { omitVirtualClassFields } from './helpers';
|
||||
import { buildApiDocument, buildApiWebDocument, buildMessageMediaContent } from './messageContent';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from './peers';
|
||||
import { buildPrepaidGiveaway, buildStatisticsPercentage } from './statistics';
|
||||
import { buildStatisticsPercentage } from './statistics';
|
||||
|
||||
export function buildShippingOptions(shippingOptions: GramJs.ShippingOption[] | undefined) {
|
||||
if (!shippingOptions) {
|
||||
@ -265,19 +276,46 @@ export function buildApiPaymentCredentials(credentials: GramJs.PaymentSavedCrede
|
||||
return credentials.map(({ id, title }) => ({ id, title }));
|
||||
}
|
||||
|
||||
export function buildPrepaidGiveaway(
|
||||
interaction: GramJs.TypePrepaidGiveaway,
|
||||
): ApiPrepaidGiveaway | ApiPrepaidStarsGiveaway {
|
||||
if (interaction instanceof GramJs.PrepaidGiveaway) {
|
||||
return {
|
||||
type: 'giveaway',
|
||||
id: interaction.id.toString(),
|
||||
date: interaction.date,
|
||||
months: interaction.months,
|
||||
quantity: interaction.quantity,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'starsGiveaway',
|
||||
id: interaction.id.toString(),
|
||||
stars: interaction.stars.toJSNumber(),
|
||||
quantity: interaction.quantity,
|
||||
boosts: interaction.boosts,
|
||||
date: interaction.date,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiBoostsStatus(boostStatus: GramJs.premium.BoostsStatus): ApiBoostsStatus {
|
||||
const {
|
||||
level, boostUrl, boosts, myBoost, currentLevelBoosts, nextLevelBoosts, premiumAudience, prepaidGiveaways,
|
||||
level, boostUrl, boosts,
|
||||
giftBoosts, myBoost, currentLevelBoosts, nextLevelBoosts,
|
||||
premiumAudience, prepaidGiveaways,
|
||||
} = boostStatus;
|
||||
|
||||
return {
|
||||
level,
|
||||
currentLevelBoosts,
|
||||
boosts,
|
||||
hasMyBoost: Boolean(myBoost),
|
||||
boostUrl,
|
||||
giftBoosts,
|
||||
nextLevelBoosts,
|
||||
...(premiumAudience && { premiumSubscribers: buildStatisticsPercentage(premiumAudience) }),
|
||||
...(prepaidGiveaways && { prepaidGiveaways: prepaidGiveaways.map(buildPrepaidGiveaway) }),
|
||||
...(prepaidGiveaways && { prepaidGiveaways: prepaidGiveaways.map((m) => buildPrepaidGiveaway(m)) }),
|
||||
};
|
||||
}
|
||||
|
||||
@ -288,6 +326,7 @@ export function buildApiBoost(boost: GramJs.Boost): ApiBoost {
|
||||
expires,
|
||||
giveaway,
|
||||
gift,
|
||||
stars,
|
||||
} = boost;
|
||||
|
||||
return {
|
||||
@ -296,6 +335,7 @@ export function buildApiBoost(boost: GramJs.Boost): ApiBoost {
|
||||
expires,
|
||||
isFromGiveaway: giveaway,
|
||||
isGift: gift,
|
||||
stars: stars?.toJSNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -342,6 +382,7 @@ export function buildApiGiveawayInfo(info: GramJs.payments.TypeGiveawayInfo): Ap
|
||||
refunded,
|
||||
startDate,
|
||||
winnersCount,
|
||||
starsPrize,
|
||||
} = info;
|
||||
|
||||
return {
|
||||
@ -353,6 +394,7 @@ export function buildApiGiveawayInfo(info: GramJs.payments.TypeGiveawayInfo): Ap
|
||||
giftCodeSlug,
|
||||
isRefunded: refunded,
|
||||
isWinner: winner,
|
||||
starsPrize: starsPrize?.toJSNumber(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -399,6 +441,38 @@ export function buildApiStarsGiftOptions(option: GramJs.StarsGiftOption): ApiSta
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiStarsGiveawayWinnersOption(
|
||||
option: GramJs.StarsGiveawayWinnersOption,
|
||||
): ApiStarsGiveawayWinnerOption {
|
||||
const {
|
||||
default: isDefault, users, perUserStars,
|
||||
} = option;
|
||||
|
||||
return {
|
||||
isDefault,
|
||||
users,
|
||||
perUserStars: perUserStars.toJSNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiStarsGiveawayOptions(option: GramJs.StarsGiveawayOption): ApiStarGiveawayOption {
|
||||
const {
|
||||
extended, default: isDefault, stars, yearlyBoosts, amount, winners, currency,
|
||||
} = option;
|
||||
|
||||
const winnerList = winners?.map((m) => buildApiStarsGiveawayWinnersOption(m)).filter(Boolean);
|
||||
|
||||
return {
|
||||
isExtended: extended,
|
||||
isDefault,
|
||||
yearlyBoosts,
|
||||
stars: stars.toJSNumber(),
|
||||
amount: amount.toJSNumber(),
|
||||
currency,
|
||||
winners: winnerList,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiStarsTransactionPeer(peer: GramJs.TypeStarsTransactionPeer): ApiStarsTransactionPeer {
|
||||
if (peer instanceof GramJs.StarsTransactionPeerAppStore) {
|
||||
return { type: 'appStore' };
|
||||
|
||||
@ -8,7 +8,7 @@ import type {
|
||||
ApiPostStatistics,
|
||||
ApiStoryPublicForward,
|
||||
ChannelMonetizationBalances,
|
||||
PrepaidGiveaway, StatisticsGraph,
|
||||
StatisticsGraph,
|
||||
StatisticsMessageInteractionCounter,
|
||||
StatisticsOverviewItem,
|
||||
StatisticsOverviewPercentage,
|
||||
@ -233,15 +233,6 @@ export function buildStatisticsPercentage(data: GramJs.StatsPercentValue): Stati
|
||||
};
|
||||
}
|
||||
|
||||
export function buildPrepaidGiveaway(prepaidGiveaway: GramJs.PrepaidGiveaway): PrepaidGiveaway {
|
||||
return {
|
||||
id: prepaidGiveaway.id.toString(),
|
||||
date: prepaidGiveaway.date,
|
||||
months: prepaidGiveaway.months,
|
||||
quantity: prepaidGiveaway.quantity,
|
||||
};
|
||||
}
|
||||
|
||||
function getOverviewPeriod(data: GramJs.StatsDateRangeDays): StatisticsOverviewPeriod {
|
||||
return {
|
||||
maxDate: data.maxDate,
|
||||
|
||||
@ -568,6 +568,23 @@ GramJs.TypeInputStorePaymentPurpose {
|
||||
|
||||
const randomId = generateRandomBigInt();
|
||||
|
||||
if (purpose.type === 'starsgiveaway') {
|
||||
return new GramJs.InputStorePaymentStarsGiveaway({
|
||||
boostPeer: buildInputPeer(purpose.chat.id, purpose.chat.accessHash),
|
||||
additionalPeers: purpose.additionalChannels?.map((chat) => buildInputPeer(chat.id, chat.accessHash)),
|
||||
stars: BigInt(purpose.stars!),
|
||||
countriesIso2: purpose.countries,
|
||||
prizeDescription: purpose.prizeDescription,
|
||||
onlyNewSubscribers: purpose.isOnlyForNewSubscribers || undefined,
|
||||
winnersAreVisible: purpose.areWinnersVisible || undefined,
|
||||
untilDate: purpose.untilDate,
|
||||
currency: purpose.currency,
|
||||
amount: BigInt(purpose.amount),
|
||||
users: purpose.users,
|
||||
randomId,
|
||||
});
|
||||
}
|
||||
|
||||
return new GramJs.InputStorePaymentPremiumGiveaway({
|
||||
boostPeer: buildInputPeer(purpose.chat.id, purpose.chat.accessHash),
|
||||
additionalPeers: purpose.additionalChannels?.map((chat) => buildInputPeer(chat.id, chat.accessHash)),
|
||||
@ -613,6 +630,13 @@ export function buildInputInvoice(invoice: ApiRequestInputInvoice) {
|
||||
});
|
||||
}
|
||||
|
||||
case 'starsgiveaway': {
|
||||
const purpose = buildInputStorePaymentPurpose(invoice.purpose);
|
||||
return new GramJs.InputInvoiceStars({
|
||||
purpose,
|
||||
});
|
||||
}
|
||||
|
||||
case 'giveaway':
|
||||
default: {
|
||||
const purpose = buildInputStorePaymentPurpose(invoice.purpose);
|
||||
|
||||
@ -17,7 +17,9 @@ import {
|
||||
buildApiPaymentForm,
|
||||
buildApiPremiumGiftCodeOption,
|
||||
buildApiPremiumPromo,
|
||||
buildApiReceipt, buildApiStarsGiftOptions,
|
||||
buildApiReceipt,
|
||||
buildApiStarsGiftOptions,
|
||||
buildApiStarsGiveawayOptions,
|
||||
buildApiStarsTransaction,
|
||||
buildApiStarTopupOption,
|
||||
buildShippingOptions,
|
||||
@ -376,6 +378,16 @@ export async function getStarsGiftOptions({
|
||||
return result.map(buildApiStarsGiftOptions);
|
||||
}
|
||||
|
||||
export async function fetchStarsGiveawayOptions() {
|
||||
const result = await invokeRequest(new GramJs.payments.GetStarsGiveawayOptions());
|
||||
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return result.map(buildApiStarsGiveawayOptions);
|
||||
}
|
||||
|
||||
export function launchPrepaidGiveaway({
|
||||
chat,
|
||||
giveawayId,
|
||||
|
||||
@ -248,8 +248,23 @@ export type ApiInputInvoiceStarsGift = {
|
||||
amount: number;
|
||||
};
|
||||
|
||||
export type ApiInputInvoiceStarsGiveaway = {
|
||||
type: 'starsgiveaway';
|
||||
chatId: string;
|
||||
additionalChannelIds?: string[];
|
||||
isOnlyForNewSubscribers?: boolean;
|
||||
areWinnersVisible?: boolean;
|
||||
prizeDescription?: string;
|
||||
countries?: string[];
|
||||
untilDate: number;
|
||||
currency: string;
|
||||
amount: number;
|
||||
stars: number;
|
||||
users: number;
|
||||
};
|
||||
|
||||
export type ApiInputInvoice = ApiInputInvoiceMessage | ApiInputInvoiceSlug | ApiInputInvoiceGiveaway
|
||||
| ApiInputInvoiceGiftCode | ApiInputInvoiceStarsGift | ApiInputInvoiceStars;
|
||||
| ApiInputInvoiceGiftCode | ApiInputInvoiceStarsGift | ApiInputInvoiceStars | ApiInputInvoiceStarsGiveaway;
|
||||
|
||||
/* Used for Invoice request */
|
||||
export type ApiRequestInputInvoiceMessage = {
|
||||
@ -274,8 +289,13 @@ export type ApiRequestInputInvoiceStars = {
|
||||
purpose: ApiInputStorePaymentPurpose;
|
||||
};
|
||||
|
||||
export type ApiRequestInputInvoiceStarsGiveaway = {
|
||||
type: 'starsgiveaway';
|
||||
purpose: ApiInputStorePaymentPurpose;
|
||||
};
|
||||
|
||||
export type ApiRequestInputInvoice = ApiRequestInputInvoiceMessage | ApiRequestInputInvoiceSlug
|
||||
| ApiRequestInputInvoiceGiveaway | ApiRequestInputInvoiceStars;
|
||||
| ApiRequestInputInvoiceGiveaway | ApiRequestInputInvoiceStars | ApiRequestInputInvoiceStarsGiveaway;
|
||||
|
||||
export interface ApiInvoice {
|
||||
mediaType: 'invoice';
|
||||
@ -351,7 +371,8 @@ export type ApiGame = {
|
||||
export type ApiGiveaway = {
|
||||
mediaType: 'giveaway';
|
||||
quantity: number;
|
||||
months: number;
|
||||
months?: number;
|
||||
stars?: number;
|
||||
untilDate: number;
|
||||
isOnlyForNewSubscribers?: true;
|
||||
countries?: string[];
|
||||
@ -361,7 +382,8 @@ export type ApiGiveaway = {
|
||||
|
||||
export type ApiGiveawayResults = {
|
||||
mediaType: 'giveawayResults';
|
||||
months: number;
|
||||
months?: number;
|
||||
stars?: number;
|
||||
untilDate: number;
|
||||
isRefunded?: true;
|
||||
isOnlyForNewSubscribers?: true;
|
||||
@ -400,6 +422,7 @@ export interface ApiAction {
|
||||
| 'giftStars'
|
||||
| 'giftPremium'
|
||||
| 'giftCode'
|
||||
| 'prizeStars'
|
||||
| 'other';
|
||||
photo?: ApiPhoto;
|
||||
amount?: number;
|
||||
|
||||
@ -211,6 +211,7 @@ export interface ApiAppConfig {
|
||||
bandwidthPremiumDownloadSpeedup?: number;
|
||||
channelRestrictAdsLevelMin?: number;
|
||||
isChannelRevenueWithdrawalEnabled?: boolean;
|
||||
isStarsGiftsEnabled?: boolean;
|
||||
}
|
||||
|
||||
export interface ApiConfig {
|
||||
|
||||
@ -5,7 +5,7 @@ import type { ApiChat } from './chats';
|
||||
import type {
|
||||
ApiDocument, ApiMessageEntity, ApiPaymentCredentials, BoughtPaidMedia,
|
||||
} from './messages';
|
||||
import type { PrepaidGiveaway, StatisticsOverviewPercentage } from './statistics';
|
||||
import type { StatisticsOverviewPercentage } from './statistics';
|
||||
import type { ApiUser } from './users';
|
||||
|
||||
export interface ApiShippingAddress {
|
||||
@ -149,8 +149,23 @@ export type ApiInputStorePaymentStarsGift = {
|
||||
amount: number;
|
||||
};
|
||||
|
||||
export type ApiInputStorePaymentStarsGiveaway = {
|
||||
type: 'starsgiveaway';
|
||||
isOnlyForNewSubscribers?: boolean;
|
||||
areWinnersVisible?: boolean;
|
||||
chat: ApiChat;
|
||||
additionalChannels?: ApiChat[];
|
||||
stars?: number;
|
||||
countries?: string[];
|
||||
prizeDescription?: string;
|
||||
untilDate: number;
|
||||
currency: string;
|
||||
amount: number;
|
||||
users: number;
|
||||
};
|
||||
|
||||
export type ApiInputStorePaymentPurpose = ApiInputStorePaymentGiveaway | ApiInputStorePaymentGiftcode |
|
||||
ApiInputStorePaymentStarsTopup | ApiInputStorePaymentStarsGift;
|
||||
ApiInputStorePaymentStarsTopup | ApiInputStorePaymentStarsGift | ApiInputStorePaymentStarsGiveaway;
|
||||
|
||||
export interface ApiPremiumGiftCodeOption {
|
||||
users: number;
|
||||
@ -159,6 +174,25 @@ export interface ApiPremiumGiftCodeOption {
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface ApiPrepaidGiveaway {
|
||||
type: 'giveaway';
|
||||
id: string;
|
||||
months: number;
|
||||
quantity: number;
|
||||
date: number;
|
||||
}
|
||||
|
||||
export type ApiPrepaidStarsGiveaway = {
|
||||
type: 'starsGiveaway';
|
||||
id: string;
|
||||
stars: number;
|
||||
quantity: number;
|
||||
boosts: number;
|
||||
date: number;
|
||||
};
|
||||
|
||||
export type ApiTypePrepaidGiveaway = ApiPrepaidGiveaway | ApiPrepaidStarsGiveaway;
|
||||
|
||||
export type ApiBoostsStatus = {
|
||||
level: number;
|
||||
currentLevelBoosts: number;
|
||||
@ -166,8 +200,9 @@ export type ApiBoostsStatus = {
|
||||
nextLevelBoosts?: number;
|
||||
hasMyBoost?: boolean;
|
||||
boostUrl: string;
|
||||
giftBoosts?: number;
|
||||
premiumSubscribers?: StatisticsOverviewPercentage;
|
||||
prepaidGiveaways?: PrepaidGiveaway[];
|
||||
prepaidGiveaways?: ApiTypePrepaidGiveaway[];
|
||||
};
|
||||
|
||||
export type ApiMyBoost = {
|
||||
@ -184,6 +219,7 @@ export type ApiBoost = {
|
||||
expires: number;
|
||||
isFromGiveaway?: boolean;
|
||||
isGift?: boolean;
|
||||
stars?: number;
|
||||
};
|
||||
|
||||
export type ApiGiveawayInfoActive = {
|
||||
@ -201,10 +237,11 @@ export type ApiGiveawayInfoResults = {
|
||||
isWinner?: true;
|
||||
isRefunded?: true;
|
||||
startDate: number;
|
||||
starsPrize?: number;
|
||||
finishDate: number;
|
||||
giftCodeSlug?: string;
|
||||
winnersCount: number;
|
||||
activatedCount: number;
|
||||
activatedCount?: number;
|
||||
};
|
||||
|
||||
export type ApiGiveawayInfo = ApiGiveawayInfoActive | ApiGiveawayInfoResults;
|
||||
@ -219,13 +256,6 @@ export type ApiCheckedGiftCode = {
|
||||
usedAt?: number;
|
||||
};
|
||||
|
||||
export interface ApiPrepaidGiveaway {
|
||||
id: string;
|
||||
months: number;
|
||||
quantity: number;
|
||||
date: number;
|
||||
}
|
||||
|
||||
export interface ApiStarsTransactionPeerUnsupported {
|
||||
type: 'unsupported';
|
||||
}
|
||||
@ -271,6 +301,7 @@ export interface ApiStarsTransaction {
|
||||
stars: number;
|
||||
isRefund?: true;
|
||||
isGift?: true;
|
||||
isPrizeStars?: true;
|
||||
isMyGift?: true; // Used only for outgoing star gift messages
|
||||
hasFailed?: true;
|
||||
isPending?: true;
|
||||
@ -287,3 +318,19 @@ export interface ApiStarTopupOption {
|
||||
currency: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface ApiStarsGiveawayWinnerOption {
|
||||
isDefault?: true;
|
||||
users: number;
|
||||
perUserStars: number;
|
||||
}
|
||||
|
||||
export interface ApiStarGiveawayOption {
|
||||
isExtended?: true;
|
||||
isDefault?: true;
|
||||
stars: number;
|
||||
yearlyBoosts: number;
|
||||
currency: string;
|
||||
amount: number;
|
||||
winners: ApiStarsGiveawayWinnerOption[];
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { ApiChat } from './chats';
|
||||
import type { ApiTypePrepaidGiveaway } from './payments';
|
||||
|
||||
export interface ApiChannelStatistics {
|
||||
growthGraph?: StatisticsGraph | string;
|
||||
@ -61,7 +62,7 @@ export interface ApiBoostStatistics {
|
||||
boosts: number;
|
||||
premiumSubscribers: StatisticsOverviewPercentage;
|
||||
remainingBoosts: number;
|
||||
prepaidGiveaways: PrepaidGiveaway[];
|
||||
prepaidGiveaways: ApiTypePrepaidGiveaway[];
|
||||
}
|
||||
|
||||
export interface ApiMessagePublicForward {
|
||||
@ -115,13 +116,6 @@ export interface StatisticsOverviewPercentage {
|
||||
percentage: string;
|
||||
}
|
||||
|
||||
export interface PrepaidGiveaway {
|
||||
id: string;
|
||||
months: number;
|
||||
quantity: number;
|
||||
date: number;
|
||||
}
|
||||
|
||||
export interface StatisticsOverviewPeriod {
|
||||
maxDate: number;
|
||||
minDate: number;
|
||||
|
||||
@ -1283,3 +1283,4 @@
|
||||
"CreditsBoxHistoryEntryGiftOutAbout" = "With Stars, {user} will be able to unlock content and services on Telegram. {link}"
|
||||
"CreditsBoxOutAbout" = "Review the {link} for Stars."
|
||||
"GiftStarsOutgoing" = "With Stars, {user} will be able to unlock content and services on Telegram."
|
||||
"PrizeCredits" = "Your prize is {count} Stars."
|
||||
|
||||
24
src/assets/premium/GiftStar.svg
Normal file
24
src/assets/premium/GiftStar.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 504 KiB |
@ -80,7 +80,7 @@ const FullNameTitle: FC<OwnProps> = ({
|
||||
|
||||
const specialTitle = useMemo(() => {
|
||||
if (customPeer) {
|
||||
return lang(customPeer.titleKey);
|
||||
return lang(customPeer.titleKey, customPeer.titleValue, 'i');
|
||||
}
|
||||
|
||||
if (isSavedMessages) {
|
||||
|
||||
@ -91,6 +91,11 @@ export function renderActionMessageText(
|
||||
.replace('un2', '%action_origin%')
|
||||
.replace(/\*\*/g, '');
|
||||
}
|
||||
if (translationKey === 'BoostingReceivedPrizeFrom') {
|
||||
unprocessed = unprocessed
|
||||
.replace('**%s**', '%target_chat%')
|
||||
.replace(/\*\*/g, '');
|
||||
}
|
||||
let processed: TextPart[];
|
||||
|
||||
if (unprocessed.includes('%star_target_user%')) {
|
||||
|
||||
@ -569,10 +569,10 @@ const Main = ({
|
||||
/>
|
||||
<AttachBotRecipientPicker requestedAttachBotInChat={requestedAttachBotInChat} />
|
||||
<MessageListHistoryHandler />
|
||||
{isPremiumModalOpen && <PremiumMainModal isOpen={isPremiumModalOpen} />}
|
||||
{isGiveawayModalOpen && <GiveawayModal isOpen={isGiveawayModalOpen} />}
|
||||
{isPremiumGiftingPickerModal && <PremiumGiftingPickerModal isOpen={isPremiumGiftingPickerModal} />}
|
||||
{isStarsGiftingPickerModal && <StarsGiftingPickerModal isOpen={isStarsGiftingPickerModal} />}
|
||||
<PremiumMainModal isOpen={isPremiumModalOpen} />
|
||||
<GiveawayModal isOpen={isGiveawayModalOpen} />
|
||||
<PremiumGiftingPickerModal isOpen={isPremiumGiftingPickerModal} />
|
||||
<StarsGiftingPickerModal isOpen={isStarsGiftingPickerModal} />
|
||||
<PremiumLimitReachedModal limit={limitReached} />
|
||||
<PaymentModal isOpen={isPaymentModalOpen} onClose={closePaymentModal} />
|
||||
<ReceiptModal isOpen={isReceiptModalOpen} onClose={clearReceipt} />
|
||||
|
||||
@ -114,6 +114,7 @@
|
||||
|
||||
.options {
|
||||
width: 100%;
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
|
||||
.giveawayTitle {
|
||||
@ -133,6 +134,10 @@
|
||||
@include mixins.adapt-margin-to-scrollbar(1rem);
|
||||
}
|
||||
|
||||
.starSubscription {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.subscriptionOption {
|
||||
margin-bottom: 0;
|
||||
padding-inline: 3.5rem 1rem;
|
||||
@ -142,10 +147,10 @@
|
||||
.status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: 0.8125rem;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 0 0.375rem 0 1.125rem;
|
||||
padding: 0 0.375rem 0 1rem;
|
||||
margin-bottom: 1.3125rem;
|
||||
}
|
||||
|
||||
@ -263,7 +268,8 @@
|
||||
}
|
||||
|
||||
.addChannel {
|
||||
margin-inline-start: initial !important;
|
||||
margin-inline-end: 1.375rem !important;
|
||||
margin-inline-start: 0.3125rem !important;
|
||||
}
|
||||
|
||||
.removeChannel {
|
||||
@ -272,6 +278,10 @@
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.starOptions {
|
||||
padding: 0.8125rem;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.root :global(.modal-dialog) {
|
||||
width: 100%;
|
||||
|
||||
@ -6,7 +6,13 @@ import React, {
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type {
|
||||
ApiCountry, ApiPremiumGiftCodeOption, ApiPrepaidGiveaway, ApiUser,
|
||||
ApiCountry,
|
||||
ApiPremiumGiftCodeOption,
|
||||
ApiPrepaidGiveaway,
|
||||
ApiPrepaidStarsGiveaway,
|
||||
ApiStarGiveawayOption,
|
||||
ApiTypePrepaidGiveaway,
|
||||
ApiUser,
|
||||
} from '../../../api/types';
|
||||
|
||||
import {
|
||||
@ -22,6 +28,7 @@ import {
|
||||
} from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatDateTimeToString } from '../../../util/dates/dateFormat';
|
||||
import { unique } from '../../../util/iteratees';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
@ -32,6 +39,7 @@ import CalendarModal from '../../common/CalendarModal';
|
||||
import CountryPickerModal from '../../common/CountryPickerModal';
|
||||
import GroupChatInfo from '../../common/GroupChatInfo';
|
||||
import Icon from '../../common/icons/Icon';
|
||||
import StarTopupOptionList from '../../modals/stars/StarTopupOptionList';
|
||||
import Button from '../../ui/Button';
|
||||
import ConfirmDialog from '../../ui/ConfirmDialog';
|
||||
import InputText from '../../ui/InputText';
|
||||
@ -51,7 +59,7 @@ import styles from './GiveawayModal.module.scss';
|
||||
import GiftBlueRound from '../../../assets/premium/GiftBlueRound.svg';
|
||||
import GiftGreenRound from '../../../assets/premium/GiftGreenRound.svg';
|
||||
import GiftRedRound from '../../../assets/premium/GiftRedRound.svg';
|
||||
import GiveawayUsersRound from '../../../assets/premium/GiveawayUsersRound.svg';
|
||||
import GiftStar from '../../../assets/premium/GiftStar.svg';
|
||||
import PremiumLogo from '../../../assets/premium/PremiumLogo.svg';
|
||||
|
||||
export type OwnProps = {
|
||||
@ -69,13 +77,15 @@ type StateProps = {
|
||||
giveawayBoostPerPremiumLimit?: number;
|
||||
userSelectionLimit?: number;
|
||||
countryList: ApiCountry[];
|
||||
prepaidGiveaway?: ApiPrepaidGiveaway;
|
||||
prepaidGiveaway?: ApiTypePrepaidGiveaway;
|
||||
countrySelectionLimit: number | undefined;
|
||||
isChannel?: boolean;
|
||||
isStarsGiftsEnabled?: boolean;
|
||||
starsGiftOptions?: ApiStarGiveawayOption[] | undefined;
|
||||
};
|
||||
|
||||
type GiveawayAction = 'createRandomlyUsers' | 'createSpecificUsers';
|
||||
type ApiGiveawayType = 'random_users' | 'specific_users';
|
||||
type GiveawayAction = 'createPremiumGiveaway' | 'createStarsGiveaway';
|
||||
type ApiGiveawayType = 'premium_giveaway' | 'stars_giveaway';
|
||||
type SubscribersType = 'all' | 'new';
|
||||
|
||||
interface TypeOption {
|
||||
@ -110,12 +120,14 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
prepaidGiveaway,
|
||||
countrySelectionLimit = GIVEAWAY_MAX_ADDITIONAL_COUNTRIES,
|
||||
userSelectionLimit = GIVEAWAY_MAX_ADDITIONAL_USERS,
|
||||
isStarsGiftsEnabled,
|
||||
starsGiftOptions,
|
||||
}) => {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const dialogRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
closeGiveawayModal, openInvoice, openPremiumModal,
|
||||
launchPrepaidGiveaway,
|
||||
launchPrepaidGiveaway, launchPrepaidStarsGiveaway,
|
||||
} = getActions();
|
||||
|
||||
const lang = useOldLang();
|
||||
@ -126,28 +138,33 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
const [isChannelPickerModalOpen, openChannelPickerModal, closeChannelPickerModal] = useFlag();
|
||||
|
||||
const TYPE_OPTIONS: TypeOption[] = [{
|
||||
name: 'BoostingCreateGiveaway',
|
||||
name: 'Premium.Title',
|
||||
text: 'BoostingWinnersRandomly',
|
||||
value: 'random_users',
|
||||
value: 'premium_giveaway',
|
||||
img: GiftBlueRound,
|
||||
actions: 'createRandomlyUsers',
|
||||
isLink: false,
|
||||
}, {
|
||||
name: 'BoostingAwardSpecificUsers',
|
||||
text: 'BoostingSelectRecipients',
|
||||
value: 'specific_users',
|
||||
img: GiveawayUsersRound,
|
||||
actions: 'createSpecificUsers',
|
||||
actions: 'createPremiumGiveaway',
|
||||
isLink: true,
|
||||
onClickAction: () => {
|
||||
openUserPickerModal();
|
||||
},
|
||||
}];
|
||||
|
||||
if (isStarsGiftsEnabled) {
|
||||
TYPE_OPTIONS.push({
|
||||
name: 'TelegramStars',
|
||||
text: 'BoostingWinnersRandomly',
|
||||
value: 'stars_giveaway',
|
||||
img: GiftStar,
|
||||
actions: 'createStarsGiveaway',
|
||||
isLink: false,
|
||||
});
|
||||
}
|
||||
|
||||
const [customExpireDate, setCustomExpireDate] = useState<number>(Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE);
|
||||
const [isHeaderHidden, setHeaderHidden] = useState(true);
|
||||
const [selectedRandomUserCount, setSelectedRandomUserCount] = useState<number>(DEFAULT_BOOST_COUNT);
|
||||
const [selectedGiveawayOption, setGiveawayOption] = useState<ApiGiveawayType>(TYPE_OPTIONS[0].value);
|
||||
const [selectedStarOption, setSelectedStarOption] = useState<ApiStarGiveawayOption | undefined>();
|
||||
const [selectedSubscriberOption, setSelectedSubscriberOption] = useState<SubscribersType>('all');
|
||||
const [selectedMonthOption, setSelectedMonthOption] = useState<number | undefined>();
|
||||
const [selectedUserIds, setSelectedUserIds] = useState<string[]>([]);
|
||||
@ -157,10 +174,16 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
const [shouldShowPrizes, setShouldShowPrizes] = useState<boolean>(false);
|
||||
const [prizeDescription, setPrizeDescription] = useState<string | undefined>(undefined);
|
||||
const [dataPrepaidGiveaway, setDataPrepaidGiveaway] = useState<ApiPrepaidGiveaway | undefined>(undefined);
|
||||
const [
|
||||
dataStarsPrepaidGiveaway, setDataStarsPrepaidGiveaway,
|
||||
] = useState<ApiPrepaidStarsGiveaway | undefined>(undefined);
|
||||
|
||||
const isRandomUsers = selectedGiveawayOption === 'random_users';
|
||||
const selectedUserCount = isRandomUsers ? selectedRandomUserCount : selectedUserIds.length;
|
||||
const isPremiumGiveaway = selectedGiveawayOption === 'premium_giveaway';
|
||||
const isStarsGiveaway = selectedGiveawayOption === 'stars_giveaway';
|
||||
const selectedUserCount = isPremiumGiveaway
|
||||
&& !selectedUserIds.length ? selectedRandomUserCount : selectedUserIds.length;
|
||||
const boostQuantity = selectedUserCount * giveawayBoostPerPremiumLimit;
|
||||
const boostStarsQuantity = selectedStarOption?.yearlyBoosts;
|
||||
|
||||
const SUBSCRIBER_OPTIONS = useMemo(() => [
|
||||
{
|
||||
@ -180,44 +203,65 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
], [isChannel, lang, selectedCountryIds]);
|
||||
|
||||
const monthQuantity = lang('Months', selectedMonthOption);
|
||||
const isStarsPrepaidGiveaway = prepaidGiveaway?.type === 'starsGiveaway';
|
||||
const isPremiumPrepaidGiveaway = prepaidGiveaway?.type === 'giveaway';
|
||||
|
||||
const selectedGift = useMemo(() => {
|
||||
return gifts!.find((gift) => gift.months === selectedMonthOption && gift.users === selectedUserCount);
|
||||
return gifts?.find((gift) => gift.months === selectedMonthOption && gift.users === selectedUserCount);
|
||||
}, [gifts, selectedMonthOption, selectedUserCount]);
|
||||
|
||||
const selectedStarsGift = useMemo(() => {
|
||||
return starsGiftOptions?.find((gift) => {
|
||||
return isStarsPrepaidGiveaway && gift.stars === (dataStarsPrepaidGiveaway?.stars);
|
||||
});
|
||||
}, [dataStarsPrepaidGiveaway, starsGiftOptions, isStarsPrepaidGiveaway]);
|
||||
|
||||
const filteredGifts = useMemo(() => {
|
||||
return gifts?.filter((gift) => gift.users === selectedUserCount);
|
||||
}, [gifts, selectedUserCount]);
|
||||
|
||||
const fullMonthlyAmount = useMemo(() => {
|
||||
if (!filteredGifts?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const basicGift = filteredGifts.reduce((acc, gift) => {
|
||||
const basicGift = filteredGifts?.reduce((acc, gift) => {
|
||||
return gift.amount < acc.amount ? gift : acc;
|
||||
});
|
||||
}, filteredGifts[0]);
|
||||
|
||||
return Math.floor(basicGift.amount / basicGift.months);
|
||||
return basicGift && Math.floor(basicGift.amount / basicGift.months);
|
||||
}, [filteredGifts]);
|
||||
|
||||
const userCountOptions = useMemo(() => {
|
||||
const uniqueUserCounts = new Set(gifts?.map((gift) => gift.users));
|
||||
return Array.from(uniqueUserCounts).sort((a, b) => a - b);
|
||||
return unique((gifts?.map((winner) => winner.users) || [])).sort((a, b) => a - b);
|
||||
}, [gifts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setSelectedMonthOption(prepaidGiveaway ? prepaidGiveaway.months : gifts?.[0].months);
|
||||
}
|
||||
}, [gifts, isOpen, prepaidGiveaway]);
|
||||
const winnerCountOptions = useMemo(() => {
|
||||
return unique((selectedStarOption?.winners?.map((winner) => winner.users) || [])).sort((a, b) => a - b);
|
||||
}, [selectedStarOption]);
|
||||
|
||||
useEffect(() => {
|
||||
if (prepaidGiveaway) {
|
||||
if (isOpen && gifts?.length && !isStarsPrepaidGiveaway) {
|
||||
setSelectedMonthOption(gifts?.[0].months);
|
||||
}
|
||||
}, [isOpen, gifts, isStarsPrepaidGiveaway]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && starsGiftOptions?.length && !isPremiumPrepaidGiveaway) {
|
||||
setSelectedStarOption(starsGiftOptions?.[0]);
|
||||
}
|
||||
}, [isOpen, starsGiftOptions, isPremiumPrepaidGiveaway]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && isStarsPrepaidGiveaway) {
|
||||
setSelectedRandomUserCount(prepaidGiveaway.quantity);
|
||||
setDataStarsPrepaidGiveaway(prepaidGiveaway);
|
||||
}
|
||||
}, [isOpen, isStarsPrepaidGiveaway, prepaidGiveaway]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && isPremiumPrepaidGiveaway) {
|
||||
setSelectedRandomUserCount(prepaidGiveaway.quantity);
|
||||
setDataPrepaidGiveaway(prepaidGiveaway);
|
||||
setSelectedMonthOption(prepaidGiveaway.months);
|
||||
}
|
||||
}, [prepaidGiveaway]);
|
||||
}, [isOpen, isPremiumPrepaidGiveaway, prepaidGiveaway]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedMemberList) {
|
||||
@ -235,10 +279,44 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
openPremiumModal();
|
||||
});
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
setDataStarsPrepaidGiveaway(undefined);
|
||||
setDataPrepaidGiveaway(undefined);
|
||||
setSelectedStarOption(undefined);
|
||||
setSelectedMonthOption(undefined);
|
||||
setSelectedRandomUserCount(DEFAULT_BOOST_COUNT);
|
||||
closeGiveawayModal();
|
||||
});
|
||||
|
||||
const handleClick = useLastCallback(() => {
|
||||
if (isRandomUsers) {
|
||||
if (isPremiumGiveaway) {
|
||||
if (selectedUserIds?.length) {
|
||||
openInvoice({
|
||||
type: 'giftcode',
|
||||
boostChannelId: chatId!,
|
||||
userIds: selectedUserIds,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
option: selectedGift!,
|
||||
});
|
||||
} else {
|
||||
openInvoice({
|
||||
type: 'giveaway',
|
||||
chatId: chatId!,
|
||||
additionalChannelIds: selectedChannelIds,
|
||||
isOnlyForNewSubscribers: selectedSubscriberOption === 'new',
|
||||
countries: selectedCountryIds,
|
||||
areWinnersVisible: shouldShowWinners,
|
||||
prizeDescription,
|
||||
untilDate: customExpireDate / 1000,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
option: selectedGift!,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
openInvoice({
|
||||
type: 'giveaway',
|
||||
type: 'starsgiveaway',
|
||||
chatId: chatId!,
|
||||
additionalChannelIds: selectedChannelIds,
|
||||
isOnlyForNewSubscribers: selectedSubscriberOption === 'new',
|
||||
@ -246,47 +324,61 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
areWinnersVisible: shouldShowWinners,
|
||||
prizeDescription,
|
||||
untilDate: customExpireDate / 1000,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
option: selectedGift!,
|
||||
});
|
||||
} else {
|
||||
openInvoice({
|
||||
type: 'giftcode',
|
||||
boostChannelId: chatId!,
|
||||
userIds: selectedUserIds,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
option: selectedGift!,
|
||||
currency: selectedStarOption!.currency,
|
||||
amount: selectedStarOption!.amount,
|
||||
stars: selectedStarOption!.stars,
|
||||
users: selectedRandomUserCount,
|
||||
});
|
||||
}
|
||||
|
||||
closeGiveawayModal();
|
||||
handleClose();
|
||||
});
|
||||
|
||||
const confirmLaunchPrepaidGiveaway = useLastCallback(() => {
|
||||
launchPrepaidGiveaway({
|
||||
chatId: chatId!,
|
||||
giveawayId: dataPrepaidGiveaway!.id,
|
||||
paymentPurpose: {
|
||||
additionalChannelIds: selectedChannelIds,
|
||||
countries: selectedCountryIds,
|
||||
prizeDescription,
|
||||
areWinnersVisible: shouldShowWinners,
|
||||
untilDate: customExpireDate / 1000,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
},
|
||||
});
|
||||
if (isStarsPrepaidGiveaway) {
|
||||
launchPrepaidStarsGiveaway({
|
||||
chatId: chatId!,
|
||||
giveawayId: dataStarsPrepaidGiveaway!.id,
|
||||
paymentPurpose: {
|
||||
additionalChannelIds: selectedChannelIds,
|
||||
countries: selectedCountryIds,
|
||||
prizeDescription,
|
||||
areWinnersVisible: shouldShowWinners,
|
||||
untilDate: customExpireDate / 1000,
|
||||
stars: dataStarsPrepaidGiveaway!.stars,
|
||||
currency: selectedStarsGift!.currency,
|
||||
amount: selectedStarsGift!.amount,
|
||||
users: dataStarsPrepaidGiveaway!.quantity,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
launchPrepaidGiveaway({
|
||||
chatId: chatId!,
|
||||
giveawayId: dataPrepaidGiveaway!.id,
|
||||
paymentPurpose: {
|
||||
additionalChannelIds: selectedChannelIds,
|
||||
countries: selectedCountryIds,
|
||||
prizeDescription,
|
||||
areWinnersVisible: shouldShowWinners,
|
||||
untilDate: customExpireDate / 1000,
|
||||
currency: selectedGift!.currency,
|
||||
amount: selectedGift!.amount,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
closeConfirmModal();
|
||||
closeGiveawayModal();
|
||||
handleClose();
|
||||
});
|
||||
|
||||
const handleRandomUserCountChange = useLastCallback((newValue) => {
|
||||
setSelectedRandomUserCount(newValue);
|
||||
});
|
||||
|
||||
const handleWinnerCountChange = useLastCallback((newValue) => {
|
||||
setSelectedRandomUserCount(newValue);
|
||||
});
|
||||
|
||||
const handlePrizeDescriptionChange = useLastCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||
setPrizeDescription(e.target.value);
|
||||
});
|
||||
@ -309,6 +401,7 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
const handleChangeTypeOption = useLastCallback((value: ApiGiveawayType) => {
|
||||
setGiveawayOption(value);
|
||||
setSelectedUserIds([]);
|
||||
setSelectedRandomUserCount(DEFAULT_BOOST_COUNT);
|
||||
});
|
||||
|
||||
const handleExpireDateChange = useLastCallback((date: Date) => {
|
||||
@ -323,7 +416,7 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
const handleSelectedUserIdsChange = useLastCallback((newSelectedIds: string[]) => {
|
||||
setSelectedUserIds(newSelectedIds);
|
||||
if (!newSelectedIds.length) {
|
||||
setGiveawayOption('random_users');
|
||||
setGiveawayOption('premium_giveaway');
|
||||
}
|
||||
});
|
||||
|
||||
@ -331,10 +424,6 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
setSelectedChannelIds(newSelectedIds);
|
||||
});
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
closeGiveawayModal();
|
||||
});
|
||||
|
||||
const handleShouldShowWinnersChange = useLastCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||
setShouldShowWinners(e.target.checked);
|
||||
});
|
||||
@ -347,7 +436,9 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
openCountryPickerModal();
|
||||
});
|
||||
|
||||
if (!gifts) return undefined;
|
||||
const handleStarClick = useLastCallback((option) => {
|
||||
setSelectedStarOption(option);
|
||||
});
|
||||
|
||||
function renderTypeOptions() {
|
||||
return (
|
||||
@ -428,12 +519,177 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
setSelectedChannelIds(filteredChannelIds);
|
||||
}
|
||||
|
||||
function renderStarOptionList() {
|
||||
return (
|
||||
<StarTopupOptionList
|
||||
className={styles.starOptions}
|
||||
options={starsGiftOptions}
|
||||
selectedStarCount={selectedRandomUserCount}
|
||||
selectedStarOption={selectedStarOption}
|
||||
onClick={handleStarClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function renderGiveawayOptionList() {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingChannelsGroupsIncludedGiveaway')}
|
||||
</h2>
|
||||
|
||||
<ListItem
|
||||
inactive
|
||||
className="chat-item-clickable contact-list-item"
|
||||
>
|
||||
<GroupChatInfo
|
||||
chatId={chatId!}
|
||||
status={lang(isChannel ? 'BoostingChannelWillReceiveBoost'
|
||||
: 'BoostingGroupWillReceiveBoost', boostQuantity || boostStarsQuantity, 'i')}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
{selectedChannelIds?.map((channelId) => {
|
||||
return (
|
||||
<ListItem
|
||||
ripple
|
||||
key={channelId}
|
||||
className="chat-item-clickable contact-list-item"
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
onClick={() => deleteParticipantsHandler(channelId)}
|
||||
rightElement={(<Icon name="close" className={styles.removeChannel} />)}
|
||||
>
|
||||
<GroupChatInfo
|
||||
chatId={channelId.toString()}
|
||||
/>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
|
||||
{selectedChannelIds.length < MAX_ADDITIONAL_CHANNELS && (
|
||||
<ListItem
|
||||
icon="add"
|
||||
ripple
|
||||
onClick={openChannelPickerModal}
|
||||
className={styles.addButton}
|
||||
iconClassName={styles.addChannel}
|
||||
>
|
||||
{lang('BoostingAddChannelOrGroup')}
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingEligibleUsers')}
|
||||
</h2>
|
||||
|
||||
{renderSubscribersOptions()}
|
||||
</div>
|
||||
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang(isChannel ? 'BoostGift.LimitSubscribersInfo' : 'lng_giveaway_users_about_group'))}
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<div className={styles.checkboxSection}>
|
||||
<h2 className={styles.title}>
|
||||
{lang('BoostingGiveawayAdditionalPrizes')}
|
||||
</h2>
|
||||
|
||||
<Switcher
|
||||
label={lang('BoostingGiveawayAdditionalPrizes')}
|
||||
checked={shouldShowPrizes}
|
||||
onChange={handleShouldShowPrizesChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{shouldShowPrizes && (
|
||||
<div className={styles.prizesSection}>
|
||||
<h2 className={styles.title}>
|
||||
{selectedRandomUserCount}
|
||||
</h2>
|
||||
<InputText
|
||||
className={styles.prizesInput}
|
||||
value={prizeDescription}
|
||||
onChange={handlePrizeDescriptionChange}
|
||||
label={lang('BoostingGiveawayEnterYourPrize')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{shouldShowPrizes ? (
|
||||
!isStarsGiveaway && !isStarsPrepaidGiveaway ? (
|
||||
<div className={styles.subscription}>
|
||||
{prizeDescription?.length ? renderText(lang('BoostingGiveawayAdditionPrizeCountNameHint',
|
||||
dataPrepaidGiveaway
|
||||
? [dataPrepaidGiveaway.quantity, prizeDescription, monthQuantity]
|
||||
: [selectedUserCount, prizeDescription, monthQuantity],
|
||||
undefined,
|
||||
selectedMonthOption), ['simple_markdown']) : renderText(lang('BoostingGiveawayAdditionPrizeCountHint',
|
||||
dataPrepaidGiveaway
|
||||
? [dataPrepaidGiveaway.quantity, monthQuantity]
|
||||
: [selectedUserCount, monthQuantity],
|
||||
undefined,
|
||||
selectedMonthOption), ['simple_markdown'])}
|
||||
</div>
|
||||
) : undefined
|
||||
) : (
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang('BoostingGiveawayAdditionPrizeHint'))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.section}>
|
||||
<div className={styles.checkboxSection}>
|
||||
<h2 className={styles.title}>
|
||||
{lang('BoostingGiveawayShowWinners')}
|
||||
</h2>
|
||||
|
||||
<Switcher
|
||||
label={lang('BoostingGiveawayAdditionalPrizes')}
|
||||
checked={shouldShowWinners}
|
||||
onChange={handleShouldShowWinnersChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang('BoostingGiveawayShowWinnersHint'))}
|
||||
</div>
|
||||
|
||||
<div className={buildClassName(styles.section,
|
||||
(dataPrepaidGiveaway || dataStarsPrepaidGiveaway || isStarsGiveaway) && styles.subscriptionFooter)}
|
||||
>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingDateWhenGiveawayEnds')}
|
||||
</h2>
|
||||
|
||||
<Button
|
||||
ariaLabel={lang('BoostGift.DateEnds')}
|
||||
className={buildClassName(styles.dateButton, 'expire-limit')}
|
||||
isText
|
||||
onClick={openCalendar}
|
||||
>
|
||||
<h3 className={styles.title}>
|
||||
{lang('BoostGift.DateEnds')}
|
||||
</h3>
|
||||
{formatDateTimeToString(customExpireDate, lang.code)}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={styles.root}
|
||||
onClose={handleClose}
|
||||
isOpen={isOpen}
|
||||
dialogRef={dialogRef}
|
||||
onEnter={(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? openConfirmModal : handleClick}
|
||||
>
|
||||
<div className={styles.main} onScroll={handleScroll}>
|
||||
<Button
|
||||
@ -458,22 +714,31 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
{lang('BoostingBoostsViaGifts')}
|
||||
</h2>
|
||||
</div>
|
||||
{dataPrepaidGiveaway ? (
|
||||
{(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? (
|
||||
<div className={styles.status}>
|
||||
<div>
|
||||
<img className={styles.prepaidImg} src={GIVEAWAY_IMG_LIST[dataPrepaidGiveaway.months]} alt="" />
|
||||
{dataStarsPrepaidGiveaway ? (
|
||||
<img className={styles.prepaidImg} src={GiftStar} alt="" />
|
||||
) : (
|
||||
<img className={styles.prepaidImg} src={GIVEAWAY_IMG_LIST[dataPrepaidGiveaway!.months]} alt="" />
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.info}>
|
||||
<h3 className={styles.title}>
|
||||
{lang('BoostingTelegramPremiumCountPlural', dataPrepaidGiveaway.quantity)}
|
||||
{dataStarsPrepaidGiveaway ? lang('Giveaway.Stars.Prepaid.Title', dataStarsPrepaidGiveaway?.stars)
|
||||
: lang('BoostingTelegramPremiumCountPlural', dataPrepaidGiveaway!.quantity)}
|
||||
</h3>
|
||||
<p className={styles.month}>{lang('PrepaidGiveawayMonths', dataPrepaidGiveaway.months)}</p>
|
||||
<p className={styles.month}>
|
||||
{dataStarsPrepaidGiveaway ? lang('Giveaway.Stars.Prepaid.Desc', dataStarsPrepaidGiveaway?.quantity)
|
||||
: lang('PrepaidGiveawayMonths', dataPrepaidGiveaway?.months)}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.quantity}>
|
||||
<div className={buildClassName(styles.floatingBadge, styles.floatingBadgeColor)}>
|
||||
<Icon name="boost" className={styles.floatingBadgeIcon} />
|
||||
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{dataPrepaidGiveaway.quantity * (giveawayBoostPerPremiumLimit ?? GIVEAWAY_BOOST_PER_PREMIUM)}
|
||||
{dataStarsPrepaidGiveaway ? dataStarsPrepaidGiveaway?.boosts
|
||||
: dataPrepaidGiveaway!.quantity * (giveawayBoostPerPremiumLimit ?? GIVEAWAY_BOOST_PER_PREMIUM)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -484,9 +749,9 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isRandomUsers && (
|
||||
{isPremiumGiveaway && !selectedUserIds?.length && (
|
||||
<>
|
||||
{!dataPrepaidGiveaway && (
|
||||
{!dataPrepaidGiveaway && !dataStarsPrepaidGiveaway && (
|
||||
<>
|
||||
<div className={styles.section}>
|
||||
<div className={styles.quantity}>
|
||||
@ -514,151 +779,57 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingChannelsIncludedGiveaway')}
|
||||
</h2>
|
||||
|
||||
<ListItem
|
||||
inactive
|
||||
className="chat-item-clickable contact-list-item"
|
||||
>
|
||||
<GroupChatInfo
|
||||
chatId={chatId!}
|
||||
status={lang(isChannel ? 'BoostingChannelWillReceiveBoost'
|
||||
: 'BoostingGroupWillReceiveBoost', boostQuantity, 'i')}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
{selectedChannelIds?.map((channelId) => {
|
||||
return (
|
||||
<ListItem
|
||||
ripple
|
||||
key={channelId}
|
||||
className="chat-item-clickable contact-list-item"
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
onClick={() => deleteParticipantsHandler(channelId)}
|
||||
rightElement={(<Icon name="close" className={styles.removeChannel} />)}
|
||||
>
|
||||
<GroupChatInfo
|
||||
chatId={channelId.toString()}
|
||||
/>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
|
||||
{selectedChannelIds.length < MAX_ADDITIONAL_CHANNELS && (
|
||||
<ListItem
|
||||
icon="add"
|
||||
ripple
|
||||
onClick={openChannelPickerModal}
|
||||
className={styles.addButton}
|
||||
iconClassName={styles.addChannel}
|
||||
>
|
||||
{lang('BoostingAddChannelOrGroup')}
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingEligibleUsers')}
|
||||
</h2>
|
||||
|
||||
{renderSubscribersOptions()}
|
||||
</div>
|
||||
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang(isChannel ? 'BoostGift.LimitSubscribersInfo' : 'lng_giveaway_users_about_group'))}
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<div className={styles.checkboxSection}>
|
||||
<h2 className={styles.title}>
|
||||
{lang('BoostingGiveawayAdditionalPrizes')}
|
||||
</h2>
|
||||
|
||||
<Switcher
|
||||
label={lang('BoostingGiveawayAdditionalPrizes')}
|
||||
checked={shouldShowPrizes}
|
||||
onChange={handleShouldShowPrizesChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{shouldShowPrizes && (
|
||||
<div className={styles.prizesSection}>
|
||||
<h2 className={styles.title}>
|
||||
{dataPrepaidGiveaway ? dataPrepaidGiveaway.quantity : selectedUserCount}
|
||||
</h2>
|
||||
<InputText
|
||||
className={styles.prizesInput}
|
||||
value={prizeDescription}
|
||||
onChange={handlePrizeDescriptionChange}
|
||||
label={lang('BoostingGiveawayEnterYourPrize')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{shouldShowPrizes ? (
|
||||
<div className={styles.subscription}>
|
||||
{prizeDescription?.length ? renderText(lang('BoostingGiveawayAdditionPrizeCountNameHint',
|
||||
dataPrepaidGiveaway
|
||||
? [dataPrepaidGiveaway.quantity, prizeDescription, monthQuantity]
|
||||
: [selectedUserCount, prizeDescription, monthQuantity],
|
||||
undefined,
|
||||
selectedMonthOption), ['simple_markdown']) : renderText(lang('BoostingGiveawayAdditionPrizeCountHint',
|
||||
dataPrepaidGiveaway
|
||||
? [dataPrepaidGiveaway.quantity, monthQuantity]
|
||||
: [selectedUserCount, monthQuantity],
|
||||
undefined,
|
||||
selectedMonthOption), ['simple_markdown'])}
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang('BoostingGiveawayAdditionPrizeHint'))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.section}>
|
||||
<div className={styles.checkboxSection}>
|
||||
<h2 className={styles.title}>
|
||||
{lang('BoostingGiveawayShowWinners')}
|
||||
</h2>
|
||||
|
||||
<Switcher
|
||||
label={lang('BoostingGiveawayAdditionalPrizes')}
|
||||
checked={shouldShowWinners}
|
||||
onChange={handleShouldShowWinnersChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang('BoostingGiveawayShowWinnersHint'))}
|
||||
</div>
|
||||
|
||||
<div className={buildClassName(styles.section, dataPrepaidGiveaway && styles.subscriptionFooter)}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingDateWhenGiveawayEnds')}
|
||||
</h2>
|
||||
|
||||
<Button
|
||||
ariaLabel={lang('BoostGift.DateEnds')}
|
||||
className={buildClassName(styles.dateButton, 'expire-limit')}
|
||||
isText
|
||||
onClick={openCalendar}
|
||||
>
|
||||
<h3 className={styles.title}>
|
||||
{lang('BoostGift.DateEnds')}
|
||||
</h3>
|
||||
{formatDateTimeToString(customExpireDate, lang.code)}
|
||||
</Button>
|
||||
</div>
|
||||
{renderGiveawayOptionList()}
|
||||
</>
|
||||
)}
|
||||
|
||||
{!dataPrepaidGiveaway && (
|
||||
{isStarsGiveaway && (
|
||||
<>
|
||||
{!dataStarsPrepaidGiveaway && !dataPrepaidGiveaway && (
|
||||
<>
|
||||
<div className={styles.section}>
|
||||
<div className={styles.quantity}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingStarsOptions')}
|
||||
</h2>
|
||||
<div className={buildClassName(styles.floatingBadge, styles.floatingBadgeColor)}>
|
||||
<Icon name="boost" className={styles.floatingBadgeIcon} />
|
||||
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{boostStarsQuantity}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{renderStarOptionList()}
|
||||
</div>
|
||||
|
||||
<div className={buildClassName(styles.subscription, styles.starSubscription)}>
|
||||
{renderText(lang('BoostGift.Stars.Info'))}
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
{lang('BoostingStarsQuantityPrizes')}
|
||||
</h2>
|
||||
|
||||
<RangeSliderWithMarks
|
||||
rangeCount={selectedRandomUserCount}
|
||||
marks={winnerCountOptions}
|
||||
onChange={handleWinnerCountChange}
|
||||
/>
|
||||
|
||||
<div className={styles.subscription}>
|
||||
{renderText(lang('BoostingStarsQuantityPrizesInfo'))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{renderGiveawayOptionList()}
|
||||
</>
|
||||
)}
|
||||
|
||||
{!dataPrepaidGiveaway && !dataStarsPrepaidGiveaway && isPremiumGiveaway && (
|
||||
<>
|
||||
<div className={styles.section}>
|
||||
<h2 className={styles.giveawayTitle}>
|
||||
@ -676,16 +847,11 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
|
||||
{selectedGiveawayOption && (
|
||||
<div className={styles.footer}>
|
||||
<Button className={styles.button} onClick={dataPrepaidGiveaway ? openConfirmModal : handleClick}>
|
||||
<Button
|
||||
className={styles.button}
|
||||
onClick={(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? openConfirmModal : handleClick}
|
||||
>
|
||||
{lang('BoostingStartGiveaway')}
|
||||
<div className={styles.quantity}>
|
||||
<div className={buildClassName(styles.floatingBadge, styles.floatingBadgeButtonColor)}>
|
||||
<Icon name="boost" className={styles.floatingBadgeIcon} />
|
||||
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{dataPrepaidGiveaway ? dataPrepaidGiveaway.quantity : boostQuantity}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
@ -748,10 +914,12 @@ export default memo(withGlobal<OwnProps>((global): StateProps => {
|
||||
selectedMemberList: giveawayModal?.selectedMemberIds,
|
||||
selectedChannelList: giveawayModal?.selectedChannelIds,
|
||||
giveawayBoostPerPremiumLimit: global.appConfig?.giveawayBoostsPerPremium,
|
||||
isStarsGiftsEnabled: global.appConfig?.isStarsGiftsEnabled,
|
||||
userSelectionLimit: global.appConfig?.giveawayAddPeersMax,
|
||||
countrySelectionLimit: global.appConfig?.giveawayCountriesMax,
|
||||
countryList: global.countryList.general,
|
||||
prepaidGiveaway: giveawayModal?.prepaidGiveaway,
|
||||
isChannel,
|
||||
starsGiftOptions: giveawayModal?.starOptions,
|
||||
};
|
||||
})(GiveawayModal));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
.wrapper {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding-inline: 3.8125rem 1rem;
|
||||
padding-inline: 3.5rem 1rem;
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ import Icon from '../../common/icons/Icon';
|
||||
|
||||
import styles from './GiveawayTypeOption.module.scss';
|
||||
|
||||
type ApiGiveawayType = 'random_users' | 'specific_users';
|
||||
type ApiGiveawayType = 'premium_giveaway' | 'stars_giveaway';
|
||||
|
||||
type OwnProps = {
|
||||
option: ApiGiveawayType;
|
||||
@ -54,7 +54,6 @@ const GiveawayTypeOption: FC<OwnProps> = ({
|
||||
<label
|
||||
className={buildClassName(styles.wrapper, className)}
|
||||
dir={lang.isRtl ? 'rtl' : undefined}
|
||||
onClick={handleClick}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
@ -74,7 +73,7 @@ const GiveawayTypeOption: FC<OwnProps> = ({
|
||||
{lang(`${name}`)}
|
||||
</h3>
|
||||
{isLink ? (
|
||||
<div className={styles.link}>
|
||||
<div className={styles.link} onClick={handleClick}>
|
||||
<span>{displayText}</span>
|
||||
<Icon name="next" />
|
||||
</div>
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
}
|
||||
|
||||
.root :global(.modal-dialog) {
|
||||
height: min(calc(55vh + 41px + 193px), 90vh);
|
||||
max-width: 26.25rem;
|
||||
}
|
||||
|
||||
@ -119,5 +118,5 @@
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: 0 1.5rem;
|
||||
margin: 0 1.5rem 1rem;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
.giveawayWrapper {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding-inline: 3.8125rem 1rem;
|
||||
padding-inline: 3.5rem 1rem;
|
||||
|
||||
cursor: var(--custom-cursor, pointer);
|
||||
|
||||
|
||||
@ -4,10 +4,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
z-index: calc(var(--z-modal-low-priority) + 1);
|
||||
}
|
||||
|
||||
.root :global(.modal-content) {
|
||||
padding: 0;
|
||||
}
|
||||
@ -15,11 +11,6 @@
|
||||
.root :global(.modal-dialog) {
|
||||
height: min(calc(55vh + 41px + 193px), 90vh);
|
||||
max-width: 26.25rem;
|
||||
}
|
||||
|
||||
.root :global(.modal-dialog),
|
||||
.root :global(.modal-content),
|
||||
.transition {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -28,6 +19,7 @@
|
||||
overflow-y: scroll;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.headerInfo {
|
||||
|
||||
@ -116,6 +116,10 @@ const StarsGiftModal: FC<OwnProps & StateProps> = ({
|
||||
setHeaderHidden(scrollTop <= 150);
|
||||
}
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
closeStarsGiftModal();
|
||||
});
|
||||
|
||||
function renderGiftTitle() {
|
||||
if (isCompleted) {
|
||||
return user ? renderText(oldLang('Notification.StarsGift.SentYou',
|
||||
@ -149,12 +153,12 @@ const StarsGiftModal: FC<OwnProps & StateProps> = ({
|
||||
|
||||
return (
|
||||
<Modal
|
||||
dialogRef={dialogRef}
|
||||
onClose={closeStarsGiftModal}
|
||||
isOpen={isOpen}
|
||||
className={buildClassName(styles.modalDialog, styles.root)}
|
||||
dialogRef={dialogRef}
|
||||
onClose={handleClose}
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
||||
<div className={styles.main} onScroll={handleScroll}>
|
||||
<Button
|
||||
round
|
||||
size="smaller"
|
||||
|
||||
@ -35,6 +35,7 @@ import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
|
||||
import useEnsureMessage from '../../hooks/useEnsureMessage';
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import { useIsIntersecting, useOnIntersect } from '../../hooks/useIntersectionObserver';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
|
||||
import useFocusMessage from './message/hooks/useFocusMessage';
|
||||
@ -105,10 +106,16 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
onIntersectPinnedMessage,
|
||||
}) => {
|
||||
const {
|
||||
openPremiumModal, requestConfetti, checkGiftCode, getReceipt, openStarsTransactionFromGift,
|
||||
openPremiumModal,
|
||||
requestConfetti,
|
||||
checkGiftCode,
|
||||
getReceipt,
|
||||
openStarsTransactionFromGift,
|
||||
openPrizeStarsTransactionFromGiveaway,
|
||||
} = getActions();
|
||||
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@ -134,6 +141,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
const isSuggestedAvatar = message.content.action?.type === 'suggestProfilePhoto' && message.content.action!.photo;
|
||||
const isJoinedMessage = isJoinedChannelMessage(message);
|
||||
const isStarsGift = message.content.action?.type === 'giftStars';
|
||||
const isPrizeStars = message.content.action?.type === 'prizeStars';
|
||||
|
||||
useEffect(() => {
|
||||
if (noAppearanceAnimation) {
|
||||
@ -214,6 +222,13 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handlePrizeStarsClick = () => {
|
||||
openPrizeStarsTransactionFromGiveaway({
|
||||
chatId: message.chatId,
|
||||
messageId: message.id,
|
||||
});
|
||||
};
|
||||
|
||||
const handleGiftCodeClick = () => {
|
||||
const slug = message.content.action?.slug;
|
||||
if (!slug) return;
|
||||
@ -343,6 +358,50 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
function renderPrizeStars() {
|
||||
const isUnclaimed = message.content.action?.isUnclaimed;
|
||||
|
||||
return (
|
||||
<span
|
||||
className="action-message-gift action-message-gift-code"
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
onClick={handlePrizeStarsClick}
|
||||
>
|
||||
<AnimatedIconFromSticker
|
||||
key={message.id}
|
||||
sticker={starGiftSticker}
|
||||
play={canPlayAnimatedEmojis}
|
||||
noLoop
|
||||
nonInteractive
|
||||
/>
|
||||
<strong>
|
||||
{oldLang(isUnclaimed ? 'BoostingUnclaimedPrize' : 'BoostingCongratulations')}
|
||||
</strong>
|
||||
<span className="action-message-subtitle">
|
||||
{targetChat && renderText(oldLang(isUnclaimed
|
||||
? 'BoostingReceivedPrizeFrom' : 'BoostingYouHaveUnclaimedPrize', getChatTitle(oldLang, targetChat)),
|
||||
['simple_markdown'])}
|
||||
</span>
|
||||
<span className="action-message-subtitle">
|
||||
{renderText(lang(
|
||||
'PrizeCredits', {
|
||||
count: (
|
||||
<b>{formatInteger(message.content.action?.stars!)}</b>
|
||||
),
|
||||
}, {
|
||||
withNodes: true,
|
||||
},
|
||||
), ['simple_markdown'])}
|
||||
</span>
|
||||
<span className="action-message-button">{
|
||||
oldLang('ActionGiftPremiumView')
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const className = buildClassName(
|
||||
'ActionMessage message-list-item',
|
||||
isFocused && !noFocusHighlight && 'focused',
|
||||
@ -368,6 +427,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
{isPremiumGift && renderGift()}
|
||||
{isGiftCode && renderGiftCode()}
|
||||
{isStarsGift && renderStarsGift()}
|
||||
{isPrizeStars && renderPrizeStars()}
|
||||
{isSuggestedAvatar && (
|
||||
<ActionMessageSuggestedAvatar message={message} renderContent={renderContent} />
|
||||
)}
|
||||
|
||||
@ -68,7 +68,7 @@ const Giveaway = ({
|
||||
const { giveaway, giveawayResults } = message.content;
|
||||
const isResults = Boolean(giveawayResults);
|
||||
const {
|
||||
months, untilDate, prizeDescription,
|
||||
months, untilDate, prizeDescription, stars,
|
||||
} = (giveaway || giveawayResults)!;
|
||||
|
||||
const isOwn = isOwnMessage(message);
|
||||
@ -130,12 +130,25 @@ const Giveaway = ({
|
||||
</>
|
||||
)}
|
||||
<p className={styles.description}>
|
||||
{renderText(lang('Chat.Giveaway.Info.Subscriptions', quantity), ['simple_markdown'])}
|
||||
<br />
|
||||
{renderText(lang(
|
||||
'ActionGiftPremiumSubtitle',
|
||||
lang('Chat.Giveaway.Info.Months', months),
|
||||
), ['simple_markdown'])}
|
||||
{message?.content?.giveaway?.stars ? (
|
||||
<>
|
||||
{renderText(
|
||||
lang('Chat.Giveaway.Message.Stars.PrizeText', lang('Stars', message?.content?.giveaway?.stars)),
|
||||
['simple_markdown'],
|
||||
)}
|
||||
<br />
|
||||
{renderText(lang('AmongWinners', quantity), ['simple_markdown'])}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{renderText(lang('Chat.Giveaway.Info.Subscriptions', quantity), ['simple_markdown'])}
|
||||
<br />
|
||||
{renderText(lang(
|
||||
'ActionGiftPremiumSubtitle',
|
||||
lang('Chat.Giveaway.Info.Months', months),
|
||||
), ['simple_markdown'])}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
@ -216,14 +229,14 @@ const Giveaway = ({
|
||||
const isResultsInfo = giveawayInfo.type === 'results';
|
||||
|
||||
const chatTitle = isApiPeerChat(sender) ? getChatTitle(lang, sender) : getUserFullName(sender);
|
||||
const duration = lang('Chat.Giveaway.Info.Months', months);
|
||||
const endDate = formatDateAtTime(lang, untilDate * 1000);
|
||||
const otherChannelsCount = giveaway?.channelIds ? giveaway.channelIds.length - 1 : 0;
|
||||
const otherChannelsString = lang('Chat.Giveaway.Info.OtherChannels', otherChannelsCount);
|
||||
const isSeveral = otherChannelsCount > 0;
|
||||
|
||||
const firstKey = isResultsInfo ? 'BoostingGiveawayHowItWorksTextEnd' : 'BoostingGiveawayHowItWorksText';
|
||||
const firstParagraph = lang(firstKey, [chatTitle, quantity, duration], undefined, quantity);
|
||||
const giveawayDuration = isResultsInfo ? lang('Chat.Giveaway.Info.Months', months) : lang('Stars', stars, 'i');
|
||||
const firstParagraph = lang(firstKey, [chatTitle, quantity, giveawayDuration], undefined, quantity);
|
||||
|
||||
const additionalPrizes = prizeDescription
|
||||
? lang('BoostingGiveawayHowItWorksIncludeText', [chatTitle, quantity, prizeDescription], undefined, quantity)
|
||||
|
||||
@ -731,6 +731,10 @@
|
||||
width: 1px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.giveaway-result-content {
|
||||
min-width: 17rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Border-radius styles
|
||||
|
||||
@ -1576,7 +1576,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
{withAvatar && renderAvatar()}
|
||||
<div
|
||||
className={buildClassName('message-content-wrapper', contentClassName.includes('text') && 'can-select-text')}
|
||||
className={buildClassName('message-content-wrapper',
|
||||
contentClassName.includes('text') && 'giveaway-result-content',
|
||||
contentClassName.includes('giveaway') && 'can-select-text')}
|
||||
>
|
||||
<div
|
||||
className={contentClassName}
|
||||
|
||||
@ -16,11 +16,29 @@
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.table .cell {
|
||||
border: 1px solid var(--color-borders);
|
||||
.table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.cell {
|
||||
border: solid 0.0625rem var(--color-borders);
|
||||
border-style: none solid solid none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.row:first-child .cell:first-child { border-top-left-radius: 0.3125rem; }
|
||||
|
||||
.row:first-child .cell:last-child { border-top-right-radius: 0.3125rem; }
|
||||
|
||||
.row:last-child .cell:first-child { border-bottom-left-radius: 0.3125rem; }
|
||||
|
||||
.row:last-child .cell:last-child { border-bottom-right-radius: 0.3125rem; }
|
||||
|
||||
.row:first-child .cell { border-top-style: solid; }
|
||||
|
||||
.row .cell:first-child { border-left-style: solid; }
|
||||
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -31,6 +31,7 @@ type OwnProps = {
|
||||
headerAvatarWebPhoto?: ApiWebDocument;
|
||||
noHeaderImage?: boolean;
|
||||
isGift?: boolean;
|
||||
isPrizeStars?: boolean;
|
||||
header?: TeactNode;
|
||||
footer?: TeactNode;
|
||||
buttonText?: string;
|
||||
@ -49,6 +50,7 @@ const TableInfoModal = ({
|
||||
headerAvatarWebPhoto,
|
||||
noHeaderImage,
|
||||
isGift,
|
||||
isPrizeStars,
|
||||
header,
|
||||
footer,
|
||||
buttonText,
|
||||
@ -75,7 +77,7 @@ const TableInfoModal = ({
|
||||
contentClassName={styles.content}
|
||||
onClose={onClose}
|
||||
>
|
||||
{!isGift && !noHeaderImage && (
|
||||
{!isGift && !isPrizeStars && !noHeaderImage && (
|
||||
withAvatar ? (
|
||||
<Avatar peer={headerAvatarPeer} webPhoto={headerAvatarWebPhoto} size="jumbo" className={styles.avatar} />
|
||||
) : (
|
||||
|
||||
@ -28,6 +28,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
--_background-color: var(--color-background-secondary-accent);
|
||||
}
|
||||
|
||||
.wideOption {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, { memo, useEffect, useMemo } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useEffect, useMemo,
|
||||
} from '../../../lib/teact/teact';
|
||||
|
||||
import type { ApiStarTopupOption } from '../../../api/types';
|
||||
import type { ApiStarGiveawayOption, ApiStarTopupOption } from '../../../api/types';
|
||||
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatCurrency } from '../../../util/formatCurrency';
|
||||
import { formatInteger } from '../../../util/textFormat';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
|
||||
import Icon from '../../common/icons/Icon';
|
||||
@ -20,18 +24,25 @@ const MAX_STARS_COUNT = 6;
|
||||
|
||||
type OwnProps = {
|
||||
isActive?: boolean;
|
||||
options?: ApiStarTopupOption[];
|
||||
options?: ApiStarTopupOption[] | ApiStarGiveawayOption[];
|
||||
selectedStarOption?: ApiStarTopupOption | ApiStarGiveawayOption;
|
||||
selectedStarCount?: number;
|
||||
starsNeeded?: number;
|
||||
onClick: (option: ApiStarTopupOption) => void;
|
||||
className?: string;
|
||||
onClick: (option: ApiStarTopupOption | ApiStarGiveawayOption) => void;
|
||||
};
|
||||
|
||||
const StarTopupOptionList: FC<OwnProps> = ({
|
||||
isActive,
|
||||
className,
|
||||
options,
|
||||
selectedStarOption,
|
||||
selectedStarCount,
|
||||
starsNeeded,
|
||||
onClick,
|
||||
}) => {
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
const [areOptionsExtended, markOptionsExtended, unmarkOptionsExtended] = useFlag();
|
||||
|
||||
@ -51,7 +62,7 @@ const StarTopupOptionList: FC<OwnProps> = ({
|
||||
));
|
||||
const forceShowAll = starsNeeded && maxOption.stars < starsNeeded;
|
||||
|
||||
const result: { option: ApiStarTopupOption; starsCount: number; isWide: boolean }[] = [];
|
||||
const result: { option: ApiStarTopupOption | ApiStarGiveawayOption; starsCount: number; isWide: boolean }[] = [];
|
||||
let currentStackedStarsCount = 0;
|
||||
let canExtendOptions = false;
|
||||
options.forEach((option, index) => {
|
||||
@ -73,13 +84,24 @@ const StarTopupOptionList: FC<OwnProps> = ({
|
||||
}, [areOptionsExtended, options, starsNeeded]);
|
||||
|
||||
return (
|
||||
<div className={styles.options}>
|
||||
<div className={buildClassName(styles.options, className)}>
|
||||
{renderingOptions?.map(({ option, starsCount, isWide }) => {
|
||||
const length = renderingOptions?.length;
|
||||
const isOdd = length % 2 === 0;
|
||||
const isActiveOption = option === selectedStarOption;
|
||||
|
||||
let perUserStarCount;
|
||||
if (option && 'winners' in option) {
|
||||
const winner = option.winners.find((opt) => opt.users === selectedStarCount)
|
||||
|| option.winners.reduce((max, opt) => (opt.users > max.users ? opt : max), option.winners[0]);
|
||||
perUserStarCount = winner?.perUserStars;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={buildClassName(styles.option, (!isOdd && isWide) && styles.wideOption)}
|
||||
className={buildClassName(
|
||||
styles.option, (!isOdd && isWide) && styles.wideOption, isActiveOption && styles.active,
|
||||
)}
|
||||
key={option.stars}
|
||||
onClick={() => onClick?.(option)}
|
||||
>
|
||||
@ -92,14 +114,21 @@ const StarTopupOptionList: FC<OwnProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.optionBottom}>
|
||||
{formatCurrency(option.amount, option.currency, lang.code)}
|
||||
{formatCurrency(option.amount, option.currency, oldLang.code)}
|
||||
</div>
|
||||
{(isActiveOption || (selectedStarOption && 'winners' in selectedStarOption)) && perUserStarCount && (
|
||||
<div className={styles.optionBottom}>
|
||||
<div className={styles.perUserStars}>
|
||||
{renderText(oldLang('BoostGift.Stars.PerUser', formatInteger(perUserStarCount)))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{!areOptionsExtended && canExtend && (
|
||||
<Button className={styles.moreOptions} isText noForcedUpperCase onClick={markOptionsExtended}>
|
||||
{lang('Stars.Purchase.ShowMore')}
|
||||
{oldLang('Stars.Purchase.ShowMore')}
|
||||
<Icon className={styles.iconDown} name="down" />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@ -56,6 +56,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
const lang = useLang();
|
||||
const { transaction } = modal || {};
|
||||
const isGift = transaction?.isGift;
|
||||
const isPrizeStars = transaction?.isPrizeStars;
|
||||
|
||||
const handleOpenMedia = useLastCallback(() => {
|
||||
const media = transaction?.extendedMedia;
|
||||
@ -158,7 +159,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
onClick={handleOpenMedia}
|
||||
/>
|
||||
)}
|
||||
{isGift ? animatedStickerData : (
|
||||
{(isGift || isPrizeStars) ? animatedStickerData : (
|
||||
<img
|
||||
className={buildClassName(styles.starsBackground, media && styles.mediaShift)}
|
||||
src={StarsBackground}
|
||||
@ -167,9 +168,10 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
/>
|
||||
)}
|
||||
{title && <h1 className={styles.title}>{title}</h1>}
|
||||
{isGift && (
|
||||
{(isGift || isPrizeStars) && (
|
||||
<h1 className={buildClassName(styles.title, styles.starTitle)}>
|
||||
{transaction?.isMyGift ? oldLang('StarsGiftSent') : oldLang('StarsGiftReceived')}
|
||||
{isPrizeStars ? oldLang('StarsGiveawayPrizeReceived')
|
||||
: transaction?.isMyGift ? oldLang('StarsGiftSent') : oldLang('StarsGiftReceived')}
|
||||
</h1>
|
||||
)}
|
||||
<p className={styles.description}>{description}</p>
|
||||
@ -199,7 +201,14 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
tableData.push([oldLang('Stars.Transaction.Media'), <SafeLink url={messageLink} text={messageLink} />]);
|
||||
}
|
||||
|
||||
if (transaction.id) {
|
||||
if (isPrizeStars) {
|
||||
tableData.push(
|
||||
[oldLang('BoostReason'), oldLang('Giveaway')],
|
||||
[oldLang('Gift'), oldLang('Stars', transaction.stars, 'i')],
|
||||
);
|
||||
}
|
||||
|
||||
if (transaction.id && !isPrizeStars) {
|
||||
tableData.push([
|
||||
oldLang('Stars.Transaction.Id'),
|
||||
(
|
||||
@ -241,7 +250,9 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
footer,
|
||||
avatarPeer: !transaction.photo ? (peer || customPeer) : undefined,
|
||||
};
|
||||
}, [transaction, oldLang, peer, isGift, animatedStickerData, giftOutAboutText, giftEntryAboutText]);
|
||||
}, [
|
||||
transaction, oldLang, peer, isGift, isPrizeStars, animatedStickerData, giftOutAboutText, giftEntryAboutText,
|
||||
]);
|
||||
|
||||
const prevModalData = usePreviousDeprecated(starModalData);
|
||||
const renderingModalData = prevModalData || starModalData;
|
||||
@ -252,6 +263,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
|
||||
className={styles.modal}
|
||||
header={renderingModalData?.header}
|
||||
isGift={isGift}
|
||||
isPrizeStars={isPrizeStars}
|
||||
tableData={renderingModalData?.tableData}
|
||||
footer={renderingModalData?.footer}
|
||||
noHeaderImage={Boolean(transaction?.extendedMedia)}
|
||||
|
||||
@ -3,7 +3,7 @@ import React, {
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiBoost, ApiBoostStatistics, ApiPrepaidGiveaway } from '../../../api/types';
|
||||
import type { ApiBoost, ApiBoostStatistics, ApiTypePrepaidGiveaway } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import {
|
||||
@ -17,7 +17,7 @@ import {
|
||||
} from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatDateAtTime } from '../../../util/dates/dateFormat';
|
||||
import { CUSTOM_PEER_TO_BE_DISTRIBUTED } from '../../../util/objects/customPeer';
|
||||
import { CUSTOM_PEER_STAR, CUSTOM_PEER_TO_BE_DISTRIBUTED } from '../../../util/objects/customPeer';
|
||||
import { formatInteger } from '../../../util/textFormat';
|
||||
import { getBoostProgressInfo } from '../../common/helpers/boostInfo';
|
||||
|
||||
@ -40,6 +40,7 @@ import styles from './BoostStatistics.module.scss';
|
||||
import GiftBlueRound from '../../../assets/premium/GiftBlueRound.svg';
|
||||
import GiftGreenRound from '../../../assets/premium/GiftGreenRound.svg';
|
||||
import GiftRedRound from '../../../assets/premium/GiftRedRound.svg';
|
||||
import GiftStar from '../../../assets/premium/GiftStar.svg';
|
||||
|
||||
type StateProps = {
|
||||
boostStatistics: TabState['boostStatistics'];
|
||||
@ -196,6 +197,8 @@ const BoostStatistics = ({
|
||||
});
|
||||
|
||||
const renderBoostList = useLastCallback((boost) => {
|
||||
const hasStars = Boolean(boost?.stars);
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
className="chat-item-clickable"
|
||||
@ -205,7 +208,8 @@ const BoostStatistics = ({
|
||||
<PrivateChatInfo
|
||||
className={styles.user}
|
||||
userId={boost.userId}
|
||||
customPeer={!boost.userId ? CUSTOM_PEER_TO_BE_DISTRIBUTED : undefined}
|
||||
customPeer={hasStars ? { ...CUSTOM_PEER_STAR, titleValue: boost.stars }
|
||||
: (!boost.userId ? CUSTOM_PEER_TO_BE_DISTRIBUTED : undefined)}
|
||||
status={lang('BoostExpireOn', formatDateAtTime(lang, boost.expires * 1000))}
|
||||
noEmojiStatus
|
||||
forceShowSelf
|
||||
@ -218,8 +222,7 @@ const BoostStatistics = ({
|
||||
);
|
||||
});
|
||||
|
||||
const handleGiveawayClick = useLastCallback((e) => {
|
||||
e.preventDefault();
|
||||
const handleGiveawayClick = useLastCallback(() => {
|
||||
openGiveawayModal({ chatId });
|
||||
});
|
||||
|
||||
@ -228,7 +231,7 @@ const BoostStatistics = ({
|
||||
loadMoreBoosters({ isGifts: tabType === 'giftedBoostList' });
|
||||
});
|
||||
|
||||
const launchPrepaidGiveawayHandler = useLastCallback((prepaidGiveaway: ApiPrepaidGiveaway) => {
|
||||
const launchPrepaidGiveawayHandler = useLastCallback((prepaidGiveaway: ApiTypePrepaidGiveaway) => {
|
||||
openGiveawayModal({ chatId, prepaidGiveaway });
|
||||
});
|
||||
|
||||
@ -271,45 +274,65 @@ const BoostStatistics = ({
|
||||
<h4 className={styles.sectionHeader} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{lang('BoostingPreparedGiveaways')}
|
||||
</h4>
|
||||
{statsOverview?.prepaidGiveaways?.map((prepaidGiveaway) => (
|
||||
<ListItem
|
||||
key={prepaidGiveaway.id}
|
||||
className="chat-item-clickable"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => launchPrepaidGiveawayHandler(prepaidGiveaway)}
|
||||
>
|
||||
<div className={buildClassName(styles.status, 'status-clickable')}>
|
||||
<div>
|
||||
<img
|
||||
src={GIVEAWAY_IMG_LIST[prepaidGiveaway.months]}
|
||||
className={styles.giveawayIcon}
|
||||
alt={lang('Giveaway')}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.info}>
|
||||
<h3>
|
||||
{lang('BoostingTelegramPremiumCountPlural', prepaidGiveaway.quantity)}
|
||||
</h3>
|
||||
<p className={styles.month}>{lang('PrepaidGiveawayMonths', prepaidGiveaway.months)}</p>
|
||||
</div>
|
||||
<div className={styles.quantity}>
|
||||
<div className={buildClassName(styles.floatingBadge,
|
||||
styles.floatingBadgeButtonColor,
|
||||
styles.floatingBadgeButton)}
|
||||
>
|
||||
<Icon name="boost" className={styles.floatingBadgeIcon} />
|
||||
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{prepaidGiveaway.quantity * (giveawayBoostsPerPremium ?? GIVEAWAY_BOOST_PER_PREMIUM)}
|
||||
{statsOverview?.prepaidGiveaways?.map((prepaidGiveaway) => {
|
||||
const isStarsGiveaway = 'stars' in prepaidGiveaway;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={prepaidGiveaway.id}
|
||||
className="chat-item-clickable"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => launchPrepaidGiveawayHandler(prepaidGiveaway)}
|
||||
>
|
||||
<div className={buildClassName(styles.status, 'status-clickable')}>
|
||||
<div>
|
||||
{isStarsGiveaway
|
||||
? (
|
||||
<img
|
||||
src={GiftStar}
|
||||
className={styles.giveawayIcon}
|
||||
alt={lang('GiftStar')}
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
src={GIVEAWAY_IMG_LIST[prepaidGiveaway.months]}
|
||||
className={styles.giveawayIcon}
|
||||
alt={lang('Giveaway')}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.info}>
|
||||
<h3>
|
||||
{isStarsGiveaway
|
||||
? lang('Giveaway.Stars.Prepaid.Title', prepaidGiveaway.stars)
|
||||
: lang('BoostingTelegramPremiumCountPlural', prepaidGiveaway.quantity)}
|
||||
</h3>
|
||||
<p className={styles.month}>{
|
||||
isStarsGiveaway ? lang('Giveaway.Stars.Prepaid.Desc', prepaidGiveaway.quantity)
|
||||
: lang('PrepaidGiveawayMonths', prepaidGiveaway.months)
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.quantity}>
|
||||
<div className={buildClassName(styles.floatingBadge,
|
||||
styles.floatingBadgeButtonColor,
|
||||
styles.floatingBadgeButton)}
|
||||
>
|
||||
<Icon name="boost" className={styles.floatingBadgeIcon} />
|
||||
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{isStarsGiveaway ? prepaidGiveaway.boosts
|
||||
: prepaidGiveaway.quantity * (giveawayBoostsPerPremium ?? GIVEAWAY_BOOST_PER_PREMIUM)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
))}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
<p className="text-muted hint" key="links-hint">{lang('BoostingSelectPaidGiveaway')}</p>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<div className={styles.section}>
|
||||
{shouldDisplayGiftList ? (
|
||||
<div
|
||||
className={buildClassName(styles.boostSection, styles.content)}
|
||||
@ -326,7 +349,7 @@ const BoostStatistics = ({
|
||||
<TabList activeTab={renderingActiveTab} tabs={tabs} onSwitchTab={setActiveTab} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.section}>
|
||||
<>
|
||||
<h4 className={styles.sectionHeader} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
{lang('BoostingBoostsCount', boostStatistics?.boosts?.count)}
|
||||
</h4>
|
||||
@ -335,25 +358,23 @@ const BoostStatistics = ({
|
||||
</div>
|
||||
)}
|
||||
{boostStatistics?.boosts?.list?.map((boost) => renderBoostList(boost))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{Boolean(boostersToLoadCount) && (
|
||||
<ListItem
|
||||
key="load-more"
|
||||
className={styles.showMore}
|
||||
disabled={boostStatistics?.isLoadingBoosters}
|
||||
onClick={handleLoadMore}
|
||||
>
|
||||
{boostStatistics?.isLoadingBoosters ? (
|
||||
<Spinner className={styles.loadMoreSpinner} />
|
||||
) : (
|
||||
<Icon name="down" className={styles.down} />
|
||||
)}
|
||||
{lang('ShowVotes', boostersToLoadCount, 'i')}
|
||||
</ListItem>
|
||||
)}
|
||||
<div className={styles.section}>
|
||||
{Boolean(boostersToLoadCount) && (
|
||||
<ListItem
|
||||
key="load-more"
|
||||
className={styles.showMore}
|
||||
disabled={boostStatistics?.isLoadingBoosters}
|
||||
onClick={handleLoadMore}
|
||||
>
|
||||
{boostStatistics?.isLoadingBoosters ? (
|
||||
<Spinner className={styles.loadMoreSpinner} />
|
||||
) : (
|
||||
<Icon name="down" className={styles.down} />
|
||||
)}
|
||||
{lang('ShowVotes', boostersToLoadCount, 'i')}
|
||||
</ListItem>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<LinkField className={styles.section} link={status!.boostUrl} withShare title={lang('LinkForBoosting')} />
|
||||
{isGiveawayAvailable && (
|
||||
|
||||
@ -7,14 +7,16 @@
|
||||
background: var(--color-links);
|
||||
border-radius: 50%;
|
||||
cursor: var(--custom-cursor, pointer);
|
||||
transform: scale(1);
|
||||
position: absolute;
|
||||
left: var(--fill-percentage);
|
||||
transform: scale(1) translate(-45%, -50%);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
z-index: 2;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.5);
|
||||
transform: scale(1.5) translate(-30%, -30%);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,30 +72,6 @@
|
||||
);
|
||||
}
|
||||
|
||||
.slider::before,
|
||||
.slider::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
transition: transform 0.2s ease;
|
||||
z-index: -1;
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
.slider::before {
|
||||
left: 0;
|
||||
background-color: var(--color-links);
|
||||
transform: scaleX(var(--fill-percentage-before));
|
||||
}
|
||||
|
||||
.slider::after {
|
||||
right: 0;
|
||||
background: var(--color-text-secondary);
|
||||
transform: scaleX(var(--fill-percentage-after));
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
.slider::-webkit-slider-thumb {
|
||||
@include thumb-styles();
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ export const MEDIA_PROGRESSIVE_CACHE_DISABLED = false;
|
||||
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
|
||||
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
||||
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v40';
|
||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v42';
|
||||
export const ASSET_CACHE_NAME = 'tt-assets';
|
||||
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
|
||||
|
||||
@ -11,7 +11,11 @@ import { buildQueryString } from '../../../util/requestQuery';
|
||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { isChatChannel, isChatSuperGroup } from '../../helpers';
|
||||
import { getRequestInputInvoice, getStarsTransactionFromGift } from '../../helpers/payments';
|
||||
import {
|
||||
getPrizeStarsTransactionFromGiveaway,
|
||||
getRequestInputInvoice,
|
||||
getStarsTransactionFromGift,
|
||||
} from '../../helpers/payments';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
appendStarsTransactions, closeInvoice,
|
||||
@ -457,12 +461,12 @@ addActionHandler('openGiveawayModal', async (global, actions, payload): Promise<
|
||||
chat,
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
const starOptions = await callApi('fetchStarsGiveawayOptions');
|
||||
|
||||
if (!result || !starOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
const isOpen = Boolean(chatId);
|
||||
|
||||
global = updateTabState(global, {
|
||||
@ -471,6 +475,7 @@ addActionHandler('openGiveawayModal', async (global, actions, payload): Promise<
|
||||
gifts: result,
|
||||
isOpen,
|
||||
prepaidGiveaway,
|
||||
starOptions,
|
||||
},
|
||||
}, tabId);
|
||||
setGlobal(global);
|
||||
@ -546,6 +551,22 @@ addActionHandler('openStarsTransactionFromGift', (global, actions, payload): Act
|
||||
return openStarsTransactionModal(global, transaction, tabId);
|
||||
});
|
||||
|
||||
addActionHandler('openPrizeStarsTransactionFromGiveaway', (global, actions, payload): ActionReturnType => {
|
||||
const {
|
||||
chatId,
|
||||
messageId,
|
||||
tabId = getCurrentTabId(),
|
||||
} = payload || {};
|
||||
|
||||
const message = selectChatMessage(global, chatId, messageId);
|
||||
if (!message) return undefined;
|
||||
|
||||
const transaction = getPrizeStarsTransactionFromGiveaway(message);
|
||||
if (!transaction) return undefined;
|
||||
|
||||
return openStarsTransactionModal(global, transaction, tabId);
|
||||
});
|
||||
|
||||
addActionHandler('openPremiumGiftModal', async (global, actions, payload): Promise<void> => {
|
||||
const {
|
||||
forUserIds, tabId = getCurrentTabId(),
|
||||
@ -974,6 +995,41 @@ addActionHandler('launchPrepaidGiveaway', async (global, actions, payload): Prom
|
||||
actions.openBoostStatistics({ chatId, tabId });
|
||||
});
|
||||
|
||||
addActionHandler('launchPrepaidStarsGiveaway', async (global, actions, payload): Promise<void> => {
|
||||
const {
|
||||
chatId, giveawayId, paymentPurpose, tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
|
||||
const additionalChannels = paymentPurpose?.additionalChannelIds?.map((id) => selectChat(global, id)).filter(Boolean);
|
||||
|
||||
const result = await callApi('launchPrepaidGiveaway', {
|
||||
chat,
|
||||
giveawayId,
|
||||
paymentPurpose: {
|
||||
type: 'starsgiveaway',
|
||||
chat,
|
||||
areWinnersVisible: paymentPurpose?.areWinnersVisible,
|
||||
additionalChannels,
|
||||
countries: paymentPurpose?.countries,
|
||||
prizeDescription: paymentPurpose.prizeDescription,
|
||||
untilDate: paymentPurpose.untilDate,
|
||||
currency: paymentPurpose.currency,
|
||||
amount: paymentPurpose.amount,
|
||||
stars: paymentPurpose.stars,
|
||||
users: paymentPurpose.users,
|
||||
},
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
actions.openBoostStatistics({ chatId, tabId });
|
||||
});
|
||||
|
||||
addActionHandler('loadStarStatus', async (global): Promise<void> => {
|
||||
const currentStatus = global.stars;
|
||||
const needsTopupOptions = !currentStatus?.topupOptions;
|
||||
|
||||
@ -85,6 +85,36 @@ export function getRequestInputInvoice<T extends GlobalState>(
|
||||
};
|
||||
}
|
||||
|
||||
if (inputInvoice.type === 'starsgiveaway') {
|
||||
const {
|
||||
chatId, additionalChannelIds, amount, currency, untilDate, areWinnersVisible, countries,
|
||||
isOnlyForNewSubscribers, prizeDescription, stars, users,
|
||||
} = inputInvoice;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) {
|
||||
return undefined;
|
||||
}
|
||||
const additionalChannels = additionalChannelIds?.map((id) => selectChat(global, id)).filter(Boolean);
|
||||
|
||||
return {
|
||||
type: 'starsgiveaway',
|
||||
purpose: {
|
||||
type: 'starsgiveaway',
|
||||
amount,
|
||||
currency,
|
||||
chat,
|
||||
additionalChannels,
|
||||
untilDate,
|
||||
areWinnersVisible,
|
||||
countries,
|
||||
isOnlyForNewSubscribers,
|
||||
prizeDescription,
|
||||
stars,
|
||||
users,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (inputInvoice.type === 'giveaway') {
|
||||
const {
|
||||
chatId, additionalChannelIds, amount, currency, option, untilDate, areWinnersVisible, countries,
|
||||
@ -207,3 +237,22 @@ export function getStarsTransactionFromGift(message: ApiMessage): ApiStarsTransa
|
||||
isMyGift: message.isOutgoing || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function getPrizeStarsTransactionFromGiveaway(message: ApiMessage): ApiStarsTransaction | undefined {
|
||||
const { action } = message.content;
|
||||
|
||||
if (action?.type !== 'prizeStars') return undefined;
|
||||
|
||||
const { transactionId, stars, targetChatId } = action;
|
||||
|
||||
return {
|
||||
id: transactionId!,
|
||||
stars: stars!,
|
||||
peer: {
|
||||
type: 'peer',
|
||||
id: targetChatId!,
|
||||
},
|
||||
date: message.date,
|
||||
isPrizeStars: true,
|
||||
};
|
||||
}
|
||||
|
||||
@ -54,7 +54,6 @@ import type {
|
||||
ApiPostStatistics,
|
||||
ApiPremiumGiftCodeOption,
|
||||
ApiPremiumPromo,
|
||||
ApiPrepaidGiveaway,
|
||||
ApiQuickReply,
|
||||
ApiReaction,
|
||||
ApiReactionKey,
|
||||
@ -64,7 +63,7 @@ import type {
|
||||
ApiSendMessageAction,
|
||||
ApiSession,
|
||||
ApiSessionData,
|
||||
ApiSponsoredMessage,
|
||||
ApiSponsoredMessage, ApiStarGiveawayOption,
|
||||
ApiStarsTransaction,
|
||||
ApiStarTopupOption,
|
||||
ApiStealthMode,
|
||||
@ -76,6 +75,7 @@ import type {
|
||||
ApiTimezone,
|
||||
ApiTopic,
|
||||
ApiTranscription,
|
||||
ApiTypePrepaidGiveaway,
|
||||
ApiTypeStoryView,
|
||||
ApiTypingStatus,
|
||||
ApiUpdate,
|
||||
@ -716,7 +716,8 @@ export type TabState = {
|
||||
gifts?: ApiPremiumGiftCodeOption[];
|
||||
selectedMemberIds?: string[];
|
||||
selectedChannelIds?: string[];
|
||||
prepaidGiveaway?: ApiPrepaidGiveaway;
|
||||
prepaidGiveaway?: ApiTypePrepaidGiveaway;
|
||||
starOptions?: ApiStarGiveawayOption[];
|
||||
};
|
||||
|
||||
deleteMessageModal?: {
|
||||
@ -1798,6 +1799,11 @@ export interface ActionPayloads {
|
||||
messageId: number;
|
||||
} & WithTabId;
|
||||
closeStarsTransactionModal: WithTabId | undefined;
|
||||
openPrizeStarsTransactionFromGiveaway: {
|
||||
chatId: string;
|
||||
messageId: number;
|
||||
} & WithTabId;
|
||||
closePrizeStarsTransactionFromGiveaway: WithTabId | undefined;
|
||||
sendCredentialsInfo: {
|
||||
credentials: ApiCredentials;
|
||||
} & WithTabId;
|
||||
@ -2239,6 +2245,22 @@ export interface ActionPayloads {
|
||||
};
|
||||
} & WithTabId;
|
||||
|
||||
launchPrepaidStarsGiveaway: {
|
||||
chatId: string;
|
||||
giveawayId: string;
|
||||
paymentPurpose: {
|
||||
additionalChannelIds?: string[];
|
||||
areWinnersVisible?: boolean;
|
||||
countries?: string[];
|
||||
prizeDescription?: string;
|
||||
untilDate: number;
|
||||
currency: string;
|
||||
stars: number;
|
||||
users: number;
|
||||
amount: number;
|
||||
};
|
||||
} & WithTabId;
|
||||
|
||||
loadStarStatus: undefined;
|
||||
loadStarsTransactions: {
|
||||
type: StarsTransactionType;
|
||||
@ -3248,7 +3270,7 @@ export interface ActionPayloads {
|
||||
openGiveawayModal: ({
|
||||
chatId: string;
|
||||
gifts?: number[] | undefined;
|
||||
prepaidGiveaway?: ApiPrepaidGiveaway | undefined;
|
||||
prepaidGiveaway?: ApiTypePrepaidGiveaway | undefined;
|
||||
} & WithTabId);
|
||||
closeGiveawayModal: WithTabId | undefined;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const api = require('./api');
|
||||
|
||||
const LAYER = 186;
|
||||
const LAYER = 187;
|
||||
const tlobjects = {};
|
||||
|
||||
for (const tl of Object.values(api)) {
|
||||
|
||||
176
src/lib/gramjs/tl/api.d.ts
vendored
176
src/lib/gramjs/tl/api.d.ts
vendored
File diff suppressed because one or more lines are too long
@ -36,7 +36,7 @@ inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> s
|
||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||
inputMediaStory#89fdd778 peer:InputPeer id:int = InputMedia;
|
||||
inputMediaWebPage#c21b8849 flags:# force_large_media:flags.0?true force_small_media:flags.1?true optional:flags.2?true url:string = InputMedia;
|
||||
inputMediaPaidMedia#aa661fc3 stars_amount:long extended_media:Vector<InputMedia> = InputMedia;
|
||||
inputMediaPaidMedia#c4103386 flags:# stars_amount:long extended_media:Vector<InputMedia> payload:flags.0?string = InputMedia;
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
inputChatUploadedPhoto#bdcdaec0 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double video_emoji_markup:flags.3?VideoSize = InputChatPhoto;
|
||||
inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto;
|
||||
@ -108,8 +108,8 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = 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;
|
||||
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;
|
||||
messageMediaGiveawayResults#c6991068 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:int prize_description:flags.1?string until_date:int = MessageMedia;
|
||||
messageMediaGiveaway#aa073beb 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:flags.4?int stars:flags.5?long until_date:int = MessageMedia;
|
||||
messageMediaGiveawayResults#ceaa3ea1 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:flags.4?int stars:flags.5?long prize_description:flags.1?string until_date:int = MessageMedia;
|
||||
messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector<MessageExtendedMedia> = MessageMedia;
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
|
||||
@ -150,12 +150,13 @@ messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
||||
messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = MessageAction;
|
||||
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
|
||||
messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
|
||||
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
||||
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionGiveawayLaunch#a80f51e4 flags:# stars:flags.0?long = MessageAction;
|
||||
messageActionGiveawayResults#87e2f155 flags:# stars:flags.0?true winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
|
||||
messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPeer> = MessageAction;
|
||||
messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction;
|
||||
messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction;
|
||||
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
@ -369,6 +370,8 @@ updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueB
|
||||
updateStarsBalance#fb85198 balance:long = Update;
|
||||
updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update;
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
|
||||
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
|
||||
updatePaidReactionPrivacy#51ca7aec private:Bool = Update;
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
||||
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
||||
@ -830,9 +833,10 @@ channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_valu
|
||||
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleSignatureProfiles#60a79c79 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionParticipantSubExtend#64642db3 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter;
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true sub_extend:flags.18?true = ChannelAdminLogEventsFilter;
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
|
||||
messages.favedStickers#2cb51097 hash:long packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
|
||||
@ -1117,6 +1121,7 @@ inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_
|
||||
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;
|
||||
inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long 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 users:int = InputStorePaymentPurpose;
|
||||
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
emojiStatusEmpty#2de11aae = EmojiStatus;
|
||||
@ -1218,9 +1223,10 @@ messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User>
|
||||
premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption;
|
||||
payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?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.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#e175e66f flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.3?string stars_prize:flags.4?long finish_date:int winners_count:int activated_count:flags.2?int = payments.GiveawayInfo;
|
||||
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
|
||||
boost#2a1c8c71 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int = Boost;
|
||||
prepaidStarsGiveaway#9a9d77e0 id:long stars:long quantity:int boosts:int date:int = PrepaidGiveaway;
|
||||
boost#4b3e14d6 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int stars:flags.6?long = Boost;
|
||||
premium.boostsList#86f8613c flags:# count:int boosts:Vector<Boost> next_offset:flags.0?string users:Vector<User> = premium.BoostsList;
|
||||
myBoost#c448415c flags:# slot:int peer:flags.0?Peer date:int expires:int cooldown_until_date:flags.1?int = MyBoost;
|
||||
premium.myBoosts#9ae228e2 my_boosts:Vector<MyBoost> chats:Vector<Chat> users:Vector<User> = premium.MyBoosts;
|
||||
@ -1310,7 +1316,7 @@ stats.broadcastRevenueTransactions#87158466 count:int transactions:Vector<Broadc
|
||||
reactionNotificationsFromContacts#bac3a61a = ReactionNotificationsFrom;
|
||||
reactionNotificationsFromAll#4b9e22a0 = ReactionNotificationsFrom;
|
||||
reactionsNotifySettings#56e34970 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings;
|
||||
broadcastRevenueBalances#8438f1c6 current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances;
|
||||
broadcastRevenueBalances#c3ff71e7 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances;
|
||||
availableEffect#93c3e27e flags:# premium_required:flags.2?true id:long emoticon:string static_icon_id:flags.0?long effect_sticker_id:long effect_animation_id:flags.1?long = AvailableEffect;
|
||||
messages.availableEffectsNotModified#d1ed9a5b = messages.AvailableEffects;
|
||||
messages.availableEffects#bddb616e hash:int effects:Vector<AvailableEffect> documents:Vector<Document> = messages.AvailableEffects;
|
||||
@ -1323,7 +1329,7 @@ starsTransactionPeerFragment#e92fd902 = StarsTransactionPeer;
|
||||
starsTransactionPeer#d80da15d peer:Peer = StarsTransactionPeer;
|
||||
starsTransactionPeerAds#60682812 = StarsTransactionPeer;
|
||||
starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption;
|
||||
starsTransaction#433aeb2b flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int = StarsTransaction;
|
||||
starsTransaction#ee7522d5 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int = StarsTransaction;
|
||||
payments.starsStatus#bbfa316c flags:# balance:long subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus;
|
||||
foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory;
|
||||
stories.foundStories#e2de7737 flags:# count:int stories:Vector<FoundStory> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = stories.FoundStories;
|
||||
@ -1340,6 +1346,8 @@ bots.previewInfo#ca71d64 media:Vector<BotPreviewMedia> lang_codes:Vector<string>
|
||||
starsSubscriptionPricing#5416d58 period:int amount:long = StarsSubscriptionPricing;
|
||||
starsSubscription#538ecf18 flags:# canceled:flags.0?true can_refulfill:flags.1?true missing_balance:flags.2?true id:string peer:Peer until_date:int pricing:StarsSubscriptionPricing chat_invite_hash:flags.3?string = StarsSubscription;
|
||||
messageReactor#4ba3a95a flags:# top:flags.0?true my:flags.1?true anonymous:flags.2?true peer_id:flags.3?Peer count:int = MessageReactor;
|
||||
starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true stars:long yearly_boosts:int store_product:flags.2?string currency:string amount:long winners:Vector<StarsGiveawayWinnersOption> = StarsGiveawayOption;
|
||||
starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption;
|
||||
---functions---
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
|
||||
@ -1643,6 +1651,7 @@ payments.sendStarsForm#2bb731d flags:# form_id:long invoice:InputInvoice = payme
|
||||
payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates;
|
||||
payments.getStarsTransactionsByID#27842d2e peer:InputPeer id:Vector<InputStarsTransaction> = payments.StarsStatus;
|
||||
payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector<StarsGiftOption>;
|
||||
payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>;
|
||||
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
|
||||
@ -368,6 +368,7 @@
|
||||
"payments.getStarsTransactionsByID",
|
||||
"payments.sendStarsForm",
|
||||
"payments.getStarsGiftOptions",
|
||||
"payments.getStarsGiveawayOptions",
|
||||
"payments.refundStarsCharge",
|
||||
"payments.getStarsGiftOptions",
|
||||
"fragment.getCollectibleInfo"
|
||||
|
||||
@ -45,7 +45,7 @@ inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> s
|
||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||
inputMediaStory#89fdd778 peer:InputPeer id:int = InputMedia;
|
||||
inputMediaWebPage#c21b8849 flags:# force_large_media:flags.0?true force_small_media:flags.1?true optional:flags.2?true url:string = InputMedia;
|
||||
inputMediaPaidMedia#aa661fc3 stars_amount:long extended_media:Vector<InputMedia> = InputMedia;
|
||||
inputMediaPaidMedia#c4103386 flags:# stars_amount:long extended_media:Vector<InputMedia> payload:flags.0?string = InputMedia;
|
||||
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
inputChatUploadedPhoto#bdcdaec0 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double video_emoji_markup:flags.3?VideoSize = InputChatPhoto;
|
||||
@ -133,8 +133,8 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = 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;
|
||||
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;
|
||||
messageMediaGiveawayResults#c6991068 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:int prize_description:flags.1?string until_date:int = MessageMedia;
|
||||
messageMediaGiveaway#aa073beb 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:flags.4?int stars:flags.5?long until_date:int = MessageMedia;
|
||||
messageMediaGiveawayResults#ceaa3ea1 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:flags.4?int stars:flags.5?long prize_description:flags.1?string until_date:int = MessageMedia;
|
||||
messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector<MessageExtendedMedia> = MessageMedia;
|
||||
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
@ -176,12 +176,13 @@ messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
||||
messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = MessageAction;
|
||||
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
|
||||
messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
|
||||
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
||||
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionGiveawayLaunch#a80f51e4 flags:# stars:flags.0?long = MessageAction;
|
||||
messageActionGiveawayResults#87e2f155 flags:# stars:flags.0?true winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
|
||||
messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector<RequestedPeer> = MessageAction;
|
||||
messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction;
|
||||
messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction;
|
||||
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
|
||||
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
@ -422,6 +423,8 @@ updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueB
|
||||
updateStarsBalance#fb85198 balance:long = Update;
|
||||
updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update;
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
|
||||
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
|
||||
updatePaidReactionPrivacy#51ca7aec private:Bool = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -1013,12 +1016,13 @@ channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_valu
|
||||
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleSignatureProfiles#60a79c79 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionParticipantSubExtend#64642db3 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
||||
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter;
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true sub_extend:flags.18?true = ChannelAdminLogEventsFilter;
|
||||
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
|
||||
@ -1472,6 +1476,7 @@ inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_
|
||||
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;
|
||||
inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long 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 users:int = InputStorePaymentPurpose;
|
||||
|
||||
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
||||
|
||||
@ -1633,11 +1638,12 @@ premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.
|
||||
payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?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.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#e175e66f flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.3?string stars_prize:flags.4?long finish_date:int winners_count:int activated_count:flags.2?int = payments.GiveawayInfo;
|
||||
|
||||
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
|
||||
prepaidStarsGiveaway#9a9d77e0 id:long stars:long quantity:int boosts:int date:int = PrepaidGiveaway;
|
||||
|
||||
boost#2a1c8c71 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int = Boost;
|
||||
boost#4b3e14d6 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int stars:flags.6?long = Boost;
|
||||
|
||||
premium.boostsList#86f8613c flags:# count:int boosts:Vector<Boost> next_offset:flags.0?string users:Vector<User> = premium.BoostsList;
|
||||
|
||||
@ -1795,7 +1801,7 @@ reactionNotificationsFromAll#4b9e22a0 = ReactionNotificationsFrom;
|
||||
|
||||
reactionsNotifySettings#56e34970 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings;
|
||||
|
||||
broadcastRevenueBalances#8438f1c6 current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances;
|
||||
broadcastRevenueBalances#c3ff71e7 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances;
|
||||
|
||||
availableEffect#93c3e27e flags:# premium_required:flags.2?true id:long emoticon:string static_icon_id:flags.0?long effect_sticker_id:long effect_animation_id:flags.1?long = AvailableEffect;
|
||||
|
||||
@ -1814,7 +1820,7 @@ starsTransactionPeerAds#60682812 = StarsTransactionPeer;
|
||||
|
||||
starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption;
|
||||
|
||||
starsTransaction#433aeb2b flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int = StarsTransaction;
|
||||
starsTransaction#ee7522d5 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> subscription_period:flags.12?int giveaway_post_id:flags.13?int = StarsTransaction;
|
||||
|
||||
payments.starsStatus#bbfa316c flags:# balance:long subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus;
|
||||
|
||||
@ -1848,6 +1854,10 @@ starsSubscription#538ecf18 flags:# canceled:flags.0?true can_refulfill:flags.1?t
|
||||
|
||||
messageReactor#4ba3a95a flags:# top:flags.0?true my:flags.1?true anonymous:flags.2?true peer_id:flags.3?Peer count:int = MessageReactor;
|
||||
|
||||
starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true stars:long yearly_boosts:int store_product:flags.2?string currency:string amount:long winners:Vector<StarsGiveawayWinnersOption> = StarsGiveawayOption;
|
||||
|
||||
starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -2244,8 +2254,9 @@ messages.editFactCheck#589ee75 peer:InputPeer msg_id:int text:TextWithEntities =
|
||||
messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates;
|
||||
messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCheck>;
|
||||
messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
|
||||
messages.sendPaidReaction#25c8fe3e flags:# private:flags.0?true peer:InputPeer msg_id:int count:int random_id:long = Updates;
|
||||
messages.sendPaidReaction#9dd6a67b flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?Bool = Updates;
|
||||
messages.togglePaidReactionPrivacy#849ad397 peer:InputPeer msg_id:int private:Bool = Bool;
|
||||
messages.getPaidReactionPrivacy#472455aa = Updates;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
||||
@ -2411,6 +2422,7 @@ payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector
|
||||
payments.getStarsSubscriptions#32512c5 flags:# missing_balance:flags.0?true peer:InputPeer offset:string = payments.StarsStatus;
|
||||
payments.changeStarsSubscription#c7770878 flags:# peer:InputPeer subscription_id:string canceled:flags.0?Bool = Bool;
|
||||
payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool;
|
||||
payments.getStarsGiveawayOptions#bd1efd3e = Vector<StarsGiveawayOption>;
|
||||
|
||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||
|
||||
@ -514,14 +514,16 @@ export type InlineBotSettings = {
|
||||
};
|
||||
|
||||
export type CustomPeerType = 'premium' | 'toBeDistributed' | 'contacts' | 'nonContacts'
|
||||
| 'groups' | 'channels' | 'bots' | 'excludeMuted' | 'excludeArchived' | 'excludeRead';
|
||||
| 'groups' | 'channels' | 'bots' | 'excludeMuted' | 'excludeArchived' | 'excludeRead' | 'stars';
|
||||
|
||||
export interface CustomPeer {
|
||||
isCustomPeer: true;
|
||||
key?: string | number;
|
||||
titleKey: string;
|
||||
subtitleKey?: string;
|
||||
avatarIcon: IconName;
|
||||
isAvatarSquare?: boolean;
|
||||
titleValue?: number;
|
||||
peerColorId?: number;
|
||||
customPeerAvatarColor?: string;
|
||||
withPremiumGradient?: boolean;
|
||||
|
||||
3
src/types/language.d.ts
vendored
3
src/types/language.d.ts
vendored
@ -1539,6 +1539,9 @@ export interface LangPair {
|
||||
'GiftStarsOutgoing': {
|
||||
'user': string | number;
|
||||
};
|
||||
'PrizeCredits': {
|
||||
'count': string | number;
|
||||
};
|
||||
}
|
||||
|
||||
export type LangKey = keyof LangPair;
|
||||
|
||||
@ -18,6 +18,14 @@ export const CUSTOM_PEER_TO_BE_DISTRIBUTED: UniqueCustomPeer = {
|
||||
withPremiumGradient: true,
|
||||
};
|
||||
|
||||
export const CUSTOM_PEER_STAR: UniqueCustomPeer = {
|
||||
isCustomPeer: true,
|
||||
type: 'stars',
|
||||
titleKey: 'Stars',
|
||||
avatarIcon: 'star',
|
||||
peerColorId: 1,
|
||||
};
|
||||
|
||||
export const CUSTOM_PEER_INCLUDED_CHAT_TYPES: UniqueCustomPeer[] = [
|
||||
{
|
||||
isCustomPeer: true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user