diff --git a/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs b/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs new file mode 100644 index 0000000000..60709e5bbd Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs differ diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 42bf87629b..733f79ef20 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1565,3 +1565,52 @@ public struct StarsSubscriptionConfiguration { } } } + +public struct TranslationConfiguration { + static var defaultValue: TranslationConfiguration { + return TranslationConfiguration(manual: .disabled, auto: .disabled) + } + + public enum TranslationAvailability { + case enabled + case system + case alternative + case disabled + + init(string: String) { + switch string { + case "enabled": + #if DEBUG + self = .system + #else + self = .enabled + #endif + case "system": + self = .system + case "alternative": + self = .alternative + default: + self = .disabled + } + } + } + + public let manual: TranslationAvailability + public let auto: TranslationAvailability + + fileprivate init(manual: TranslationAvailability, auto: TranslationAvailability) { + self.manual = manual + self.auto = auto + } + + public static func with(appConfiguration: AppConfiguration) -> TranslationConfiguration { + if let data = appConfiguration.data { + let manualValue = data["translations_manual_enabled"] as? String ?? "disabled" + let autoValue = data["translations_auto_enabled"] as? String ?? "disabled" + + return TranslationConfiguration(manual: TranslationAvailability(string: manualValue), auto: TranslationAvailability(string: autoValue)) + } else { + return .defaultValue + } + } +} diff --git a/submodules/PremiumUI/Resources/diamond.scn b/submodules/PremiumUI/Resources/diamond.scn deleted file mode 100644 index 882a662d15..0000000000 Binary files a/submodules/PremiumUI/Resources/diamond.scn and /dev/null differ diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 60f72dcce5..23b85bf85f 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -827,7 +827,7 @@ public enum PremiumPerk: CaseIterable { case .paidMessages: return "Premium/Perk/PaidMessages" case .todo: - return "Premium/Perk/PaidMessages" + return "Premium/Perk/Todo" case .businessLocation: return "Premium/BusinessPerk/Location" case .businessHours: @@ -858,6 +858,7 @@ struct PremiumIntroConfiguration { .voiceToText, .fasterDownload, .translation, + .todo, .animatedEmoji, .emojiStatus, .messageEffects, @@ -2172,6 +2173,8 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent { demoSubject = .messageEffects case .paidMessages: demoSubject = .paidMessages + case .todo: + demoSubject = .todo case .business: demoSubject = .business let _ = ApplicationSpecificNotice.setDismissedBusinessBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone() @@ -3699,6 +3702,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { let buttonTitle: String var buttonSubtitle: String? if case let .auth(price) = context.component.source { + //TODO:localize buttonTitle = "Sign up for \(price)" buttonSubtitle = "Get Telegram Premium for 1 week" } else if isUnusedGift { diff --git a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift index 7807536eee..fcb305ae46 100644 --- a/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift +++ b/submodules/SettingsUI/Sources/Language Selection/LocalizationListControllerNode.swift @@ -431,6 +431,32 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { }) } + let translationConfiguration = TranslationConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + var translateButtonAvailable = false + var chatTranslationAvailable = false + + switch translationConfiguration.manual { + case .enabled, .alternative: + translateButtonAvailable = true + case .system: + if #available(iOS 18.0, *) { + translateButtonAvailable = true + } + default: + break + } + + switch translationConfiguration.auto { + case .enabled: + chatTranslationAvailable = true + case .system: + if #available(iOS 18.0, *) { + chatTranslationAvailable = true + } + default: + break + } + let previousState = Atomic(value: nil) let previousEntriesHolder = Atomic<([LanguageListEntry], PresentationTheme, PresentationStrings)?>(value: nil) self.listDisposable = combineLatest( @@ -465,7 +491,6 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { if let languages = translationSettings.ignoredLanguages { ignoredLanguages = languages } else { - if var activeLanguage = activeLanguageCode { let rawSuffix = "-raw" if activeLanguage.hasSuffix(rawSuffix) { @@ -497,12 +522,15 @@ final class LocalizationListControllerNode: ViewControllerTracingNode { if !localizationListState.availableOfficialLocalizations.isEmpty { strongSelf.currentListState = localizationListState - if #available(iOS 12.0, *) { + if translateButtonAvailable || chatTranslationAvailable { entries.append(.translateTitle(text: presentationData.strings.Localization_TranslateMessages.uppercased())) - entries.append(.translate(text: presentationData.strings.Localization_ShowTranslate, value: showTranslate)) - - entries.append(.translateEntire(text: presentationData.strings.Localization_TranslateEntireChat, value: translateChats, locked: !isPremium)) + if translateButtonAvailable { + entries.append(.translate(text: presentationData.strings.Localization_ShowTranslate, value: showTranslate)) + } + if chatTranslationAvailable { + entries.append(.translateEntire(text: presentationData.strings.Localization_TranslateEntireChat, value: translateChats, locked: !isPremium)) + } var value = "" if ignoredLanguages.count > 1 { diff --git a/submodules/StatisticsUI/Sources/ChannelStatsController.swift b/submodules/StatisticsUI/Sources/ChannelStatsController.swift index e2559fbacc..382a785978 100644 --- a/submodules/StatisticsUI/Sources/ChannelStatsController.swift +++ b/submodules/StatisticsUI/Sources/ChannelStatsController.swift @@ -51,7 +51,7 @@ private final class ChannelStatsControllerArguments { let buyAds: () -> Void let openMonetizationIntro: () -> Void let openMonetizationInfo: () -> Void - let openTonTransaction: (RevenueStatsTransactionsContext.State.Transaction) -> Void + let openTonTransaction: (StarsContext.State.Transaction) -> Void let openStarsTransaction: (StarsContext.State.Transaction) -> Void let expandTransactions: (Bool) -> Void let updateCpmEnabled: (Bool) -> Void @@ -59,7 +59,7 @@ private final class ChannelStatsControllerArguments { let openEarnStars: () -> Void let dismissInput: () -> Void - init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal, openPostStats: @escaping (EnginePeer, StatsPostItem) -> Void, openStory: @escaping (EngineStoryItem, UIView) -> Void, contextAction: @escaping (MessageId, ASDisplayNode, ContextGesture?) -> Void, copyBoostLink: @escaping (String) -> Void, shareBoostLink: @escaping (String) -> Void, openBoost: @escaping (ChannelBoostersContext.State.Boost) -> Void, expandBoosters: @escaping () -> Void, openGifts: @escaping () -> Void, createPrepaidGiveaway: @escaping (PrepaidGiveaway) -> Void, updateGiftsSelected: @escaping (Bool) -> Void, updateStarsSelected: @escaping (Bool) -> Void, requestTonWithdraw: @escaping () -> Void, requestStarsWithdraw: @escaping () -> Void, showTimeoutTooltip: @escaping (Int32) -> Void, buyAds: @escaping () -> Void, openMonetizationIntro: @escaping () -> Void, openMonetizationInfo: @escaping () -> Void, openTonTransaction: @escaping (RevenueStatsTransactionsContext.State.Transaction) -> Void, openStarsTransaction: @escaping (StarsContext.State.Transaction) -> Void, expandTransactions: @escaping (Bool) -> Void, updateCpmEnabled: @escaping (Bool) -> Void, presentCpmLocked: @escaping () -> Void, openEarnStars: @escaping () -> Void, dismissInput: @escaping () -> Void) { + init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal, openPostStats: @escaping (EnginePeer, StatsPostItem) -> Void, openStory: @escaping (EngineStoryItem, UIView) -> Void, contextAction: @escaping (MessageId, ASDisplayNode, ContextGesture?) -> Void, copyBoostLink: @escaping (String) -> Void, shareBoostLink: @escaping (String) -> Void, openBoost: @escaping (ChannelBoostersContext.State.Boost) -> Void, expandBoosters: @escaping () -> Void, openGifts: @escaping () -> Void, createPrepaidGiveaway: @escaping (PrepaidGiveaway) -> Void, updateGiftsSelected: @escaping (Bool) -> Void, updateStarsSelected: @escaping (Bool) -> Void, requestTonWithdraw: @escaping () -> Void, requestStarsWithdraw: @escaping () -> Void, showTimeoutTooltip: @escaping (Int32) -> Void, buyAds: @escaping () -> Void, openMonetizationIntro: @escaping () -> Void, openMonetizationInfo: @escaping () -> Void, openTonTransaction: @escaping (StarsContext.State.Transaction) -> Void, openStarsTransaction: @escaping (StarsContext.State.Transaction) -> Void, expandTransactions: @escaping (Bool) -> Void, updateCpmEnabled: @escaping (Bool) -> Void, presentCpmLocked: @escaping () -> Void, openEarnStars: @escaping () -> Void, dismissInput: @escaping () -> Void) { self.context = context self.loadDetailedGraph = loadDetailedGraph self.openPostStats = openPostStats @@ -242,11 +242,11 @@ private enum StatsEntry: ItemListNodeEntry { case adsStarsRevenueGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType, Double) case adsProceedsTitle(PresentationTheme, String) - case adsProceedsOverview(PresentationTheme, RevenueStats?, StarsRevenueStats?) + case adsProceedsOverview(PresentationTheme, StarsRevenueStats?, StarsRevenueStats?) case adsProceedsInfo(PresentationTheme, String) case adsTonBalanceTitle(PresentationTheme, String) - case adsTonBalance(PresentationTheme, RevenueStats, Bool, Bool) + case adsTonBalance(PresentationTheme, StarsRevenueStats, Bool, Bool) case adsTonBalanceInfo(PresentationTheme, String) case adsStarsBalanceTitle(PresentationTheme, String) @@ -256,7 +256,7 @@ private enum StatsEntry: ItemListNodeEntry { case earnStarsInfo case adsTransactionsTitle(PresentationTheme, String) case adsTransactionsTabs(PresentationTheme, String, String, Bool) - case adsTransaction(Int32, PresentationTheme, RevenueStatsTransactionsContext.State.Transaction) + case adsTransaction(Int32, PresentationTheme, StarsContext.State.Transaction) case adsStarsTransaction(Int32, PresentationTheme, StarsContext.State.Transaction) case adsTransactionsExpand(PresentationTheme, String, Bool) @@ -1155,8 +1155,7 @@ private enum StatsEntry: ItemListNodeEntry { let detailText: String var detailColor: ItemListDisclosureItemDetailLabelColor = .generic - switch transaction { - case let .proceeds(_, fromDate, toDate): + if let fromDate = transaction.adsProceedsFromDate, let toDate = transaction.adsProceedsToDate { title = NSAttributedString(string: presentationData.strings.Monetization_Transaction_Proceeds, font: font, textColor: theme.list.itemPrimaryTextColor) let fromDateString = stringForMediumCompactDate(timestamp: fromDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, withTime: false) let toDateString = stringForMediumCompactDate(timestamp: toDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, withTime: false) @@ -1165,24 +1164,26 @@ private enum StatsEntry: ItemListNodeEntry { } else { detailText = "\(fromDateString) – \(toDateString)" } - case let .withdrawal(status, _, date, provider, _, _): - title = NSAttributedString(string: presentationData.strings.Monetization_Transaction_Withdrawal(provider).string, font: font, textColor: theme.list.itemPrimaryTextColor) + } else if case .fragment = transaction.peer { + title = NSAttributedString(string: presentationData.strings.Monetization_Transaction_Withdrawal("Fragment").string, font: font, textColor: theme.list.itemPrimaryTextColor) labelColor = theme.list.itemDestructiveColor - switch status { - case .succeed: - detailText = stringForMediumCompactDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) - case .failed: - detailText = stringForMediumCompactDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, withTime: false) + " – \(presentationData.strings.Monetization_Transaction_Failed)" - detailColor = .destructive - case .pending: + if transaction.flags.contains(.isPending) { detailText = presentationData.strings.Monetization_Transaction_Pending + } else if transaction.flags.contains(.isFailed) { + detailText = stringForMediumCompactDate(timestamp: transaction.date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, withTime: false) + " – \(presentationData.strings.Monetization_Transaction_Failed)" + detailColor = .destructive + } else { + detailText = stringForMediumCompactDate(timestamp: transaction.date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) } - case let .refund(_, date, _): + } else if transaction.flags.contains(.isRefund) { title = NSAttributedString(string: presentationData.strings.Monetization_Transaction_Refund, font: font, textColor: theme.list.itemPrimaryTextColor) - detailText = stringForMediumCompactDate(timestamp: date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) + detailText = stringForMediumCompactDate(timestamp: transaction.date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) + } else { + title = NSAttributedString() + detailText = "" } - let label = tonAmountAttributedString(formatTonAmountText(transaction.amount, dateTimeFormat: presentationData.dateTimeFormat, showPlus: true), integralFont: font, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString + let label = tonAmountAttributedString(formatTonAmountText(transaction.count.amount.value, dateTimeFormat: presentationData.dateTimeFormat, showPlus: true), integralFont: font, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString label.insert(NSAttributedString(string: " $ ", font: font, textColor: labelColor), at: 1) if let range = label.string.range(of: "$"), let icon = generateTintedImage(image: UIImage(bundleImageName: "Ads/TonMedium"), color: labelColor) { @@ -1565,9 +1566,9 @@ private func monetizationEntries( presentationData: PresentationData, state: ChannelStatsControllerState, peer: EnginePeer?, - data: RevenueStats?, + data: StarsRevenueStats?, boostData: ChannelBoostStatus?, - transactionsInfo: RevenueStatsTransactionsContext.State, + transactionsInfo: StarsTransactionsContext.State, starsData: StarsRevenueStats?, starsTransactionsInfo: StarsTransactionsContext.State, adsRestricted: Bool, @@ -1587,9 +1588,9 @@ private func monetizationEntries( if canViewRevenue, let data { entries.append(.adsHeader(presentationData.theme, isBot ? presentationData.strings.Monetization_Bot_Header : presentationData.strings.Monetization_Header)) - if !data.topHoursGraph.isEmpty { + if let topHoursGraph = data.topHoursGraph, !topHoursGraph.isEmpty { entries.append(.adsImpressionsTitle(presentationData.theme, presentationData.strings.Monetization_ImpressionsTitle)) - entries.append(.adsImpressionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.topHoursGraph, .hourlyStep)) + entries.append(.adsImpressionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, topHoursGraph, .hourlyStep)) } if !data.revenueGraph.isEmpty { @@ -1608,8 +1609,8 @@ private func monetizationEntries( entries.append(.adsProceedsTitle(presentationData.theme, presentationData.strings.Monetization_StarsProceeds_Title)) entries.append(.adsProceedsOverview(presentationData.theme, canViewRevenue ? data : nil, canViewStarsRevenue ? starsData : nil)) - let hasTonBalance = (data?.balances.overallRevenue ?? 0) > 0 - let hasStarsBalance = (starsData?.balances.overallRevenue ?? StarsAmount.zero) > StarsAmount.zero + let hasTonBalance = (data?.balances.overallRevenue.amount ?? StarsAmount.zero) > StarsAmount.zero + let hasStarsBalance = (starsData?.balances.overallRevenue.amount ?? StarsAmount.zero) > StarsAmount.zero let proceedsInfo: String if (canViewStarsRevenue && hasStarsBalance) && (canViewRevenue && hasTonBalance) { @@ -1632,11 +1633,11 @@ private func monetizationEntries( if canViewRevenue, let data { entries.append(.adsTonBalanceTitle(presentationData.theme, isBot ? presentationData.strings.Monetization_Bot_BalanceTitle : presentationData.strings.Monetization_TonBalanceTitle)) - entries.append(.adsTonBalance(presentationData.theme, data, (isCreator || isBot) && data.balances.availableBalance > 0, data.balances.withdrawEnabled)) + entries.append(.adsTonBalance(presentationData.theme, data, (isCreator || isBot) && data.balances.availableBalance.amount > StarsAmount.zero, data.balances.withdrawEnabled)) if isCreator || isBot { let withdrawalInfoText: String - if data.balances.availableBalance == 0 { + if data.balances.availableBalance.amount == StarsAmount.zero { withdrawalInfoText = presentationData.strings.Monetization_Balance_ZeroInfo } else if monetizationConfiguration.withdrawalAvailable { withdrawalInfoText = presentationData.strings.Monetization_Balance_AvailableInfo @@ -1647,9 +1648,9 @@ private func monetizationEntries( } } - if canViewStarsRevenue, let starsData, starsData.balances.overallRevenue > StarsAmount.zero { + if canViewStarsRevenue, let starsData, starsData.balances.overallRevenue.amount > StarsAmount.zero { entries.append(.adsStarsBalanceTitle(presentationData.theme, presentationData.strings.Monetization_StarsBalanceTitle)) - entries.append(.adsStarsBalance(presentationData.theme, starsData, isCreator && starsData.balances.availableBalance > StarsAmount.zero, !isGroup, starsData.balances.withdrawEnabled, starsData.balances.nextWithdrawalTimestamp)) + entries.append(.adsStarsBalance(presentationData.theme, starsData, isCreator && starsData.balances.availableBalance.amount > StarsAmount.zero, !isGroup, starsData.balances.withdrawEnabled, starsData.balances.nextWithdrawalTimestamp)) entries.append(.adsStarsBalanceInfo(presentationData.theme, isGroup ? presentationData.strings.Monetization_Balance_StarsInfoGroup : presentationData.strings.Monetization_Balance_StarsInfo)) } @@ -1693,12 +1694,12 @@ private func monetizationEntries( i += 1 } - if transactions.count < transactionsInfo.count { + if transactionsInfo.canLoadMore || transactionsInfo.transactions.count > transactions.count { let moreCount: Int32 if !state.transactionsExpanded { - moreCount = min(20, transactionsInfo.count - Int32(transactions.count)) + moreCount = min(20, Int32(transactionsInfo.transactions.count - transactions.count)) } else { - moreCount = min(50, transactionsInfo.count - Int32(transactions.count)) + moreCount = min(50, Int32(transactionsInfo.transactions.count - transactions.count)) } entries.append(.adsTransactionsExpand(presentationData.theme, presentationData.strings.Monetization_Transaction_ShowMoreTransactions(moreCount), false)) } @@ -1762,8 +1763,8 @@ private func channelStatsControllerEntries( giveawayAvailable: Bool, isGroup: Bool, boostsOnly: Bool, - revenueState: RevenueStats?, - revenueTransactions: RevenueStatsTransactionsContext.State, + revenueState: StarsRevenueStats?, + revenueTransactions: StarsTransactionsContext.State, starsState: StarsRevenueStats?, starsTransactions: StarsTransactionsContext.State, adsRestricted: Bool, @@ -1826,7 +1827,7 @@ public func channelStatsController( updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peerId: PeerId, section: ChannelStatsSection = .stats, - existingRevenueContext: RevenueStatsContext? = nil, + existingRevenueContext: StarsRevenueStatsContext? = nil, existingStarsRevenueContext: StarsRevenueStatsContext? = nil, boostStatus: ChannelBoostStatus? = nil, boostStatusUpdated: ((ChannelBoostStatus) -> Void)? = nil @@ -1887,15 +1888,16 @@ public func channelStatsController( let boostsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: false) let giftsContext = ChannelBoostersContext(account: context.account, peerId: peerId, gift: true) - let revenueContext = existingRevenueContext ?? RevenueStatsContext(account: context.account, peerId: peerId) - let revenueState = Promise() + let revenueContext = existingRevenueContext ?? context.engine.payments.peerStarsRevenueContext(peerId: peerId, ton: true) + let revenueState = Promise() revenueState.set(.single(nil) |> then(revenueContext.state |> map(Optional.init))) - let starsContext = existingStarsRevenueContext ?? context.engine.payments.peerStarsRevenueContext(peerId: peerId) + let starsContext = existingStarsRevenueContext ?? context.engine.payments.peerStarsRevenueContext(peerId: peerId, ton: false) let starsState = Promise() starsState.set(.single(nil) |> then(starsContext.state |> map(Optional.init))) - let revenueTransactions = RevenueStatsTransactionsContext(account: context.account, peerId: peerId) + let revenueTransactions = context.engine.payments.peerStarsTransactionsContext(subject: .peer(peerId: peerId, ton: true), mode: .all) + revenueTransactions.loadMore() let starsTransactions = context.engine.payments.peerStarsTransactionsContext(subject: .peer(peerId: peerId, ton: false), mode: .all) starsTransactions.loadMore() @@ -1906,7 +1908,7 @@ public func channelStatsController( var navigateToChatImpl: ((EnginePeer) -> Void)? var navigateToMessageImpl: ((EngineMessage.Id) -> Void)? var openBoostImpl: ((Bool) -> Void)? - var openTonTransactionImpl: ((RevenueStatsTransactionsContext.State.Transaction) -> Void)? + var openTonTransactionImpl: ((StarsContext.State.Transaction) -> Void)? var openStarsTransactionImpl: ((StarsContext.State.Transaction) -> Void)? var requestTonWithdrawImpl: (() -> Void)? var requestStarsWithdrawImpl: (() -> Void)? @@ -2514,7 +2516,7 @@ public func channelStatsController( } } requestTonWithdrawImpl = { - withdrawalDisposable.set((context.engine.peers.checkChannelRevenueWithdrawalAvailability() + withdrawalDisposable.set((context.engine.peers.checkStarsRevenueWithdrawalAvailability() |> deliverOnMainQueue).start(error: { error in let controller = revenueWithdrawalController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, initialError: error, present: { c, _ in presentImpl?(c) diff --git a/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift b/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift index b85bbdeb10..3c9d2c4f20 100644 --- a/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift +++ b/submodules/StatisticsUI/Sources/MonetizationBalanceItem.swift @@ -175,14 +175,17 @@ final class MonetizationBalanceItemNode: ListViewItemNode, ItemListItemNode { let value: String var isStars = false - if let stats = item.stats as? RevenueStats { - let cryptoValue = formatTonAmountText(stats.balances.availableBalance, dateTimeFormat: item.presentationData.dateTimeFormat) - amountString = tonAmountAttributedString(cryptoValue, integralFont: integralFont, fractionalFont: fractionalFont, color: item.presentationData.theme.list.itemPrimaryTextColor, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator) - value = stats.balances.availableBalance == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))" - } else if let stats = item.stats as? StarsRevenueStats { - amountString = NSAttributedString(string: presentationStringsFormattedNumber(stats.balances.availableBalance, item.presentationData.dateTimeFormat.groupingSeparator), font: integralFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor) - value = stats.balances.availableBalance == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))" - isStars = true + if let stats = item.stats as? StarsRevenueStats { + switch stats.balances.availableBalance.currency { + case .ton: + let cryptoValue = formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat) + amountString = tonAmountAttributedString(cryptoValue, integralFont: integralFont, fractionalFont: fractionalFont, color: item.presentationData.theme.list.itemPrimaryTextColor, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator) + value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))" + case .stars: + amountString = NSAttributedString(string: presentationStringsFormattedNumber(stats.balances.availableBalance.amount, item.presentationData.dateTimeFormat.groupingSeparator), font: integralFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor) + value = stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))" + isStars = true + } } else { fatalError() } diff --git a/submodules/StatisticsUI/Sources/RevenueWithdrawalController.swift b/submodules/StatisticsUI/Sources/RevenueWithdrawalController.swift index 7664d1e2cd..174ed110a3 100644 --- a/submodules/StatisticsUI/Sources/RevenueWithdrawalController.swift +++ b/submodules/StatisticsUI/Sources/RevenueWithdrawalController.swift @@ -46,7 +46,7 @@ func confirmRevenueWithdrawalController(context: AccountContext, updatedPresenta } contentNode.updateIsChecking(true) - let signal = context.engine.peers.requestChannelRevenueWithdrawalUrl(peerId: peerId, password: contentNode.password) + let signal = context.engine.peers.requestStarsRevenueWithdrawalUrl(peerId: peerId, ton: false, amount: nil, password: contentNode.password) disposable.set((signal |> deliverOnMainQueue).start(next: { url in dismissImpl?() completion(url) @@ -73,7 +73,7 @@ func confirmRevenueWithdrawalController(context: AccountContext, updatedPresenta } -func revenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peerId: EnginePeer.Id, initialError: RequestRevenueWithdrawalError, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (String) -> Void) -> ViewController { +func revenueWithdrawalController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peerId: EnginePeer.Id, initialError: RequestStarsRevenueWithdrawalError, present: @escaping (ViewController, Any?) -> Void, completion: @escaping (String) -> Void) -> ViewController { let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } let theme = AlertControllerTheme(presentationData: presentationData) diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index 60777f05e1..4a707b0696 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -36,10 +36,6 @@ extension StoryStats: Stats { } -extension RevenueStats: Stats { - -} - extension StarsRevenueStats: Stats { } @@ -763,8 +759,8 @@ class StatsOverviewItemNode: ListViewItemNode { } else { height += topLeftItemLayoutAndApply!.0.height * 4.0 + verticalSpacing * 3.0 } - } else if let stats = item.stats as? RevenueStats { - if let additionalStats = item.additionalStats as? StarsRevenueStats, additionalStats.balances.overallRevenue > StarsAmount.zero { + } else if let stats = item.stats as? StarsRevenueStats, case .ton = stats.balances.overallRevenue.currency { + if let additionalStats = item.additionalStats as? StarsRevenueStats, additionalStats.balances.overallRevenue.amount > StarsAmount.zero { twoColumnLayout = true useMinLeftColumnWidth = true @@ -772,9 +768,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.availableBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Available, - (stats.balances.availableBalance == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.availableBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -782,9 +778,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.currentBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.currentBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Current, - (stats.balances.currentBalance == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.currentBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -792,9 +788,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.overallRevenue, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.overallRevenue.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Total, - (stats.balances.overallRevenue == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.overallRevenue.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -802,9 +798,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(additionalStats.balances.availableBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(additionalStats.balances.availableBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat), " ", - (additionalStats.balances.availableBalance == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.availableBalance.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (additionalStats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.availableBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) @@ -812,9 +808,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(additionalStats.balances.currentBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(additionalStats.balances.currentBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat), " ", - (additionalStats.balances.currentBalance == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.currentBalance.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (additionalStats.balances.currentBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.currentBalance.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) @@ -822,9 +818,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(additionalStats.balances.overallRevenue, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(additionalStats.balances.overallRevenue.amount, dateTimeFormat: item.presentationData.dateTimeFormat), " ", - (additionalStats.balances.overallRevenue == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.overallRevenue.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (additionalStats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(additionalStats.balances.overallRevenue.amount.value, divide: false, rate: additionalStats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) @@ -836,9 +832,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.availableBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.availableBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_Overview_Available, - (stats.balances.availableBalance == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.availableBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -846,9 +842,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.currentBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.currentBalance.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_Overview_Current, - (stats.balances.currentBalance == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.currentBalance.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -856,9 +852,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatTonAmountText(stats.balances.overallRevenue, dateTimeFormat: item.presentationData.dateTimeFormat), + formatTonAmountText(stats.balances.overallRevenue.amount.value, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_Overview_Total, - (stats.balances.overallRevenue == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.overallRevenue.amount.value == 0 ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .ton ) @@ -871,9 +867,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(stats.balances.availableBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(stats.balances.availableBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Available, - (stats.balances.availableBalance == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.availableBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.availableBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) @@ -881,9 +877,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(stats.balances.currentBalance, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(stats.balances.currentBalance.amount, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Current, - (stats.balances.currentBalance == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.currentBalance.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.currentBalance.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) @@ -891,9 +887,9 @@ class StatsOverviewItemNode: ListViewItemNode { item.context, params.width, item.presentationData, - formatStarsAmountText(stats.balances.overallRevenue, dateTimeFormat: item.presentationData.dateTimeFormat), + formatStarsAmountText(stats.balances.overallRevenue.amount, dateTimeFormat: item.presentationData.dateTimeFormat), item.presentationData.strings.Monetization_StarsProceeds_Total, - (stats.balances.overallRevenue == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), + (stats.balances.overallRevenue.amount == StarsAmount.zero ? "" : "≈\(formatTonUsdValue(stats.balances.overallRevenue.amount.value, divide: false, rate: stats.usdRate, dateTimeFormat: item.presentationData.dateTimeFormat))", .generic), .stars ) diff --git a/submodules/StatisticsUI/Sources/TransactionInfoScreen.swift b/submodules/StatisticsUI/Sources/TransactionInfoScreen.swift index 1d7edc0e22..5d2b16cd61 100644 --- a/submodules/StatisticsUI/Sources/TransactionInfoScreen.swift +++ b/submodules/StatisticsUI/Sources/TransactionInfoScreen.swift @@ -23,14 +23,14 @@ private final class SheetContent: CombinedComponent { let context: AccountContext let peer: EnginePeer - let transaction: RevenueStatsTransactionsContext.State.Transaction + let transaction: StarsContext.State.Transaction let openExplorer: (String) -> Void let dismiss: () -> Void init( context: AccountContext, peer: EnginePeer, - transaction: RevenueStatsTransactionsContext.State.Transaction, + transaction: StarsContext.State.Transaction, openExplorer: @escaping (String) -> Void, dismiss: @escaping () -> Void ) { @@ -136,40 +136,45 @@ private final class SheetContent: CombinedComponent { let labelColor: UIColor var showPeer = false - switch component.transaction { - case let .proceeds(amount, fromDate, toDate): + if let fromDate = component.transaction.adsProceedsFromDate, let toDate = component.transaction.adsProceedsToDate { labelColor = theme.list.itemDisclosureActions.constructive.fillColor - amountString = tonAmountAttributedString(formatTonAmountText(amount, dateTimeFormat: dateTimeFormat, showPlus: true), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString + amountString = tonAmountAttributedString(formatTonAmountText(component.transaction.count.amount.value, dateTimeFormat: dateTimeFormat, showPlus: true), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString dateString = "\(stringForMediumCompactDate(timestamp: fromDate, strings: strings, dateTimeFormat: dateTimeFormat)) – \(stringForMediumCompactDate(timestamp: toDate, strings: strings, dateTimeFormat: dateTimeFormat))" titleString = strings.Monetization_TransactionInfo_Proceeds buttonTitle = strings.Common_OK explorerUrl = nil showPeer = true - case let .withdrawal(status, amount, date, provider, _, transactionUrl): + } else if case .fragment = component.transaction.peer { labelColor = theme.list.itemDestructiveColor - amountString = tonAmountAttributedString(formatTonAmountText(amount, dateTimeFormat: dateTimeFormat), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString - dateString = stringForFullDate(timestamp: date, strings: strings, dateTimeFormat: dateTimeFormat) + amountString = tonAmountAttributedString(formatTonAmountText(component.transaction.count.amount.value, dateTimeFormat: dateTimeFormat), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString + dateString = stringForFullDate(timestamp: component.transaction.date, strings: strings, dateTimeFormat: dateTimeFormat) - switch status { - case .succeed: - titleString = strings.Monetization_TransactionInfo_Withdrawal(provider).string - buttonTitle = strings.Monetization_TransactionInfo_ViewInExplorer - case .pending: + if component.transaction.flags.contains(.isPending) { titleString = strings.Monetization_TransactionInfo_Pending buttonTitle = strings.Common_OK - case .failed: + } else if component.transaction.flags.contains(.isFailed) { titleString = strings.Monetization_TransactionInfo_Failed buttonTitle = strings.Common_OK titleColor = theme.list.itemDestructiveColor + } else { + titleString = strings.Monetization_TransactionInfo_Withdrawal("Fragment").string + buttonTitle = strings.Monetization_TransactionInfo_ViewInExplorer } - explorerUrl = transactionUrl - case let .refund(amount, date, _): + explorerUrl = component.transaction.transactionUrl + } else if component.transaction.flags.contains(.isRefund) { labelColor = theme.list.itemDisclosureActions.constructive.fillColor titleString = strings.Monetization_TransactionInfo_Refund - amountString = tonAmountAttributedString(formatTonAmountText(amount, dateTimeFormat: dateTimeFormat, showPlus: true), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString - dateString = stringForFullDate(timestamp: date, strings: strings, dateTimeFormat: dateTimeFormat) + amountString = tonAmountAttributedString(formatTonAmountText(component.transaction.count.amount.value, dateTimeFormat: dateTimeFormat, showPlus: true), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString + dateString = stringForFullDate(timestamp: component.transaction.date, strings: strings, dateTimeFormat: dateTimeFormat) buttonTitle = strings.Common_OK explorerUrl = nil + } else { + labelColor = theme.list.itemDisclosureActions.constructive.fillColor + amountString = tonAmountAttributedString(formatTonAmountText(component.transaction.count.amount.value, dateTimeFormat: dateTimeFormat, showPlus: true), integralFont: integralFont, fractionalFont: fractionalFont, color: labelColor, decimalSeparator: dateTimeFormat.decimalSeparator).mutableCopy() as! NSMutableAttributedString + dateString = "" + titleString = "" + buttonTitle = "" + explorerUrl = nil } amountString.insert(NSAttributedString(string: " $ ", font: integralFont, textColor: labelColor), at: 1) @@ -293,13 +298,13 @@ private final class SheetContainerComponent: CombinedComponent { let context: AccountContext let peer: EnginePeer - let transaction: RevenueStatsTransactionsContext.State.Transaction + let transaction: StarsContext.State.Transaction let openExplorer: (String) -> Void init( context: AccountContext, peer: EnginePeer, - transaction: RevenueStatsTransactionsContext.State.Transaction, + transaction: StarsContext.State.Transaction, openExplorer: @escaping (String) -> Void ) { self.context = context @@ -410,7 +415,7 @@ final class TransactionInfoScreen: ViewControllerComponentContainer { init( context: AccountContext, peer: EnginePeer, - transaction: RevenueStatsTransactionsContext.State.Transaction, + transaction: StarsContext.State.Transaction, openExplorer: @escaping (String) -> Void ) { self.context = context diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 2d961b7d2c..627bd470a1 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -110,10 +110,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[602479523] = { return Api.BotPreviewMedia.parse_botPreviewMedia($0) } dict[-113453988] = { return Api.BotVerification.parse_botVerification($0) } dict[-1328716265] = { return Api.BotVerifierSettings.parse_botVerifierSettings($0) } - dict[-1006669337] = { return Api.BroadcastRevenueBalances.parse_broadcastRevenueBalances($0) } - dict[1434332356] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionProceeds($0) } - dict[1121127726] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionRefund($0) } - dict[1515784568] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionWithdrawal($0) } dict[-283809188] = { return Api.BusinessAwayMessage.parse_businessAwayMessage($0) } dict[-910564679] = { return Api.BusinessAwayMessageSchedule.parse_businessAwayMessageScheduleAlways($0) } dict[-867328308] = { return Api.BusinessAwayMessageSchedule.parse_businessAwayMessageScheduleCustom($0) } @@ -609,6 +605,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[775611918] = { return Api.MessageAction.parse_messageActionStarGiftUnique($0) } dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) } dict[-293988970] = { return Api.MessageAction.parse_messageActionSuggestedPostApproval($0) } + dict[1777932024] = { return Api.MessageAction.parse_messageActionSuggestedPostRefund($0) } + dict[-1780625559] = { return Api.MessageAction.parse_messageActionSuggestedPostSuccess($0) } dict[-940721021] = { return Api.MessageAction.parse_messageActionTodoAppendTasks($0) } dict[-864265079] = { return Api.MessageAction.parse_messageActionTodoCompletions($0) } dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) } @@ -964,7 +962,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[779004698] = { return Api.StarsSubscription.parse_starsSubscription($0) } dict[88173912] = { return Api.StarsSubscriptionPricing.parse_starsSubscriptionPricing($0) } dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) } - dict[-1549805238] = { return Api.StarsTransaction.parse_starsTransaction($0) } + dict[325426864] = { return Api.StarsTransaction.parse_starsTransaction($0) } dict[-670195363] = { return Api.StarsTransactionPeer.parse_starsTransactionPeer($0) } dict[-110658899] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAPI($0) } dict[1617438738] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAds($0) } @@ -1042,7 +1040,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-997782967] = { return Api.Update.parse_updateBotStopped($0) } dict[-2095595325] = { return Api.Update.parse_updateBotWebhookJSON($0) } dict[-1684914010] = { return Api.Update.parse_updateBotWebhookJSONQuery($0) } - dict[-539401739] = { return Api.Update.parse_updateBroadcastRevenueTransactions($0) } dict[513998247] = { return Api.Update.parse_updateBusinessBotCallbackQuery($0) } dict[1666927625] = { return Api.Update.parse_updateChannel($0) } dict[-1304443240] = { return Api.Update.parse_updateChannelAvailableMessages($0) } @@ -1436,7 +1433,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1877571094] = { return Api.payments.StarGifts.parse_starGifts($0) } dict[-1551326360] = { return Api.payments.StarGifts.parse_starGiftsNotModified($0) } dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) } - dict[-919881925] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) } + dict[1814066038] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) } dict[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) } dict[1822222573] = { return Api.payments.StarsStatus.parse_starsStatus($0) } dict[-1261053863] = { return Api.payments.SuggestedStarRefBots.parse_suggestedStarRefBots($0) } @@ -1457,9 +1454,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1696454430] = { return Api.premium.MyBoosts.parse_myBoosts($0) } dict[-594852657] = { return Api.smsjobs.EligibilityToJoin.parse_eligibleToJoin($0) } dict[720277905] = { return Api.smsjobs.Status.parse_status($0) } - dict[1409802903] = { return Api.stats.BroadcastRevenueStats.parse_broadcastRevenueStats($0) } - dict[-2028632986] = { return Api.stats.BroadcastRevenueTransactions.parse_broadcastRevenueTransactions($0) } - dict[-328886473] = { return Api.stats.BroadcastRevenueWithdrawalUrl.parse_broadcastRevenueWithdrawalUrl($0) } dict[963421692] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) } dict[-276825834] = { return Api.stats.MegagroupStats.parse_megagroupStats($0) } dict[2145983508] = { return Api.stats.MessageStats.parse_messageStats($0) } @@ -1620,10 +1614,6 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.BotVerifierSettings: _1.serialize(buffer, boxed) - case let _1 as Api.BroadcastRevenueBalances: - _1.serialize(buffer, boxed) - case let _1 as Api.BroadcastRevenueTransaction: - _1.serialize(buffer, boxed) case let _1 as Api.BusinessAwayMessage: _1.serialize(buffer, boxed) case let _1 as Api.BusinessAwayMessageSchedule: @@ -2598,12 +2588,6 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.smsjobs.Status: _1.serialize(buffer, boxed) - case let _1 as Api.stats.BroadcastRevenueStats: - _1.serialize(buffer, boxed) - case let _1 as Api.stats.BroadcastRevenueTransactions: - _1.serialize(buffer, boxed) - case let _1 as Api.stats.BroadcastRevenueWithdrawalUrl: - _1.serialize(buffer, boxed) case let _1 as Api.stats.BroadcastStats: _1.serialize(buffer, boxed) case let _1 as Api.stats.MegagroupStats: diff --git a/submodules/TelegramApi/Sources/Api15.swift b/submodules/TelegramApi/Sources/Api15.swift index 7359821a69..5c2505e379 100644 --- a/submodules/TelegramApi/Sources/Api15.swift +++ b/submodules/TelegramApi/Sources/Api15.swift @@ -397,6 +397,8 @@ public extension Api { case messageActionStarGiftUnique(flags: Int32, gift: Api.StarGift, canExportAt: Int32?, transferStars: Int64?, fromId: Api.Peer?, peer: Api.Peer?, savedId: Int64?, resaleStars: Int64?, canTransferAt: Int32?, canResellAt: Int32?) case messageActionSuggestProfilePhoto(photo: Api.Photo) case messageActionSuggestedPostApproval(flags: Int32, rejectComment: String?, scheduleDate: Int32?, price: Api.StarsAmount?) + case messageActionSuggestedPostRefund(flags: Int32) + case messageActionSuggestedPostSuccess(price: Api.StarsAmount) case messageActionTodoAppendTasks(list: [Api.TodoItem]) case messageActionTodoCompletions(completed: [Int32], incompleted: [Int32]) case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?) @@ -825,6 +827,18 @@ public extension Api { if Int(flags) & Int(1 << 3) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 4) != 0 {price!.serialize(buffer, true)} break + case .messageActionSuggestedPostRefund(let flags): + if boxed { + buffer.appendInt32(1777932024) + } + serializeInt32(flags, buffer: buffer, boxed: false) + break + case .messageActionSuggestedPostSuccess(let price): + if boxed { + buffer.appendInt32(-1780625559) + } + price.serialize(buffer, true) + break case .messageActionTodoAppendTasks(let list): if boxed { buffer.appendInt32(-940721021) @@ -985,6 +999,10 @@ public extension Api { return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)]) case .messageActionSuggestedPostApproval(let flags, let rejectComment, let scheduleDate, let price): return ("messageActionSuggestedPostApproval", [("flags", flags as Any), ("rejectComment", rejectComment as Any), ("scheduleDate", scheduleDate as Any), ("price", price as Any)]) + case .messageActionSuggestedPostRefund(let flags): + return ("messageActionSuggestedPostRefund", [("flags", flags as Any)]) + case .messageActionSuggestedPostSuccess(let price): + return ("messageActionSuggestedPostSuccess", [("price", price as Any)]) case .messageActionTodoAppendTasks(let list): return ("messageActionTodoAppendTasks", [("list", list as Any)]) case .messageActionTodoCompletions(let completed, let incompleted): @@ -1832,6 +1850,30 @@ public extension Api { return nil } } + public static func parse_messageActionSuggestedPostRefund(_ reader: BufferReader) -> MessageAction? { + var _1: Int32? + _1 = reader.readInt32() + let _c1 = _1 != nil + if _c1 { + return Api.MessageAction.messageActionSuggestedPostRefund(flags: _1!) + } + else { + return nil + } + } + public static func parse_messageActionSuggestedPostSuccess(_ reader: BufferReader) -> MessageAction? { + var _1: Api.StarsAmount? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.StarsAmount + } + let _c1 = _1 != nil + if _c1 { + return Api.MessageAction.messageActionSuggestedPostSuccess(price: _1!) + } + else { + return nil + } + } public static func parse_messageActionTodoAppendTasks(_ reader: BufferReader) -> MessageAction? { var _1: [Api.TodoItem]? if let _ = reader.readInt32() { diff --git a/submodules/TelegramApi/Sources/Api2.swift b/submodules/TelegramApi/Sources/Api2.swift index 4337a392c9..ddea45fec8 100644 --- a/submodules/TelegramApi/Sources/Api2.swift +++ b/submodules/TelegramApi/Sources/Api2.swift @@ -914,166 +914,6 @@ public extension Api { } } -public extension Api { - enum BroadcastRevenueBalances: TypeConstructorDescription { - case broadcastRevenueBalances(flags: Int32, currentBalance: Int64, availableBalance: Int64, overallRevenue: Int64) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .broadcastRevenueBalances(let flags, let currentBalance, let availableBalance, let overallRevenue): - if boxed { - buffer.appendInt32(-1006669337) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt64(currentBalance, buffer: buffer, boxed: false) - serializeInt64(availableBalance, buffer: buffer, boxed: false) - serializeInt64(overallRevenue, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .broadcastRevenueBalances(let flags, let currentBalance, let availableBalance, let overallRevenue): - return ("broadcastRevenueBalances", [("flags", flags as Any), ("currentBalance", currentBalance as Any), ("availableBalance", availableBalance as Any), ("overallRevenue", overallRevenue as Any)]) - } - } - - public static func parse_broadcastRevenueBalances(_ reader: BufferReader) -> BroadcastRevenueBalances? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int64? - _2 = reader.readInt64() - var _3: Int64? - _3 = reader.readInt64() - var _4: Int64? - _4 = reader.readInt64() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - if _c1 && _c2 && _c3 && _c4 { - return Api.BroadcastRevenueBalances.broadcastRevenueBalances(flags: _1!, currentBalance: _2!, availableBalance: _3!, overallRevenue: _4!) - } - else { - return nil - } - } - - } -} -public extension Api { - enum BroadcastRevenueTransaction: TypeConstructorDescription { - case broadcastRevenueTransactionProceeds(amount: Int64, fromDate: Int32, toDate: Int32) - case broadcastRevenueTransactionRefund(amount: Int64, date: Int32, provider: String) - case broadcastRevenueTransactionWithdrawal(flags: Int32, amount: Int64, date: Int32, provider: String, transactionDate: Int32?, transactionUrl: String?) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .broadcastRevenueTransactionProceeds(let amount, let fromDate, let toDate): - if boxed { - buffer.appendInt32(1434332356) - } - serializeInt64(amount, buffer: buffer, boxed: false) - serializeInt32(fromDate, buffer: buffer, boxed: false) - serializeInt32(toDate, buffer: buffer, boxed: false) - break - case .broadcastRevenueTransactionRefund(let amount, let date, let provider): - if boxed { - buffer.appendInt32(1121127726) - } - serializeInt64(amount, buffer: buffer, boxed: false) - serializeInt32(date, buffer: buffer, boxed: false) - serializeString(provider, buffer: buffer, boxed: false) - break - case .broadcastRevenueTransactionWithdrawal(let flags, let amount, let date, let provider, let transactionDate, let transactionUrl): - if boxed { - buffer.appendInt32(1515784568) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt64(amount, buffer: buffer, boxed: false) - serializeInt32(date, buffer: buffer, boxed: false) - serializeString(provider, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 1) != 0 {serializeInt32(transactionDate!, buffer: buffer, boxed: false)} - if Int(flags) & Int(1 << 1) != 0 {serializeString(transactionUrl!, buffer: buffer, boxed: false)} - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .broadcastRevenueTransactionProceeds(let amount, let fromDate, let toDate): - return ("broadcastRevenueTransactionProceeds", [("amount", amount as Any), ("fromDate", fromDate as Any), ("toDate", toDate as Any)]) - case .broadcastRevenueTransactionRefund(let amount, let date, let provider): - return ("broadcastRevenueTransactionRefund", [("amount", amount as Any), ("date", date as Any), ("provider", provider as Any)]) - case .broadcastRevenueTransactionWithdrawal(let flags, let amount, let date, let provider, let transactionDate, let transactionUrl): - return ("broadcastRevenueTransactionWithdrawal", [("flags", flags as Any), ("amount", amount as Any), ("date", date as Any), ("provider", provider as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any)]) - } - } - - public static func parse_broadcastRevenueTransactionProceeds(_ reader: BufferReader) -> BroadcastRevenueTransaction? { - var _1: Int64? - _1 = reader.readInt64() - var _2: Int32? - _2 = reader.readInt32() - var _3: Int32? - _3 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.BroadcastRevenueTransaction.broadcastRevenueTransactionProceeds(amount: _1!, fromDate: _2!, toDate: _3!) - } - else { - return nil - } - } - public static func parse_broadcastRevenueTransactionRefund(_ reader: BufferReader) -> BroadcastRevenueTransaction? { - var _1: Int64? - _1 = reader.readInt64() - var _2: Int32? - _2 = reader.readInt32() - var _3: String? - _3 = parseString(reader) - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.BroadcastRevenueTransaction.broadcastRevenueTransactionRefund(amount: _1!, date: _2!, provider: _3!) - } - else { - return nil - } - } - public static func parse_broadcastRevenueTransactionWithdrawal(_ reader: BufferReader) -> BroadcastRevenueTransaction? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int64? - _2 = reader.readInt64() - var _3: Int32? - _3 = reader.readInt32() - var _4: String? - _4 = parseString(reader) - var _5: Int32? - if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() } - var _6: String? - if Int(_1!) & Int(1 << 1) != 0 {_6 = parseString(reader) } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil - let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { - return Api.BroadcastRevenueTransaction.broadcastRevenueTransactionWithdrawal(flags: _1!, amount: _2!, date: _3!, provider: _4!, transactionDate: _5, transactionUrl: _6) - } - else { - return nil - } - } - - } -} public extension Api { enum BusinessAwayMessage: TypeConstructorDescription { case businessAwayMessage(flags: Int32, shortcutId: Int32, schedule: Api.BusinessAwayMessageSchedule, recipients: Api.BusinessRecipients) @@ -1190,3 +1030,203 @@ public extension Api { } } +public extension Api { + enum BusinessBotRecipients: TypeConstructorDescription { + case businessBotRecipients(flags: Int32, users: [Int64]?, excludeUsers: [Int64]?) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .businessBotRecipients(let flags, let users, let excludeUsers): + if boxed { + buffer.appendInt32(-1198722189) + } + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 4) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users!.count)) + for item in users! { + serializeInt64(item, buffer: buffer, boxed: false) + }} + if Int(flags) & Int(1 << 6) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(excludeUsers!.count)) + for item in excludeUsers! { + serializeInt64(item, buffer: buffer, boxed: false) + }} + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .businessBotRecipients(let flags, let users, let excludeUsers): + return ("businessBotRecipients", [("flags", flags as Any), ("users", users as Any), ("excludeUsers", excludeUsers as Any)]) + } + } + + public static func parse_businessBotRecipients(_ reader: BufferReader) -> BusinessBotRecipients? { + var _1: Int32? + _1 = reader.readInt32() + var _2: [Int64]? + if Int(_1!) & Int(1 << 4) != 0 {if let _ = reader.readInt32() { + _2 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) + } } + var _3: [Int64]? + if Int(_1!) & Int(1 << 6) != 0 {if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) + } } + let _c1 = _1 != nil + let _c2 = (Int(_1!) & Int(1 << 4) == 0) || _2 != nil + let _c3 = (Int(_1!) & Int(1 << 6) == 0) || _3 != nil + if _c1 && _c2 && _c3 { + return Api.BusinessBotRecipients.businessBotRecipients(flags: _1!, users: _2, excludeUsers: _3) + } + else { + return nil + } + } + + } +} +public extension Api { + enum BusinessBotRights: TypeConstructorDescription { + case businessBotRights(flags: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .businessBotRights(let flags): + if boxed { + buffer.appendInt32(-1604170505) + } + serializeInt32(flags, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .businessBotRights(let flags): + return ("businessBotRights", [("flags", flags as Any)]) + } + } + + public static func parse_businessBotRights(_ reader: BufferReader) -> BusinessBotRights? { + var _1: Int32? + _1 = reader.readInt32() + let _c1 = _1 != nil + if _c1 { + return Api.BusinessBotRights.businessBotRights(flags: _1!) + } + else { + return nil + } + } + + } +} +public extension Api { + enum BusinessChatLink: TypeConstructorDescription { + case businessChatLink(flags: Int32, link: String, message: String, entities: [Api.MessageEntity]?, title: String?, views: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .businessChatLink(let flags, let link, let message, let entities, let title, let views): + if boxed { + buffer.appendInt32(-1263638929) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeString(link, buffer: buffer, boxed: false) + serializeString(message, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(entities!.count)) + for item in entities! { + item.serialize(buffer, true) + }} + if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)} + serializeInt32(views, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .businessChatLink(let flags, let link, let message, let entities, let title, let views): + return ("businessChatLink", [("flags", flags as Any), ("link", link as Any), ("message", message as Any), ("entities", entities as Any), ("title", title as Any), ("views", views as Any)]) + } + } + + public static func parse_businessChatLink(_ reader: BufferReader) -> BusinessChatLink? { + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + _2 = parseString(reader) + var _3: String? + _3 = parseString(reader) + var _4: [Api.MessageEntity]? + if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() { + _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self) + } } + var _5: String? + if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) } + var _6: Int32? + _6 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil + let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil + let _c6 = _6 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { + return Api.BusinessChatLink.businessChatLink(flags: _1!, link: _2!, message: _3!, entities: _4, title: _5, views: _6!) + } + else { + return nil + } + } + + } +} +public extension Api { + enum BusinessGreetingMessage: TypeConstructorDescription { + case businessGreetingMessage(shortcutId: Int32, recipients: Api.BusinessRecipients, noActivityDays: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays): + if boxed { + buffer.appendInt32(-451302485) + } + serializeInt32(shortcutId, buffer: buffer, boxed: false) + recipients.serialize(buffer, true) + serializeInt32(noActivityDays, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays): + return ("businessGreetingMessage", [("shortcutId", shortcutId as Any), ("recipients", recipients as Any), ("noActivityDays", noActivityDays as Any)]) + } + } + + public static func parse_businessGreetingMessage(_ reader: BufferReader) -> BusinessGreetingMessage? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Api.BusinessRecipients? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients + } + var _3: Int32? + _3 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.BusinessGreetingMessage.businessGreetingMessage(shortcutId: _1!, recipients: _2!, noActivityDays: _3!) + } + else { + return nil + } + } + + } +} diff --git a/submodules/TelegramApi/Sources/Api25.swift b/submodules/TelegramApi/Sources/Api25.swift index 8ea74bad94..00956dbfa9 100644 --- a/submodules/TelegramApi/Sources/Api25.swift +++ b/submodules/TelegramApi/Sources/Api25.swift @@ -504,17 +504,17 @@ public extension Api { } public extension Api { enum StarsTransaction: TypeConstructorDescription { - case starsTransaction(flags: Int32, id: String, stars: Api.StarsAmount, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?, subscriptionPeriod: Int32?, giveawayPostId: Int32?, stargift: Api.StarGift?, floodskipNumber: Int32?, starrefCommissionPermille: Int32?, starrefPeer: Api.Peer?, starrefAmount: Api.StarsAmount?, paidMessages: Int32?, premiumGiftMonths: Int32?) + case starsTransaction(flags: Int32, id: String, amount: Api.StarsAmount, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?, subscriptionPeriod: Int32?, giveawayPostId: Int32?, stargift: Api.StarGift?, floodskipNumber: Int32?, starrefCommissionPermille: Int32?, starrefPeer: Api.Peer?, starrefAmount: Api.StarsAmount?, paidMessages: Int32?, premiumGiftMonths: Int32?, adsProceedsFromDate: Int32?, adsProceedsToDate: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod, let giveawayPostId, let stargift, let floodskipNumber, let starrefCommissionPermille, let starrefPeer, let starrefAmount, let paidMessages, let premiumGiftMonths): + case .starsTransaction(let flags, let id, let amount, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod, let giveawayPostId, let stargift, let floodskipNumber, let starrefCommissionPermille, let starrefPeer, let starrefAmount, let paidMessages, let premiumGiftMonths, let adsProceedsFromDate, let adsProceedsToDate): if boxed { - buffer.appendInt32(-1549805238) + buffer.appendInt32(325426864) } serializeInt32(flags, buffer: buffer, boxed: false) serializeString(id, buffer: buffer, boxed: false) - stars.serialize(buffer, true) + amount.serialize(buffer, true) serializeInt32(date, buffer: buffer, boxed: false) peer.serialize(buffer, true) if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)} @@ -538,14 +538,16 @@ public extension Api { if Int(flags) & Int(1 << 17) != 0 {starrefAmount!.serialize(buffer, true)} if Int(flags) & Int(1 << 19) != 0 {serializeInt32(paidMessages!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 20) != 0 {serializeInt32(premiumGiftMonths!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 23) != 0 {serializeInt32(adsProceedsFromDate!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 23) != 0 {serializeInt32(adsProceedsToDate!, buffer: buffer, boxed: false)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod, let giveawayPostId, let stargift, let floodskipNumber, let starrefCommissionPermille, let starrefPeer, let starrefAmount, let paidMessages, let premiumGiftMonths): - return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any), ("subscriptionPeriod", subscriptionPeriod as Any), ("giveawayPostId", giveawayPostId as Any), ("stargift", stargift as Any), ("floodskipNumber", floodskipNumber as Any), ("starrefCommissionPermille", starrefCommissionPermille as Any), ("starrefPeer", starrefPeer as Any), ("starrefAmount", starrefAmount as Any), ("paidMessages", paidMessages as Any), ("premiumGiftMonths", premiumGiftMonths as Any)]) + case .starsTransaction(let flags, let id, let amount, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod, let giveawayPostId, let stargift, let floodskipNumber, let starrefCommissionPermille, let starrefPeer, let starrefAmount, let paidMessages, let premiumGiftMonths, let adsProceedsFromDate, let adsProceedsToDate): + return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("amount", amount as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any), ("subscriptionPeriod", subscriptionPeriod as Any), ("giveawayPostId", giveawayPostId as Any), ("stargift", stargift as Any), ("floodskipNumber", floodskipNumber as Any), ("starrefCommissionPermille", starrefCommissionPermille as Any), ("starrefPeer", starrefPeer as Any), ("starrefAmount", starrefAmount as Any), ("paidMessages", paidMessages as Any), ("premiumGiftMonths", premiumGiftMonths as Any), ("adsProceedsFromDate", adsProceedsFromDate as Any), ("adsProceedsToDate", adsProceedsToDate as Any)]) } } @@ -608,6 +610,10 @@ public extension Api { if Int(_1!) & Int(1 << 19) != 0 {_21 = reader.readInt32() } var _22: Int32? if Int(_1!) & Int(1 << 20) != 0 {_22 = reader.readInt32() } + var _23: Int32? + if Int(_1!) & Int(1 << 23) != 0 {_23 = reader.readInt32() } + var _24: Int32? + if Int(_1!) & Int(1 << 23) != 0 {_24 = reader.readInt32() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil @@ -630,8 +636,10 @@ public extension Api { let _c20 = (Int(_1!) & Int(1 << 17) == 0) || _20 != nil let _c21 = (Int(_1!) & Int(1 << 19) == 0) || _21 != nil let _c22 = (Int(_1!) & Int(1 << 20) == 0) || _22 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 { - return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13, subscriptionPeriod: _14, giveawayPostId: _15, stargift: _16, floodskipNumber: _17, starrefCommissionPermille: _18, starrefPeer: _19, starrefAmount: _20, paidMessages: _21, premiumGiftMonths: _22) + let _c23 = (Int(_1!) & Int(1 << 23) == 0) || _23 != nil + let _c24 = (Int(_1!) & Int(1 << 23) == 0) || _24 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 { + return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, amount: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13, subscriptionPeriod: _14, giveawayPostId: _15, stargift: _16, floodskipNumber: _17, starrefCommissionPermille: _18, starrefPeer: _19, starrefAmount: _20, paidMessages: _21, premiumGiftMonths: _22, adsProceedsFromDate: _23, adsProceedsToDate: _24) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api27.swift b/submodules/TelegramApi/Sources/Api27.swift index 3b63ab8600..0265253957 100644 --- a/submodules/TelegramApi/Sources/Api27.swift +++ b/submodules/TelegramApi/Sources/Api27.swift @@ -73,7 +73,6 @@ public extension Api { case updateBotStopped(userId: Int64, date: Int32, stopped: Api.Bool, qts: Int32) case updateBotWebhookJSON(data: Api.DataJSON) case updateBotWebhookJSONQuery(queryId: Int64, data: Api.DataJSON, timeout: Int32) - case updateBroadcastRevenueTransactions(peer: Api.Peer, balances: Api.BroadcastRevenueBalances) case updateBusinessBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, connectionId: String, message: Api.Message, replyToMessage: Api.Message?, chatInstance: Int64, data: Buffer?) case updateChannel(channelId: Int64) case updateChannelAvailableMessages(channelId: Int64, availableMinId: Int32) @@ -413,13 +412,6 @@ public extension Api { data.serialize(buffer, true) serializeInt32(timeout, buffer: buffer, boxed: false) break - case .updateBroadcastRevenueTransactions(let peer, let balances): - if boxed { - buffer.appendInt32(-539401739) - } - peer.serialize(buffer, true) - balances.serialize(buffer, true) - break case .updateBusinessBotCallbackQuery(let flags, let queryId, let userId, let connectionId, let message, let replyToMessage, let chatInstance, let data): if boxed { buffer.appendInt32(513998247) @@ -1515,8 +1507,6 @@ public extension Api { return ("updateBotWebhookJSON", [("data", data as Any)]) case .updateBotWebhookJSONQuery(let queryId, let data, let timeout): return ("updateBotWebhookJSONQuery", [("queryId", queryId as Any), ("data", data as Any), ("timeout", timeout as Any)]) - case .updateBroadcastRevenueTransactions(let peer, let balances): - return ("updateBroadcastRevenueTransactions", [("peer", peer as Any), ("balances", balances as Any)]) case .updateBusinessBotCallbackQuery(let flags, let queryId, let userId, let connectionId, let message, let replyToMessage, let chatInstance, let data): return ("updateBusinessBotCallbackQuery", [("flags", flags as Any), ("queryId", queryId as Any), ("userId", userId as Any), ("connectionId", connectionId as Any), ("message", message as Any), ("replyToMessage", replyToMessage as Any), ("chatInstance", chatInstance as Any), ("data", data as Any)]) case .updateChannel(let channelId): @@ -2242,24 +2232,6 @@ public extension Api { return nil } } - public static func parse_updateBroadcastRevenueTransactions(_ reader: BufferReader) -> Update? { - var _1: Api.Peer? - if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.Peer - } - var _2: Api.BroadcastRevenueBalances? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.BroadcastRevenueBalances - } - let _c1 = _1 != nil - let _c2 = _2 != nil - if _c1 && _c2 { - return Api.Update.updateBroadcastRevenueTransactions(peer: _1!, balances: _2!) - } - else { - return nil - } - } public static func parse_updateBusinessBotCallbackQuery(_ reader: BufferReader) -> Update? { var _1: Int32? _1 = reader.readInt32() diff --git a/submodules/TelegramApi/Sources/Api3.swift b/submodules/TelegramApi/Sources/Api3.swift index 1818e0060b..bb3b303e57 100644 --- a/submodules/TelegramApi/Sources/Api3.swift +++ b/submodules/TelegramApi/Sources/Api3.swift @@ -1,203 +1,3 @@ -public extension Api { - enum BusinessBotRecipients: TypeConstructorDescription { - case businessBotRecipients(flags: Int32, users: [Int64]?, excludeUsers: [Int64]?) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .businessBotRecipients(let flags, let users, let excludeUsers): - if boxed { - buffer.appendInt32(-1198722189) - } - serializeInt32(flags, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 4) != 0 {buffer.appendInt32(481674261) - buffer.appendInt32(Int32(users!.count)) - for item in users! { - serializeInt64(item, buffer: buffer, boxed: false) - }} - if Int(flags) & Int(1 << 6) != 0 {buffer.appendInt32(481674261) - buffer.appendInt32(Int32(excludeUsers!.count)) - for item in excludeUsers! { - serializeInt64(item, buffer: buffer, boxed: false) - }} - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .businessBotRecipients(let flags, let users, let excludeUsers): - return ("businessBotRecipients", [("flags", flags as Any), ("users", users as Any), ("excludeUsers", excludeUsers as Any)]) - } - } - - public static func parse_businessBotRecipients(_ reader: BufferReader) -> BusinessBotRecipients? { - var _1: Int32? - _1 = reader.readInt32() - var _2: [Int64]? - if Int(_1!) & Int(1 << 4) != 0 {if let _ = reader.readInt32() { - _2 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) - } } - var _3: [Int64]? - if Int(_1!) & Int(1 << 6) != 0 {if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) - } } - let _c1 = _1 != nil - let _c2 = (Int(_1!) & Int(1 << 4) == 0) || _2 != nil - let _c3 = (Int(_1!) & Int(1 << 6) == 0) || _3 != nil - if _c1 && _c2 && _c3 { - return Api.BusinessBotRecipients.businessBotRecipients(flags: _1!, users: _2, excludeUsers: _3) - } - else { - return nil - } - } - - } -} -public extension Api { - enum BusinessBotRights: TypeConstructorDescription { - case businessBotRights(flags: Int32) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .businessBotRights(let flags): - if boxed { - buffer.appendInt32(-1604170505) - } - serializeInt32(flags, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .businessBotRights(let flags): - return ("businessBotRights", [("flags", flags as Any)]) - } - } - - public static func parse_businessBotRights(_ reader: BufferReader) -> BusinessBotRights? { - var _1: Int32? - _1 = reader.readInt32() - let _c1 = _1 != nil - if _c1 { - return Api.BusinessBotRights.businessBotRights(flags: _1!) - } - else { - return nil - } - } - - } -} -public extension Api { - enum BusinessChatLink: TypeConstructorDescription { - case businessChatLink(flags: Int32, link: String, message: String, entities: [Api.MessageEntity]?, title: String?, views: Int32) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .businessChatLink(let flags, let link, let message, let entities, let title, let views): - if boxed { - buffer.appendInt32(-1263638929) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeString(link, buffer: buffer, boxed: false) - serializeString(message, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261) - buffer.appendInt32(Int32(entities!.count)) - for item in entities! { - item.serialize(buffer, true) - }} - if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)} - serializeInt32(views, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .businessChatLink(let flags, let link, let message, let entities, let title, let views): - return ("businessChatLink", [("flags", flags as Any), ("link", link as Any), ("message", message as Any), ("entities", entities as Any), ("title", title as Any), ("views", views as Any)]) - } - } - - public static func parse_businessChatLink(_ reader: BufferReader) -> BusinessChatLink? { - var _1: Int32? - _1 = reader.readInt32() - var _2: String? - _2 = parseString(reader) - var _3: String? - _3 = parseString(reader) - var _4: [Api.MessageEntity]? - if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() { - _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self) - } } - var _5: String? - if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) } - var _6: Int32? - _6 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil - let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil - let _c6 = _6 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { - return Api.BusinessChatLink.businessChatLink(flags: _1!, link: _2!, message: _3!, entities: _4, title: _5, views: _6!) - } - else { - return nil - } - } - - } -} -public extension Api { - enum BusinessGreetingMessage: TypeConstructorDescription { - case businessGreetingMessage(shortcutId: Int32, recipients: Api.BusinessRecipients, noActivityDays: Int32) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays): - if boxed { - buffer.appendInt32(-451302485) - } - serializeInt32(shortcutId, buffer: buffer, boxed: false) - recipients.serialize(buffer, true) - serializeInt32(noActivityDays, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays): - return ("businessGreetingMessage", [("shortcutId", shortcutId as Any), ("recipients", recipients as Any), ("noActivityDays", noActivityDays as Any)]) - } - } - - public static func parse_businessGreetingMessage(_ reader: BufferReader) -> BusinessGreetingMessage? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Api.BusinessRecipients? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients - } - var _3: Int32? - _3 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.BusinessGreetingMessage.businessGreetingMessage(shortcutId: _1!, recipients: _2!, noActivityDays: _3!) - } - else { - return nil - } - } - - } -} public extension Api { enum BusinessIntro: TypeConstructorDescription { case businessIntro(flags: Int32, title: String, description: String, sticker: Api.Document?) diff --git a/submodules/TelegramApi/Sources/Api36.swift b/submodules/TelegramApi/Sources/Api36.swift index cfc3b45e13..c7e80100b6 100644 --- a/submodules/TelegramApi/Sources/Api36.swift +++ b/submodules/TelegramApi/Sources/Api36.swift @@ -392,14 +392,16 @@ public extension Api.payments { } public extension Api.payments { enum StarsRevenueStats: TypeConstructorDescription { - case starsRevenueStats(revenueGraph: Api.StatsGraph, status: Api.StarsRevenueStatus, usdRate: Double) + case starsRevenueStats(flags: Int32, topHoursGraph: Api.StatsGraph?, revenueGraph: Api.StatsGraph, status: Api.StarsRevenueStatus, usdRate: Double) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .starsRevenueStats(let revenueGraph, let status, let usdRate): + case .starsRevenueStats(let flags, let topHoursGraph, let revenueGraph, let status, let usdRate): if boxed { - buffer.appendInt32(-919881925) + buffer.appendInt32(1814066038) } + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {topHoursGraph!.serialize(buffer, true)} revenueGraph.serialize(buffer, true) status.serialize(buffer, true) serializeDouble(usdRate, buffer: buffer, boxed: false) @@ -409,27 +411,35 @@ public extension Api.payments { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .starsRevenueStats(let revenueGraph, let status, let usdRate): - return ("starsRevenueStats", [("revenueGraph", revenueGraph as Any), ("status", status as Any), ("usdRate", usdRate as Any)]) + case .starsRevenueStats(let flags, let topHoursGraph, let revenueGraph, let status, let usdRate): + return ("starsRevenueStats", [("flags", flags as Any), ("topHoursGraph", topHoursGraph as Any), ("revenueGraph", revenueGraph as Any), ("status", status as Any), ("usdRate", usdRate as Any)]) } } public static func parse_starsRevenueStats(_ reader: BufferReader) -> StarsRevenueStats? { - var _1: Api.StatsGraph? + var _1: Int32? + _1 = reader.readInt32() + var _2: Api.StatsGraph? + if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } } + var _3: Api.StatsGraph? if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.StatsGraph + _3 = Api.parse(reader, signature: signature) as? Api.StatsGraph } - var _2: Api.StarsRevenueStatus? + var _4: Api.StarsRevenueStatus? if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.StarsRevenueStatus + _4 = Api.parse(reader, signature: signature) as? Api.StarsRevenueStatus } - var _3: Double? - _3 = reader.readDouble() + var _5: Double? + _5 = reader.readDouble() let _c1 = _1 != nil - let _c2 = _2 != nil + let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.payments.StarsRevenueStats.starsRevenueStats(revenueGraph: _1!, status: _2!, usdRate: _3!) + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.payments.StarsRevenueStats.starsRevenueStats(flags: _1!, topHoursGraph: _2, revenueGraph: _3!, status: _4!, usdRate: _5!) } else { return nil @@ -1561,73 +1571,39 @@ public extension Api.smsjobs { } } public extension Api.stats { - enum BroadcastRevenueStats: TypeConstructorDescription { - case broadcastRevenueStats(topHoursGraph: Api.StatsGraph, revenueGraph: Api.StatsGraph, balances: Api.BroadcastRevenueBalances, usdRate: Double) + enum BroadcastStats: TypeConstructorDescription { + case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, reactionsPerPost: Api.StatsAbsValueAndPrev, viewsPerStory: Api.StatsAbsValueAndPrev, sharesPerStory: Api.StatsAbsValueAndPrev, reactionsPerStory: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph, ivInteractionsGraph: Api.StatsGraph, viewsBySourceGraph: Api.StatsGraph, newFollowersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, reactionsByEmotionGraph: Api.StatsGraph, storyInteractionsGraph: Api.StatsGraph, storyReactionsByEmotionGraph: Api.StatsGraph, recentPostsInteractions: [Api.PostInteractionCounters]) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .broadcastRevenueStats(let topHoursGraph, let revenueGraph, let balances, let usdRate): + case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let reactionsPerPost, let viewsPerStory, let sharesPerStory, let reactionsPerStory, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let reactionsByEmotionGraph, let storyInteractionsGraph, let storyReactionsByEmotionGraph, let recentPostsInteractions): if boxed { - buffer.appendInt32(1409802903) + buffer.appendInt32(963421692) } + period.serialize(buffer, true) + followers.serialize(buffer, true) + viewsPerPost.serialize(buffer, true) + sharesPerPost.serialize(buffer, true) + reactionsPerPost.serialize(buffer, true) + viewsPerStory.serialize(buffer, true) + sharesPerStory.serialize(buffer, true) + reactionsPerStory.serialize(buffer, true) + enabledNotifications.serialize(buffer, true) + growthGraph.serialize(buffer, true) + followersGraph.serialize(buffer, true) + muteGraph.serialize(buffer, true) topHoursGraph.serialize(buffer, true) - revenueGraph.serialize(buffer, true) - balances.serialize(buffer, true) - serializeDouble(usdRate, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .broadcastRevenueStats(let topHoursGraph, let revenueGraph, let balances, let usdRate): - return ("broadcastRevenueStats", [("topHoursGraph", topHoursGraph as Any), ("revenueGraph", revenueGraph as Any), ("balances", balances as Any), ("usdRate", usdRate as Any)]) - } - } - - public static func parse_broadcastRevenueStats(_ reader: BufferReader) -> BroadcastRevenueStats? { - var _1: Api.StatsGraph? - if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _2: Api.StatsGraph? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _3: Api.BroadcastRevenueBalances? - if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.BroadcastRevenueBalances - } - var _4: Double? - _4 = reader.readDouble() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - if _c1 && _c2 && _c3 && _c4 { - return Api.stats.BroadcastRevenueStats.broadcastRevenueStats(topHoursGraph: _1!, revenueGraph: _2!, balances: _3!, usdRate: _4!) - } - else { - return nil - } - } - - } -} -public extension Api.stats { - enum BroadcastRevenueTransactions: TypeConstructorDescription { - case broadcastRevenueTransactions(count: Int32, transactions: [Api.BroadcastRevenueTransaction]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .broadcastRevenueTransactions(let count, let transactions): - if boxed { - buffer.appendInt32(-2028632986) - } - serializeInt32(count, buffer: buffer, boxed: false) + interactionsGraph.serialize(buffer, true) + ivInteractionsGraph.serialize(buffer, true) + viewsBySourceGraph.serialize(buffer, true) + newFollowersBySourceGraph.serialize(buffer, true) + languagesGraph.serialize(buffer, true) + reactionsByEmotionGraph.serialize(buffer, true) + storyInteractionsGraph.serialize(buffer, true) + storyReactionsByEmotionGraph.serialize(buffer, true) buffer.appendInt32(481674261) - buffer.appendInt32(Int32(transactions.count)) - for item in transactions { + buffer.appendInt32(Int32(recentPostsInteractions.count)) + for item in recentPostsInteractions { item.serialize(buffer, true) } break @@ -1636,22 +1612,124 @@ public extension Api.stats { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .broadcastRevenueTransactions(let count, let transactions): - return ("broadcastRevenueTransactions", [("count", count as Any), ("transactions", transactions as Any)]) + case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let reactionsPerPost, let viewsPerStory, let sharesPerStory, let reactionsPerStory, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let reactionsByEmotionGraph, let storyInteractionsGraph, let storyReactionsByEmotionGraph, let recentPostsInteractions): + return ("broadcastStats", [("period", period as Any), ("followers", followers as Any), ("viewsPerPost", viewsPerPost as Any), ("sharesPerPost", sharesPerPost as Any), ("reactionsPerPost", reactionsPerPost as Any), ("viewsPerStory", viewsPerStory as Any), ("sharesPerStory", sharesPerStory as Any), ("reactionsPerStory", reactionsPerStory as Any), ("enabledNotifications", enabledNotifications as Any), ("growthGraph", growthGraph as Any), ("followersGraph", followersGraph as Any), ("muteGraph", muteGraph as Any), ("topHoursGraph", topHoursGraph as Any), ("interactionsGraph", interactionsGraph as Any), ("ivInteractionsGraph", ivInteractionsGraph as Any), ("viewsBySourceGraph", viewsBySourceGraph as Any), ("newFollowersBySourceGraph", newFollowersBySourceGraph as Any), ("languagesGraph", languagesGraph as Any), ("reactionsByEmotionGraph", reactionsByEmotionGraph as Any), ("storyInteractionsGraph", storyInteractionsGraph as Any), ("storyReactionsByEmotionGraph", storyReactionsByEmotionGraph as Any), ("recentPostsInteractions", recentPostsInteractions as Any)]) } } - public static func parse_broadcastRevenueTransactions(_ reader: BufferReader) -> BroadcastRevenueTransactions? { - var _1: Int32? - _1 = reader.readInt32() - var _2: [Api.BroadcastRevenueTransaction]? + public static func parse_broadcastStats(_ reader: BufferReader) -> BroadcastStats? { + var _1: Api.StatsDateRangeDays? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays + } + var _2: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _3: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _4: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _5: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _6: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _6 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _7: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _7 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _8: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _8 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _9: Api.StatsPercentValue? + if let signature = reader.readInt32() { + _9 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue + } + var _10: Api.StatsGraph? + if let signature = reader.readInt32() { + _10 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _11: Api.StatsGraph? + if let signature = reader.readInt32() { + _11 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _12: Api.StatsGraph? + if let signature = reader.readInt32() { + _12 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _13: Api.StatsGraph? + if let signature = reader.readInt32() { + _13 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _14: Api.StatsGraph? + if let signature = reader.readInt32() { + _14 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _15: Api.StatsGraph? + if let signature = reader.readInt32() { + _15 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _16: Api.StatsGraph? + if let signature = reader.readInt32() { + _16 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _17: Api.StatsGraph? + if let signature = reader.readInt32() { + _17 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _18: Api.StatsGraph? + if let signature = reader.readInt32() { + _18 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _19: Api.StatsGraph? + if let signature = reader.readInt32() { + _19 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _20: Api.StatsGraph? + if let signature = reader.readInt32() { + _20 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _21: Api.StatsGraph? + if let signature = reader.readInt32() { + _21 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _22: [Api.PostInteractionCounters]? if let _ = reader.readInt32() { - _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BroadcastRevenueTransaction.self) + _22 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PostInteractionCounters.self) } let _c1 = _1 != nil let _c2 = _2 != nil - if _c1 && _c2 { - return Api.stats.BroadcastRevenueTransactions.broadcastRevenueTransactions(count: _1!, transactions: _2!) + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + let _c10 = _10 != nil + let _c11 = _11 != nil + let _c12 = _12 != nil + let _c13 = _13 != nil + let _c14 = _14 != nil + let _c15 = _15 != nil + let _c16 = _16 != nil + let _c17 = _17 != nil + let _c18 = _18 != nil + let _c19 = _19 != nil + let _c20 = _20 != nil + let _c21 = _21 != nil + let _c22 = _22 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 { + return Api.stats.BroadcastStats.broadcastStats(period: _1!, followers: _2!, viewsPerPost: _3!, sharesPerPost: _4!, reactionsPerPost: _5!, viewsPerStory: _6!, sharesPerStory: _7!, reactionsPerStory: _8!, enabledNotifications: _9!, growthGraph: _10!, followersGraph: _11!, muteGraph: _12!, topHoursGraph: _13!, interactionsGraph: _14!, ivInteractionsGraph: _15!, viewsBySourceGraph: _16!, newFollowersBySourceGraph: _17!, languagesGraph: _18!, reactionsByEmotionGraph: _19!, storyInteractionsGraph: _20!, storyReactionsByEmotionGraph: _21!, recentPostsInteractions: _22!) } else { return nil @@ -1661,33 +1739,191 @@ public extension Api.stats { } } public extension Api.stats { - enum BroadcastRevenueWithdrawalUrl: TypeConstructorDescription { - case broadcastRevenueWithdrawalUrl(url: String) + enum MegagroupStats: TypeConstructorDescription { + case megagroupStats(period: Api.StatsDateRangeDays, members: Api.StatsAbsValueAndPrev, messages: Api.StatsAbsValueAndPrev, viewers: Api.StatsAbsValueAndPrev, posters: Api.StatsAbsValueAndPrev, growthGraph: Api.StatsGraph, membersGraph: Api.StatsGraph, newMembersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, messagesGraph: Api.StatsGraph, actionsGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, weekdaysGraph: Api.StatsGraph, topPosters: [Api.StatsGroupTopPoster], topAdmins: [Api.StatsGroupTopAdmin], topInviters: [Api.StatsGroupTopInviter], users: [Api.User]) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .broadcastRevenueWithdrawalUrl(let url): + case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users): if boxed { - buffer.appendInt32(-328886473) + buffer.appendInt32(-276825834) + } + period.serialize(buffer, true) + members.serialize(buffer, true) + messages.serialize(buffer, true) + viewers.serialize(buffer, true) + posters.serialize(buffer, true) + growthGraph.serialize(buffer, true) + membersGraph.serialize(buffer, true) + newMembersBySourceGraph.serialize(buffer, true) + languagesGraph.serialize(buffer, true) + messagesGraph.serialize(buffer, true) + actionsGraph.serialize(buffer, true) + topHoursGraph.serialize(buffer, true) + weekdaysGraph.serialize(buffer, true) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(topPosters.count)) + for item in topPosters { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(topAdmins.count)) + for item in topAdmins { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(topInviters.count)) + for item in topInviters { + item.serialize(buffer, true) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users.count)) + for item in users { + item.serialize(buffer, true) } - serializeString(url, buffer: buffer, boxed: false) break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .broadcastRevenueWithdrawalUrl(let url): - return ("broadcastRevenueWithdrawalUrl", [("url", url as Any)]) + case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users): + return ("megagroupStats", [("period", period as Any), ("members", members as Any), ("messages", messages as Any), ("viewers", viewers as Any), ("posters", posters as Any), ("growthGraph", growthGraph as Any), ("membersGraph", membersGraph as Any), ("newMembersBySourceGraph", newMembersBySourceGraph as Any), ("languagesGraph", languagesGraph as Any), ("messagesGraph", messagesGraph as Any), ("actionsGraph", actionsGraph as Any), ("topHoursGraph", topHoursGraph as Any), ("weekdaysGraph", weekdaysGraph as Any), ("topPosters", topPosters as Any), ("topAdmins", topAdmins as Any), ("topInviters", topInviters as Any), ("users", users as Any)]) } } - public static func parse_broadcastRevenueWithdrawalUrl(_ reader: BufferReader) -> BroadcastRevenueWithdrawalUrl? { - var _1: String? - _1 = parseString(reader) + public static func parse_megagroupStats(_ reader: BufferReader) -> MegagroupStats? { + var _1: Api.StatsDateRangeDays? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays + } + var _2: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _3: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _4: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _5: Api.StatsAbsValueAndPrev? + if let signature = reader.readInt32() { + _5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev + } + var _6: Api.StatsGraph? + if let signature = reader.readInt32() { + _6 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _7: Api.StatsGraph? + if let signature = reader.readInt32() { + _7 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _8: Api.StatsGraph? + if let signature = reader.readInt32() { + _8 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _9: Api.StatsGraph? + if let signature = reader.readInt32() { + _9 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _10: Api.StatsGraph? + if let signature = reader.readInt32() { + _10 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _11: Api.StatsGraph? + if let signature = reader.readInt32() { + _11 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _12: Api.StatsGraph? + if let signature = reader.readInt32() { + _12 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _13: Api.StatsGraph? + if let signature = reader.readInt32() { + _13 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _14: [Api.StatsGroupTopPoster]? + if let _ = reader.readInt32() { + _14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopPoster.self) + } + var _15: [Api.StatsGroupTopAdmin]? + if let _ = reader.readInt32() { + _15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopAdmin.self) + } + var _16: [Api.StatsGroupTopInviter]? + if let _ = reader.readInt32() { + _16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopInviter.self) + } + var _17: [Api.User]? + if let _ = reader.readInt32() { + _17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + } let _c1 = _1 != nil - if _c1 { - return Api.stats.BroadcastRevenueWithdrawalUrl.broadcastRevenueWithdrawalUrl(url: _1!) + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + let _c10 = _10 != nil + let _c11 = _11 != nil + let _c12 = _12 != nil + let _c13 = _13 != nil + let _c14 = _14 != nil + let _c15 = _15 != nil + let _c16 = _16 != nil + let _c17 = _17 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 { + return Api.stats.MegagroupStats.megagroupStats(period: _1!, members: _2!, messages: _3!, viewers: _4!, posters: _5!, growthGraph: _6!, membersGraph: _7!, newMembersBySourceGraph: _8!, languagesGraph: _9!, messagesGraph: _10!, actionsGraph: _11!, topHoursGraph: _12!, weekdaysGraph: _13!, topPosters: _14!, topAdmins: _15!, topInviters: _16!, users: _17!) + } + else { + return nil + } + } + + } +} +public extension Api.stats { + enum MessageStats: TypeConstructorDescription { + case messageStats(viewsGraph: Api.StatsGraph, reactionsByEmotionGraph: Api.StatsGraph) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .messageStats(let viewsGraph, let reactionsByEmotionGraph): + if boxed { + buffer.appendInt32(2145983508) + } + viewsGraph.serialize(buffer, true) + reactionsByEmotionGraph.serialize(buffer, true) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .messageStats(let viewsGraph, let reactionsByEmotionGraph): + return ("messageStats", [("viewsGraph", viewsGraph as Any), ("reactionsByEmotionGraph", reactionsByEmotionGraph as Any)]) + } + } + + public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? { + var _1: Api.StatsGraph? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + var _2: Api.StatsGraph? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.StatsGraph + } + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return Api.stats.MessageStats.messageStats(viewsGraph: _1!, reactionsByEmotionGraph: _2!) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api37.swift b/submodules/TelegramApi/Sources/Api37.swift index e3c0df82da..7e36ea42bf 100644 --- a/submodules/TelegramApi/Sources/Api37.swift +++ b/submodules/TelegramApi/Sources/Api37.swift @@ -1,365 +1,3 @@ -public extension Api.stats { - enum BroadcastStats: TypeConstructorDescription { - case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, reactionsPerPost: Api.StatsAbsValueAndPrev, viewsPerStory: Api.StatsAbsValueAndPrev, sharesPerStory: Api.StatsAbsValueAndPrev, reactionsPerStory: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph, ivInteractionsGraph: Api.StatsGraph, viewsBySourceGraph: Api.StatsGraph, newFollowersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, reactionsByEmotionGraph: Api.StatsGraph, storyInteractionsGraph: Api.StatsGraph, storyReactionsByEmotionGraph: Api.StatsGraph, recentPostsInteractions: [Api.PostInteractionCounters]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let reactionsPerPost, let viewsPerStory, let sharesPerStory, let reactionsPerStory, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let reactionsByEmotionGraph, let storyInteractionsGraph, let storyReactionsByEmotionGraph, let recentPostsInteractions): - if boxed { - buffer.appendInt32(963421692) - } - period.serialize(buffer, true) - followers.serialize(buffer, true) - viewsPerPost.serialize(buffer, true) - sharesPerPost.serialize(buffer, true) - reactionsPerPost.serialize(buffer, true) - viewsPerStory.serialize(buffer, true) - sharesPerStory.serialize(buffer, true) - reactionsPerStory.serialize(buffer, true) - enabledNotifications.serialize(buffer, true) - growthGraph.serialize(buffer, true) - followersGraph.serialize(buffer, true) - muteGraph.serialize(buffer, true) - topHoursGraph.serialize(buffer, true) - interactionsGraph.serialize(buffer, true) - ivInteractionsGraph.serialize(buffer, true) - viewsBySourceGraph.serialize(buffer, true) - newFollowersBySourceGraph.serialize(buffer, true) - languagesGraph.serialize(buffer, true) - reactionsByEmotionGraph.serialize(buffer, true) - storyInteractionsGraph.serialize(buffer, true) - storyReactionsByEmotionGraph.serialize(buffer, true) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(recentPostsInteractions.count)) - for item in recentPostsInteractions { - item.serialize(buffer, true) - } - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .broadcastStats(let period, let followers, let viewsPerPost, let sharesPerPost, let reactionsPerPost, let viewsPerStory, let sharesPerStory, let reactionsPerStory, let enabledNotifications, let growthGraph, let followersGraph, let muteGraph, let topHoursGraph, let interactionsGraph, let ivInteractionsGraph, let viewsBySourceGraph, let newFollowersBySourceGraph, let languagesGraph, let reactionsByEmotionGraph, let storyInteractionsGraph, let storyReactionsByEmotionGraph, let recentPostsInteractions): - return ("broadcastStats", [("period", period as Any), ("followers", followers as Any), ("viewsPerPost", viewsPerPost as Any), ("sharesPerPost", sharesPerPost as Any), ("reactionsPerPost", reactionsPerPost as Any), ("viewsPerStory", viewsPerStory as Any), ("sharesPerStory", sharesPerStory as Any), ("reactionsPerStory", reactionsPerStory as Any), ("enabledNotifications", enabledNotifications as Any), ("growthGraph", growthGraph as Any), ("followersGraph", followersGraph as Any), ("muteGraph", muteGraph as Any), ("topHoursGraph", topHoursGraph as Any), ("interactionsGraph", interactionsGraph as Any), ("ivInteractionsGraph", ivInteractionsGraph as Any), ("viewsBySourceGraph", viewsBySourceGraph as Any), ("newFollowersBySourceGraph", newFollowersBySourceGraph as Any), ("languagesGraph", languagesGraph as Any), ("reactionsByEmotionGraph", reactionsByEmotionGraph as Any), ("storyInteractionsGraph", storyInteractionsGraph as Any), ("storyReactionsByEmotionGraph", storyReactionsByEmotionGraph as Any), ("recentPostsInteractions", recentPostsInteractions as Any)]) - } - } - - public static func parse_broadcastStats(_ reader: BufferReader) -> BroadcastStats? { - var _1: Api.StatsDateRangeDays? - if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays - } - var _2: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _3: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _4: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _5: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _6: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _6 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _7: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _7 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _8: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _8 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _9: Api.StatsPercentValue? - if let signature = reader.readInt32() { - _9 = Api.parse(reader, signature: signature) as? Api.StatsPercentValue - } - var _10: Api.StatsGraph? - if let signature = reader.readInt32() { - _10 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _11: Api.StatsGraph? - if let signature = reader.readInt32() { - _11 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _12: Api.StatsGraph? - if let signature = reader.readInt32() { - _12 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _13: Api.StatsGraph? - if let signature = reader.readInt32() { - _13 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _14: Api.StatsGraph? - if let signature = reader.readInt32() { - _14 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _15: Api.StatsGraph? - if let signature = reader.readInt32() { - _15 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _16: Api.StatsGraph? - if let signature = reader.readInt32() { - _16 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _17: Api.StatsGraph? - if let signature = reader.readInt32() { - _17 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _18: Api.StatsGraph? - if let signature = reader.readInt32() { - _18 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _19: Api.StatsGraph? - if let signature = reader.readInt32() { - _19 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _20: Api.StatsGraph? - if let signature = reader.readInt32() { - _20 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _21: Api.StatsGraph? - if let signature = reader.readInt32() { - _21 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _22: [Api.PostInteractionCounters]? - if let _ = reader.readInt32() { - _22 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PostInteractionCounters.self) - } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - let _c5 = _5 != nil - let _c6 = _6 != nil - let _c7 = _7 != nil - let _c8 = _8 != nil - let _c9 = _9 != nil - let _c10 = _10 != nil - let _c11 = _11 != nil - let _c12 = _12 != nil - let _c13 = _13 != nil - let _c14 = _14 != nil - let _c15 = _15 != nil - let _c16 = _16 != nil - let _c17 = _17 != nil - let _c18 = _18 != nil - let _c19 = _19 != nil - let _c20 = _20 != nil - let _c21 = _21 != nil - let _c22 = _22 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 { - return Api.stats.BroadcastStats.broadcastStats(period: _1!, followers: _2!, viewsPerPost: _3!, sharesPerPost: _4!, reactionsPerPost: _5!, viewsPerStory: _6!, sharesPerStory: _7!, reactionsPerStory: _8!, enabledNotifications: _9!, growthGraph: _10!, followersGraph: _11!, muteGraph: _12!, topHoursGraph: _13!, interactionsGraph: _14!, ivInteractionsGraph: _15!, viewsBySourceGraph: _16!, newFollowersBySourceGraph: _17!, languagesGraph: _18!, reactionsByEmotionGraph: _19!, storyInteractionsGraph: _20!, storyReactionsByEmotionGraph: _21!, recentPostsInteractions: _22!) - } - else { - return nil - } - } - - } -} -public extension Api.stats { - enum MegagroupStats: TypeConstructorDescription { - case megagroupStats(period: Api.StatsDateRangeDays, members: Api.StatsAbsValueAndPrev, messages: Api.StatsAbsValueAndPrev, viewers: Api.StatsAbsValueAndPrev, posters: Api.StatsAbsValueAndPrev, growthGraph: Api.StatsGraph, membersGraph: Api.StatsGraph, newMembersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, messagesGraph: Api.StatsGraph, actionsGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, weekdaysGraph: Api.StatsGraph, topPosters: [Api.StatsGroupTopPoster], topAdmins: [Api.StatsGroupTopAdmin], topInviters: [Api.StatsGroupTopInviter], users: [Api.User]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users): - if boxed { - buffer.appendInt32(-276825834) - } - period.serialize(buffer, true) - members.serialize(buffer, true) - messages.serialize(buffer, true) - viewers.serialize(buffer, true) - posters.serialize(buffer, true) - growthGraph.serialize(buffer, true) - membersGraph.serialize(buffer, true) - newMembersBySourceGraph.serialize(buffer, true) - languagesGraph.serialize(buffer, true) - messagesGraph.serialize(buffer, true) - actionsGraph.serialize(buffer, true) - topHoursGraph.serialize(buffer, true) - weekdaysGraph.serialize(buffer, true) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(topPosters.count)) - for item in topPosters { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(topAdmins.count)) - for item in topAdmins { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(topInviters.count)) - for item in topInviters { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(users.count)) - for item in users { - item.serialize(buffer, true) - } - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .megagroupStats(let period, let members, let messages, let viewers, let posters, let growthGraph, let membersGraph, let newMembersBySourceGraph, let languagesGraph, let messagesGraph, let actionsGraph, let topHoursGraph, let weekdaysGraph, let topPosters, let topAdmins, let topInviters, let users): - return ("megagroupStats", [("period", period as Any), ("members", members as Any), ("messages", messages as Any), ("viewers", viewers as Any), ("posters", posters as Any), ("growthGraph", growthGraph as Any), ("membersGraph", membersGraph as Any), ("newMembersBySourceGraph", newMembersBySourceGraph as Any), ("languagesGraph", languagesGraph as Any), ("messagesGraph", messagesGraph as Any), ("actionsGraph", actionsGraph as Any), ("topHoursGraph", topHoursGraph as Any), ("weekdaysGraph", weekdaysGraph as Any), ("topPosters", topPosters as Any), ("topAdmins", topAdmins as Any), ("topInviters", topInviters as Any), ("users", users as Any)]) - } - } - - public static func parse_megagroupStats(_ reader: BufferReader) -> MegagroupStats? { - var _1: Api.StatsDateRangeDays? - if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.StatsDateRangeDays - } - var _2: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _3: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _4: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _5: Api.StatsAbsValueAndPrev? - if let signature = reader.readInt32() { - _5 = Api.parse(reader, signature: signature) as? Api.StatsAbsValueAndPrev - } - var _6: Api.StatsGraph? - if let signature = reader.readInt32() { - _6 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _7: Api.StatsGraph? - if let signature = reader.readInt32() { - _7 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _8: Api.StatsGraph? - if let signature = reader.readInt32() { - _8 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _9: Api.StatsGraph? - if let signature = reader.readInt32() { - _9 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _10: Api.StatsGraph? - if let signature = reader.readInt32() { - _10 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _11: Api.StatsGraph? - if let signature = reader.readInt32() { - _11 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _12: Api.StatsGraph? - if let signature = reader.readInt32() { - _12 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _13: Api.StatsGraph? - if let signature = reader.readInt32() { - _13 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _14: [Api.StatsGroupTopPoster]? - if let _ = reader.readInt32() { - _14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopPoster.self) - } - var _15: [Api.StatsGroupTopAdmin]? - if let _ = reader.readInt32() { - _15 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopAdmin.self) - } - var _16: [Api.StatsGroupTopInviter]? - if let _ = reader.readInt32() { - _16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StatsGroupTopInviter.self) - } - var _17: [Api.User]? - if let _ = reader.readInt32() { - _17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) - } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - let _c5 = _5 != nil - let _c6 = _6 != nil - let _c7 = _7 != nil - let _c8 = _8 != nil - let _c9 = _9 != nil - let _c10 = _10 != nil - let _c11 = _11 != nil - let _c12 = _12 != nil - let _c13 = _13 != nil - let _c14 = _14 != nil - let _c15 = _15 != nil - let _c16 = _16 != nil - let _c17 = _17 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 { - return Api.stats.MegagroupStats.megagroupStats(period: _1!, members: _2!, messages: _3!, viewers: _4!, posters: _5!, growthGraph: _6!, membersGraph: _7!, newMembersBySourceGraph: _8!, languagesGraph: _9!, messagesGraph: _10!, actionsGraph: _11!, topHoursGraph: _12!, weekdaysGraph: _13!, topPosters: _14!, topAdmins: _15!, topInviters: _16!, users: _17!) - } - else { - return nil - } - } - - } -} -public extension Api.stats { - enum MessageStats: TypeConstructorDescription { - case messageStats(viewsGraph: Api.StatsGraph, reactionsByEmotionGraph: Api.StatsGraph) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .messageStats(let viewsGraph, let reactionsByEmotionGraph): - if boxed { - buffer.appendInt32(2145983508) - } - viewsGraph.serialize(buffer, true) - reactionsByEmotionGraph.serialize(buffer, true) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .messageStats(let viewsGraph, let reactionsByEmotionGraph): - return ("messageStats", [("viewsGraph", viewsGraph as Any), ("reactionsByEmotionGraph", reactionsByEmotionGraph as Any)]) - } - } - - public static func parse_messageStats(_ reader: BufferReader) -> MessageStats? { - var _1: Api.StatsGraph? - if let signature = reader.readInt32() { - _1 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - var _2: Api.StatsGraph? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.StatsGraph - } - let _c1 = _1 != nil - let _c2 = _2 != nil - if _c1 && _c2 { - return Api.stats.MessageStats.messageStats(viewsGraph: _1!, reactionsByEmotionGraph: _2!) - } - else { - return nil - } - } - - } -} public extension Api.stats { enum PublicForwards: TypeConstructorDescription { case publicForwards(flags: Int32, count: Int32, forwards: [Api.PublicForward], nextOffset: String?, chats: [Api.Chat], users: [Api.User]) @@ -1596,3 +1234,111 @@ public extension Api.updates { } } +public extension Api.updates { + enum State: TypeConstructorDescription { + case state(pts: Int32, qts: Int32, date: Int32, seq: Int32, unreadCount: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .state(let pts, let qts, let date, let seq, let unreadCount): + if boxed { + buffer.appendInt32(-1519637954) + } + serializeInt32(pts, buffer: buffer, boxed: false) + serializeInt32(qts, buffer: buffer, boxed: false) + serializeInt32(date, buffer: buffer, boxed: false) + serializeInt32(seq, buffer: buffer, boxed: false) + serializeInt32(unreadCount, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .state(let pts, let qts, let date, let seq, let unreadCount): + return ("state", [("pts", pts as Any), ("qts", qts as Any), ("date", date as Any), ("seq", seq as Any), ("unreadCount", unreadCount as Any)]) + } + } + + public static func parse_state(_ reader: BufferReader) -> State? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: Int32? + _5 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.updates.State.state(pts: _1!, qts: _2!, date: _3!, seq: _4!, unreadCount: _5!) + } + else { + return nil + } + } + + } +} +public extension Api.upload { + enum CdnFile: TypeConstructorDescription { + case cdnFile(bytes: Buffer) + case cdnFileReuploadNeeded(requestToken: Buffer) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .cdnFile(let bytes): + if boxed { + buffer.appendInt32(-1449145777) + } + serializeBytes(bytes, buffer: buffer, boxed: false) + break + case .cdnFileReuploadNeeded(let requestToken): + if boxed { + buffer.appendInt32(-290921362) + } + serializeBytes(requestToken, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .cdnFile(let bytes): + return ("cdnFile", [("bytes", bytes as Any)]) + case .cdnFileReuploadNeeded(let requestToken): + return ("cdnFileReuploadNeeded", [("requestToken", requestToken as Any)]) + } + } + + public static func parse_cdnFile(_ reader: BufferReader) -> CdnFile? { + var _1: Buffer? + _1 = parseBytes(reader) + let _c1 = _1 != nil + if _c1 { + return Api.upload.CdnFile.cdnFile(bytes: _1!) + } + else { + return nil + } + } + public static func parse_cdnFileReuploadNeeded(_ reader: BufferReader) -> CdnFile? { + var _1: Buffer? + _1 = parseBytes(reader) + let _c1 = _1 != nil + if _c1 { + return Api.upload.CdnFile.cdnFileReuploadNeeded(requestToken: _1!) + } + else { + return nil + } + } + + } +} diff --git a/submodules/TelegramApi/Sources/Api38.swift b/submodules/TelegramApi/Sources/Api38.swift index 281a495dbf..df11f101cb 100644 --- a/submodules/TelegramApi/Sources/Api38.swift +++ b/submodules/TelegramApi/Sources/Api38.swift @@ -1,111 +1,3 @@ -public extension Api.updates { - enum State: TypeConstructorDescription { - case state(pts: Int32, qts: Int32, date: Int32, seq: Int32, unreadCount: Int32) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .state(let pts, let qts, let date, let seq, let unreadCount): - if boxed { - buffer.appendInt32(-1519637954) - } - serializeInt32(pts, buffer: buffer, boxed: false) - serializeInt32(qts, buffer: buffer, boxed: false) - serializeInt32(date, buffer: buffer, boxed: false) - serializeInt32(seq, buffer: buffer, boxed: false) - serializeInt32(unreadCount, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .state(let pts, let qts, let date, let seq, let unreadCount): - return ("state", [("pts", pts as Any), ("qts", qts as Any), ("date", date as Any), ("seq", seq as Any), ("unreadCount", unreadCount as Any)]) - } - } - - public static func parse_state(_ reader: BufferReader) -> State? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - var _3: Int32? - _3 = reader.readInt32() - var _4: Int32? - _4 = reader.readInt32() - var _5: Int32? - _5 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - let _c5 = _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.updates.State.state(pts: _1!, qts: _2!, date: _3!, seq: _4!, unreadCount: _5!) - } - else { - return nil - } - } - - } -} -public extension Api.upload { - enum CdnFile: TypeConstructorDescription { - case cdnFile(bytes: Buffer) - case cdnFileReuploadNeeded(requestToken: Buffer) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .cdnFile(let bytes): - if boxed { - buffer.appendInt32(-1449145777) - } - serializeBytes(bytes, buffer: buffer, boxed: false) - break - case .cdnFileReuploadNeeded(let requestToken): - if boxed { - buffer.appendInt32(-290921362) - } - serializeBytes(requestToken, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .cdnFile(let bytes): - return ("cdnFile", [("bytes", bytes as Any)]) - case .cdnFileReuploadNeeded(let requestToken): - return ("cdnFileReuploadNeeded", [("requestToken", requestToken as Any)]) - } - } - - public static func parse_cdnFile(_ reader: BufferReader) -> CdnFile? { - var _1: Buffer? - _1 = parseBytes(reader) - let _c1 = _1 != nil - if _c1 { - return Api.upload.CdnFile.cdnFile(bytes: _1!) - } - else { - return nil - } - } - public static func parse_cdnFileReuploadNeeded(_ reader: BufferReader) -> CdnFile? { - var _1: Buffer? - _1 = parseBytes(reader) - let _c1 = _1 != nil - if _c1 { - return Api.upload.CdnFile.cdnFileReuploadNeeded(requestToken: _1!) - } - else { - return nil - } - } - - } -} public extension Api.upload { enum File: TypeConstructorDescription { case file(type: Api.storage.FileType, mtime: Int32, bytes: Buffer) diff --git a/submodules/TelegramApi/Sources/Api39.swift b/submodules/TelegramApi/Sources/Api39.swift index 341867958d..7bd3b42275 100644 --- a/submodules/TelegramApi/Sources/Api39.swift +++ b/submodules/TelegramApi/Sources/Api39.swift @@ -9674,13 +9674,14 @@ public extension Api.functions.payments { } } public extension Api.functions.payments { - static func getStarsRevenueWithdrawalUrl(peer: Api.InputPeer, stars: Int64, password: Api.InputCheckPasswordSRP) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getStarsRevenueWithdrawalUrl(flags: Int32, peer: Api.InputPeer, amount: Int64?, password: Api.InputCheckPasswordSRP) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(331081907) + buffer.appendInt32(607378578) + serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) - serializeInt64(stars, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 1) != 0 {serializeInt64(amount!, buffer: buffer, boxed: false)} password.serialize(buffer, true) - return (FunctionDescription(name: "payments.getStarsRevenueWithdrawalUrl", parameters: [("peer", String(describing: peer)), ("stars", String(describing: stars)), ("password", String(describing: password))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsRevenueWithdrawalUrl? in + return (FunctionDescription(name: "payments.getStarsRevenueWithdrawalUrl", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("amount", String(describing: amount)), ("password", String(describing: password))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsRevenueWithdrawalUrl? in let reader = BufferReader(buffer) var result: Api.payments.StarsRevenueWithdrawalUrl? if let signature = reader.readInt32() { @@ -9758,16 +9759,17 @@ public extension Api.functions.payments { } } public extension Api.functions.payments { - static func getStarsTransactionsByID(peer: Api.InputPeer, id: [Api.InputStarsTransaction]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getStarsTransactionsByID(flags: Int32, peer: Api.InputPeer, id: [Api.InputStarsTransaction]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(662973742) + buffer.appendInt32(768218808) + serializeInt32(flags, buffer: buffer, boxed: false) peer.serialize(buffer, true) buffer.appendInt32(481674261) buffer.appendInt32(Int32(id.count)) for item in id { item.serialize(buffer, true) } - return (FunctionDescription(name: "payments.getStarsTransactionsByID", parameters: [("peer", String(describing: peer)), ("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in + return (FunctionDescription(name: "payments.getStarsTransactionsByID", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in let reader = BufferReader(buffer) var result: Api.payments.StarsStatus? if let signature = reader.readInt32() { @@ -10927,55 +10929,6 @@ public extension Api.functions.smsjobs { }) } } -public extension Api.functions.stats { - static func getBroadcastRevenueStats(flags: Int32, peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-142021095) - serializeInt32(flags, buffer: buffer, boxed: false) - peer.serialize(buffer, true) - return (FunctionDescription(name: "stats.getBroadcastRevenueStats", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueStats? in - let reader = BufferReader(buffer) - var result: Api.stats.BroadcastRevenueStats? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.stats.BroadcastRevenueStats - } - return result - }) - } -} -public extension Api.functions.stats { - static func getBroadcastRevenueTransactions(peer: Api.InputPeer, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(1889078125) - peer.serialize(buffer, true) - serializeInt32(offset, buffer: buffer, boxed: false) - serializeInt32(limit, buffer: buffer, boxed: false) - return (FunctionDescription(name: "stats.getBroadcastRevenueTransactions", parameters: [("peer", String(describing: peer)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueTransactions? in - let reader = BufferReader(buffer) - var result: Api.stats.BroadcastRevenueTransactions? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.stats.BroadcastRevenueTransactions - } - return result - }) - } -} -public extension Api.functions.stats { - static func getBroadcastRevenueWithdrawalUrl(peer: Api.InputPeer, password: Api.InputCheckPasswordSRP) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-1644889427) - peer.serialize(buffer, true) - password.serialize(buffer, true) - return (FunctionDescription(name: "stats.getBroadcastRevenueWithdrawalUrl", parameters: [("peer", String(describing: peer)), ("password", String(describing: password))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.BroadcastRevenueWithdrawalUrl? in - let reader = BufferReader(buffer) - var result: Api.stats.BroadcastRevenueWithdrawalUrl? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.stats.BroadcastRevenueWithdrawalUrl - } - return result - }) - } -} public extension Api.functions.stats { static func getBroadcastStats(flags: Int32, channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() diff --git a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift index c1778a9068..de69062dd6 100644 --- a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift +++ b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift @@ -129,7 +129,6 @@ enum AccountStateMutationOperation { case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction) case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String) case UpdateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) - case UpdateRevenueBalances(peerId: PeerId, balances: RevenueStats.Balances) case UpdateStarsBalance(peerId: PeerId, currency: CurrencyAmount.Currency, balance: StarsAmount) case UpdateStarsRevenueStatus(peerId: PeerId, status: StarsRevenueStats.Balances) case UpdateStarsReactionsDefaultPrivacy(privacy: TelegramPaidReactionPrivacy) @@ -692,10 +691,6 @@ struct AccountMutableState { self.addOperation(.UpdateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date, device: device, location: location)) } - mutating func updateRevenueBalances(peerId: PeerId, balances: RevenueStats.Balances) { - self.addOperation(.UpdateRevenueBalances(peerId: peerId, balances: balances)) - } - mutating func updateStarsBalance(peerId: PeerId, currency: CurrencyAmount.Currency, balance: StarsAmount) { self.addOperation(.UpdateStarsBalance(peerId: peerId, currency: currency, balance: balance)) } @@ -714,7 +709,7 @@ struct AccountMutableState { mutating func addOperation(_ operation: AccountStateMutationOperation) { switch operation { - case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery: + case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery: break case let .AddMessages(messages, location): for message in messages { @@ -858,7 +853,6 @@ struct AccountReplayedFinalState { let updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] let updateConfig: Bool let isPremiumUpdated: Bool - let updatedRevenueBalances: [PeerId: RevenueStats.Balances] let updatedStarsBalance: [PeerId: StarsAmount] let updatedTonBalance: [PeerId: StarsAmount] let updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] @@ -892,7 +886,6 @@ struct AccountFinalStateEvents { let updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] let updateConfig: Bool let isPremiumUpdated: Bool - let updatedRevenueBalances: [PeerId: RevenueStats.Balances] let updatedStarsBalance: [PeerId: StarsAmount] let updatedTonBalance: [PeerId: StarsAmount] let updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] @@ -900,10 +893,10 @@ struct AccountFinalStateEvents { let addedConferenceInvitationMessagesIds: [MessageId] var isEmpty: Bool { - return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.sentScheduledMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedRevenueBalances.isEmpty && self.updatedStarsBalance.isEmpty && self.updatedTonBalance.isEmpty && self.updatedStarsRevenueStatus.isEmpty && self.reportMessageDelivery.isEmpty && self.addedConferenceInvitationMessagesIds.isEmpty + return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.sentScheduledMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedStarsBalance.isEmpty && self.updatedTonBalance.isEmpty && self.updatedStarsRevenueStatus.isEmpty && self.reportMessageDelivery.isEmpty && self.addedConferenceInvitationMessagesIds.isEmpty } - init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedRevenueBalances: [PeerId: RevenueStats.Balances] = [:], updatedStarsBalance: [PeerId: StarsAmount] = [:], updatedTonBalance: [PeerId: StarsAmount] = [:], updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:], sentScheduledMessageIds: Set = Set(), reportMessageDelivery: Set = Set(), addedConferenceInvitationMessagesIds: [MessageId] = []) { + init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedStarsBalance: [PeerId: StarsAmount] = [:], updatedTonBalance: [PeerId: StarsAmount] = [:], updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:], sentScheduledMessageIds: Set = Set(), reportMessageDelivery: Set = Set(), addedConferenceInvitationMessagesIds: [MessageId] = []) { self.addedIncomingMessageIds = addedIncomingMessageIds self.addedReactionEvents = addedReactionEvents self.wasScheduledMessageIds = wasScheduledMessageIds @@ -927,7 +920,6 @@ struct AccountFinalStateEvents { self.updatedOutgoingThreadReadStates = updatedOutgoingThreadReadStates self.updateConfig = updateConfig self.isPremiumUpdated = isPremiumUpdated - self.updatedRevenueBalances = updatedRevenueBalances self.updatedStarsBalance = updatedStarsBalance self.updatedTonBalance = updatedTonBalance self.updatedStarsRevenueStatus = updatedStarsRevenueStatus @@ -960,7 +952,6 @@ struct AccountFinalStateEvents { self.updatedOutgoingThreadReadStates = state.updatedOutgoingThreadReadStates self.updateConfig = state.updateConfig self.isPremiumUpdated = state.isPremiumUpdated - self.updatedRevenueBalances = state.updatedRevenueBalances self.updatedStarsBalance = state.updatedStarsBalance self.updatedTonBalance = state.updatedTonBalance self.updatedStarsRevenueStatus = state.updatedStarsRevenueStatus @@ -1027,7 +1018,6 @@ struct AccountFinalStateEvents { updatedIncomingThreadReadStates: self.updatedIncomingThreadReadStates.merging(other.updatedIncomingThreadReadStates,uniquingKeysWith: { lhs, _ in lhs }), updateConfig: updateConfig, isPremiumUpdated: isPremiumUpdated, - updatedRevenueBalances: self.updatedRevenueBalances.merging(other.updatedRevenueBalances, uniquingKeysWith: { lhs, _ in lhs }), updatedStarsBalance: self.updatedStarsBalance.merging(other.updatedStarsBalance, uniquingKeysWith: { lhs, _ in lhs }), updatedTonBalance: self.updatedTonBalance.merging(other.updatedTonBalance, uniquingKeysWith: { lhs, _ in lhs }), updatedStarsRevenueStatus: self.updatedStarsRevenueStatus.merging(other.updatedStarsRevenueStatus, uniquingKeysWith: { lhs, _ in lhs }), diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index eb7de8d13b..070586f06c 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -232,7 +232,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] { } switch action { - case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon: + case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund: break case let .messageActionChannelMigrateFrom(_, chatId): result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))) diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift index 8354858c1a..3a58f9ad9c 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift @@ -264,6 +264,10 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe return TelegramMediaAction(action: .suggestedPostApprovalStatus(status: status)) case let .messageActionGiftTon(_, currency, amount, cryptoCurrency, cryptoAmount, transactionId): return TelegramMediaAction(action: .giftTon(currency: currency, amount: amount, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, transactionId: transactionId)) + case .messageActionSuggestedPostSuccess: + return nil + case .messageActionSuggestedPostRefund: + return nil } } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index d6414b9638..69c0c11f0c 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -1836,8 +1836,6 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox: updatedState.updateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date ?? 0, device: device ?? "", location: location ?? "") case let .updatePeerWallpaper(_, peer, wallpaper): updatedState.updateWallpaper(peerId: peer.peerId, wallpaper: wallpaper.flatMap { TelegramWallpaper(apiWallpaper: $0) }) - case let .updateBroadcastRevenueTransactions(peer, balances): - updatedState.updateRevenueBalances(peerId: peer.peerId, balances: RevenueStats.Balances(apiRevenueBalances: balances)) case let .updateStarsBalance(balance): let amount = CurrencyAmount(apiAmount: balance) updatedState.updateStarsBalance(peerId: accountPeerId, currency: amount.currency, balance: amount.amount) @@ -3581,7 +3579,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation]) var currentAddQuickReplyMessages: OptimizeAddMessagesState? for operation in operations { switch operation { - case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery: + case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery: if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) } @@ -3716,7 +3714,6 @@ func replayFinalState( var deletedMessageIds: [DeletedMessageId] = [] var syncAttachMenuBots = false var updateConfig = false - var updatedRevenueBalances: [PeerId: RevenueStats.Balances] = [:] var updatedStarsBalance: [PeerId: StarsAmount] = [:] var updatedTonBalance: [PeerId: StarsAmount] = [:] var updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:] @@ -5169,8 +5166,6 @@ func replayFinalState( } else { transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.NewSessionReviews, itemId: id.rawValue) } - case let .UpdateRevenueBalances(peerId, balances): - updatedRevenueBalances[peerId] = balances case let .UpdateStarsBalance(peerId, currency, balance): switch currency { case .ton: @@ -5702,7 +5697,6 @@ func replayFinalState( updatedOutgoingThreadReadStates: updatedOutgoingThreadReadStates, updateConfig: updateConfig, isPremiumUpdated: isPremiumUpdated, - updatedRevenueBalances: updatedRevenueBalances, updatedStarsBalance: updatedStarsBalance, updatedTonBalance: updatedTonBalance, updatedStarsRevenueStatus: updatedStarsRevenueStatus, diff --git a/submodules/TelegramCore/Sources/State/AccountStateManager.swift b/submodules/TelegramCore/Sources/State/AccountStateManager.swift index 29d3ae0dd8..59a730582b 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManager.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManager.swift @@ -44,10 +44,6 @@ private final class UpdatedPeersNearbySubscriberContext { let subscribers = Bag<([PeerNearby]) -> Void>() } -private final class UpdatedRevenueBalancesSubscriberContext { - let subscribers = Bag<([PeerId: RevenueStats.Balances]) -> Void>() -} - private final class UpdatedStarsBalanceSubscriberContext { let subscribers = Bag<([PeerId: StarsAmount]) -> Void>() } @@ -353,7 +349,6 @@ public final class AccountStateManager { private var updatedWebpageContexts: [MediaId: UpdatedWebpageSubscriberContext] = [:] private var updatedPeersNearbyContext = UpdatedPeersNearbySubscriberContext() - private var updatedRevenueBalancesContext = UpdatedRevenueBalancesSubscriberContext() private var updatedStarsBalanceContext = UpdatedStarsBalanceSubscriberContext() private var updatedTonBalanceContext = UpdatedStarsBalanceSubscriberContext() private var updatedStarsRevenueStatusContext = UpdatedStarsRevenueStatusSubscriberContext() @@ -1112,9 +1107,6 @@ public final class AccountStateManager { if let updatedPeersNearby = events.updatedPeersNearby { strongSelf.notifyUpdatedPeersNearby(updatedPeersNearby) } - if !events.updatedRevenueBalances.isEmpty { - strongSelf.notifyUpdatedRevenueBalances(events.updatedRevenueBalances) - } if !events.updatedStarsBalance.isEmpty { strongSelf.notifyUpdatedStarsBalance(events.updatedStarsBalance) } @@ -1708,33 +1700,6 @@ public final class AccountStateManager { } } - public func updatedRevenueBalances() -> Signal<[PeerId: RevenueStats.Balances], NoError> { - let queue = self.queue - return Signal { [weak self] subscriber in - let disposable = MetaDisposable() - queue.async { - if let strongSelf = self { - let index = strongSelf.updatedRevenueBalancesContext.subscribers.add({ revenueBalances in - subscriber.putNext(revenueBalances) - }) - - disposable.set(ActionDisposable { - if let strongSelf = self { - strongSelf.updatedRevenueBalancesContext.subscribers.remove(index) - } - }) - } - } - return disposable - } - } - - private func notifyUpdatedRevenueBalances(_ updatedRevenueBalances: [PeerId: RevenueStats.Balances]) { - for subscriber in self.updatedRevenueBalancesContext.subscribers.copyItems() { - subscriber(updatedRevenueBalances) - } - } - public func updatedStarsBalance() -> Signal<[PeerId: StarsAmount], NoError> { let queue = self.queue return Signal { [weak self] subscriber in @@ -2165,12 +2130,6 @@ public final class AccountStateManager { } } - public func updatedRevenueBalances() -> Signal<[PeerId: RevenueStats.Balances], NoError> { - return self.impl.signalWith { impl, subscriber in - return impl.updatedRevenueBalances().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) - } - } - public func updatedStarsBalance() -> Signal<[PeerId: StarsAmount], NoError> { return self.impl.signalWith { impl, subscriber in return impl.updatedStarsBalance().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) @@ -2179,7 +2138,7 @@ public final class AccountStateManager { public func updatedTonBalance() -> Signal<[PeerId: StarsAmount], NoError> { return self.impl.signalWith { impl, subscriber in - return impl.updatedStarsBalance().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) + return impl.updatedTonBalance().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) } } diff --git a/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift b/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift deleted file mode 100644 index 1fc95e8463..0000000000 --- a/submodules/TelegramCore/Sources/Statistics/RevenueStatistics.swift +++ /dev/null @@ -1,589 +0,0 @@ -import Foundation -import SwiftSignalKit -import Postbox -import TelegramApi -import MtProtoKit - -public struct RevenueStats: Equatable, Codable { - private enum CodingKeys: String, CodingKey { - case topHoursGraph - case revenueGraph - case balances - case usdRate - } - - static func key(peerId: PeerId) -> ValueBoxKey { - let key = ValueBoxKey(length: 8 + 4) - key.setInt64(0, value: peerId.toInt64()) - return key - } - - public struct Balances: Equatable, Codable { - private enum CodingKeys: String, CodingKey { - case currentBalance - case availableBalance - case overallRevenue - case withdrawEnabled - } - - public let currentBalance: Int64 - public let availableBalance: Int64 - public let overallRevenue: Int64 - public let withdrawEnabled: Bool - - init( - currentBalance: Int64, - availableBalance: Int64, - overallRevenue: Int64, - withdrawEnabled: Bool - ) { - self.currentBalance = currentBalance - self.availableBalance = availableBalance - self.overallRevenue = overallRevenue - self.withdrawEnabled = withdrawEnabled - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.currentBalance = try container.decode(Int64.self, forKey: .currentBalance) - self.availableBalance = try container.decode(Int64.self, forKey: .availableBalance) - self.overallRevenue = try container.decode(Int64.self, forKey: .overallRevenue) - self.withdrawEnabled = try container.decode(Bool.self, forKey: .withdrawEnabled) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(self.currentBalance, forKey: .currentBalance) - try container.encode(self.availableBalance, forKey: .availableBalance) - try container.encode(self.overallRevenue, forKey: .overallRevenue) - try container.encode(self.withdrawEnabled, forKey: .withdrawEnabled) - } - } - - public let topHoursGraph: StatsGraph - public let revenueGraph: StatsGraph - public let balances: Balances - public let usdRate: Double - - init(topHoursGraph: StatsGraph, revenueGraph: StatsGraph, balances: Balances, usdRate: Double) { - self.topHoursGraph = topHoursGraph - self.revenueGraph = revenueGraph - self.balances = balances - self.usdRate = usdRate - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.topHoursGraph = try container.decode(StatsGraph.self, forKey: .topHoursGraph) - self.revenueGraph = try container.decode(StatsGraph.self, forKey: .revenueGraph) - self.balances = try container.decode(Balances.self, forKey: .balances) - self.usdRate = try container.decode(Double.self, forKey: .usdRate) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(self.topHoursGraph, forKey: .topHoursGraph) - try container.encode(self.revenueGraph, forKey: .revenueGraph) - try container.encode(self.balances, forKey: .balances) - try container.encode(self.usdRate, forKey: .usdRate) - } - - public static func == (lhs: RevenueStats, rhs: RevenueStats) -> Bool { - if lhs.topHoursGraph != rhs.topHoursGraph { - return false - } - if lhs.revenueGraph != rhs.revenueGraph { - return false - } - if lhs.balances != rhs.balances { - return false - } - if lhs.usdRate != rhs.usdRate { - return false - } - return true - } -} - -public extension RevenueStats { - func withUpdated(balances: RevenueStats.Balances) -> RevenueStats { - return RevenueStats( - topHoursGraph: self.topHoursGraph, - revenueGraph: self.revenueGraph, - balances: balances, - usdRate: self.usdRate - ) - } -} - -extension RevenueStats { - init(apiRevenueStats: Api.stats.BroadcastRevenueStats, peerId: PeerId) { - switch apiRevenueStats { - case let .broadcastRevenueStats(topHoursGraph, revenueGraph, balances, usdRate): - self.init(topHoursGraph: StatsGraph(apiStatsGraph: topHoursGraph), revenueGraph: StatsGraph(apiStatsGraph: revenueGraph), balances: RevenueStats.Balances(apiRevenueBalances: balances), usdRate: usdRate) - } - } -} - -extension RevenueStats.Balances { - init(apiRevenueBalances: Api.BroadcastRevenueBalances) { - switch apiRevenueBalances { - case let .broadcastRevenueBalances(flags, currentBalance, availableBalance, overallRevenue): - self.init(currentBalance: currentBalance, availableBalance: availableBalance, overallRevenue: overallRevenue, withdrawEnabled: ((flags & (1 << 0)) != 0)) - } - } -} - -public struct RevenueStatsContextState: Equatable { - public var stats: RevenueStats? -} - -private func requestRevenueStats(postbox: Postbox, network: Network, peerId: PeerId, dark: Bool = false) -> Signal { - return postbox.transaction { transaction -> Peer? in - if let peer = transaction.getPeer(peerId) { - return peer - } - return nil - } |> mapToSignal { peer -> Signal in - guard let peer, let channel = peer as? TelegramChannel, case .broadcast = channel.info, let inputPeer = apiInputPeer(peer) else { - return .never() - } - - var flags: Int32 = 0 - if dark { - flags |= (1 << 1) - } - - return network.request(Api.functions.stats.getBroadcastRevenueStats(flags: flags, peer: inputPeer)) - |> map { result -> RevenueStats? in - return RevenueStats(apiRevenueStats: result, peerId: peerId) - } - |> retryRequest - } -} - -private final class RevenueStatsContextImpl { - private let account: Account - private let peerId: PeerId - - private var _state: RevenueStatsContextState { - didSet { - if self._state != oldValue { - self._statePromise.set(.single(self._state)) - } - } - } - private let _statePromise = Promise() - var state: Signal { - return self._statePromise.get() - } - - private let disposable = MetaDisposable() - - init(account: Account, peerId: PeerId) { - assert(Queue.mainQueue().isCurrent()) - - self.account = account - self.peerId = peerId - self._state = RevenueStatsContextState(stats: nil) - self._statePromise.set(.single(self._state)) - - self.load() - - let _ = (account.postbox.transaction { transaction -> RevenueStats? in - return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedRevenueStats, key: StarsRevenueStats.key(peerId: peerId)))?.get(RevenueStats.self) - } - |> deliverOnMainQueue).start(next: { [weak self] cachedResult in - guard let self, let cachedResult else { - return - } - self._state = RevenueStatsContextState(stats: cachedResult) - self._statePromise.set(.single(self._state)) - }) - } - - deinit { - assert(Queue.mainQueue().isCurrent()) - self.disposable.dispose() - } - - fileprivate func load() { - assert(Queue.mainQueue().isCurrent()) - - let account = self.account - let peerId = self.peerId - let signal = requestRevenueStats(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId) - |> mapToSignal { initial -> Signal in - guard let initial else { - return .single(nil) - } - return .single(initial) - |> then( - account.stateManager.updatedRevenueBalances() - |> mapToSignal { updates in - if let balances = updates[peerId] { - return .single(initial.withUpdated(balances: balances)) - } - return .complete() - } - ) - } - - self.disposable.set((signal - |> deliverOnMainQueue).start(next: { [weak self] stats in - if let self { - self._state = RevenueStatsContextState(stats: stats) - self._statePromise.set(.single(self._state)) - - if let stats { - let _ = (self.account.postbox.transaction { transaction in - if let entry = CodableEntry(stats) { - transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedRevenueStats, key: StarsRevenueStats.key(peerId: peerId)), entry: entry) - } - }).start() - } - } - })) - } - - func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal { - if let token = graph.token { - return requestGraph(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId, token: token, x: x) - } else { - return .single(nil) - } - } -} - -public final class RevenueStatsContext { - private let impl: QueueLocalObject - - public var state: Signal { - return Signal { subscriber in - let disposable = MetaDisposable() - self.impl.with { impl in - disposable.set(impl.state.start(next: { value in - subscriber.putNext(value) - })) - } - return disposable - } - } - - public init(account: Account, peerId: PeerId) { - self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: { - return RevenueStatsContextImpl(account: account, peerId: peerId) - }) - } - - public func reload() { - self.impl.with { impl in - impl.load() - } - } - - public func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal { - return Signal { subscriber in - let disposable = MetaDisposable() - self.impl.with { impl in - disposable.set(impl.loadDetailedGraph(graph, x: x).start(next: { value in - subscriber.putNext(value) - subscriber.putCompletion() - })) - } - return disposable - } - } -} - -private final class RevenueStatsTransactionsContextImpl { - private let queue: Queue - private let account: Account - private let peerId: EnginePeer.Id - private let disposable = MetaDisposable() - private var updateDisposable: Disposable? - private var isLoadingMore: Bool = false - private var hasLoadedOnce: Bool = false - private var canLoadMore: Bool = true - private var results: [RevenueStatsTransactionsContext.State.Transaction] = [] - private var count: Int32 - private var lastOffset: Int32? - - let state = Promise() - - init(queue: Queue, account: Account, peerId: EnginePeer.Id) { - self.queue = queue - self.account = account - self.peerId = peerId - - self.count = 0 - - self.loadMore() - - self.updateDisposable = (account.stateManager.updatedRevenueBalances() - |> deliverOn(self.queue)).startStrict(next: { [weak self] _ in - self?.reload() - }) - } - - deinit { - self.disposable.dispose() - self.updateDisposable?.dispose() - } - - func reload() { - self.lastOffset = nil - - self.loadMore() - } - - func loadMore() { - if self.isLoadingMore || !self.canLoadMore { - return - } - self.isLoadingMore = true - let account = self.account - let peerId = self.peerId - let lastOffset = self.lastOffset - - self.disposable.set((self.account.postbox.transaction { transaction -> Peer? in - guard let peer = transaction.getPeer(peerId) else { - return nil - } - return peer - } - |> mapToSignal { peer -> Signal<([RevenueStatsTransactionsContext.State.Transaction], Int32, Int32?), NoError> in - if let peer { - guard let channel = peer as? TelegramChannel, case .broadcast = channel.info, let inputPeer = apiInputPeer(peer) else { - return .complete() - } - let offset = lastOffset ?? 0 - let limit: Int32 = lastOffset == nil ? 25 : 50 - - return account.network.request(Api.functions.stats.getBroadcastRevenueTransactions(peer: inputPeer, offset: offset, limit: limit), automaticFloodWait: false) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) - } - |> mapToSignal { result -> Signal<([RevenueStatsTransactionsContext.State.Transaction], Int32, Int32?), NoError> in - return account.postbox.transaction { transaction -> ([RevenueStatsTransactionsContext.State.Transaction], Int32, Int32?) in - guard let result = result else { - return ([], 0, nil) - } - switch result { - case let .broadcastRevenueTransactions(count, transactions): - let nextOffset = offset + Int32(transactions.count) - var resultTransactions: [RevenueStatsTransactionsContext.State.Transaction] = [] - for transaction in transactions { - switch transaction { - case let .broadcastRevenueTransactionProceeds(amount, fromDate, toDate): - resultTransactions.append(.proceeds(amount: amount, fromDate: fromDate, toDate: toDate)) - case let .broadcastRevenueTransactionRefund(amount, date, provider): - resultTransactions.append(.refund(amount: amount, date: date, provider: provider)) - case let .broadcastRevenueTransactionWithdrawal(flags, amount, date, provider, transactionDate, transactionUrl): - let status: RevenueStatsTransactionsContext.State.Transaction.WithdrawalStatus - if (flags & (1 << 0)) != 0 { - status = .pending - } else if (flags & (1 << 2)) != 0 { - status = .failed - } else { - status = .succeed - } - resultTransactions.append(.withdrawal(status: status, amount: amount, date: date, provider: provider, transactionDate: transactionDate, transactionUrl: transactionUrl)) - } - } - return (resultTransactions, count, nextOffset) - } - } - } - } else { - return .single(([], 0, nil)) - } - } - |> deliverOn(self.queue)).start(next: { [weak self] transactions, updatedCount, nextOffset in - guard let strongSelf = self else { - return - } - strongSelf.lastOffset = nextOffset - for transaction in transactions { - strongSelf.results.append(transaction) - } - strongSelf.isLoadingMore = false - strongSelf.hasLoadedOnce = true - strongSelf.canLoadMore = !transactions.isEmpty && nextOffset != nil - if strongSelf.canLoadMore { - strongSelf.count = max(updatedCount, Int32(strongSelf.results.count)) - } else { - strongSelf.count = Int32(strongSelf.results.count) - } - strongSelf.updateState() - })) - self.updateState() - } - - private func updateState() { - self.state.set(.single(RevenueStatsTransactionsContext.State(transactions: self.results, isLoadingMore: self.isLoadingMore, hasLoadedOnce: self.hasLoadedOnce, canLoadMore: self.canLoadMore, count: self.count))) - } -} - -public final class RevenueStatsTransactionsContext { - public struct State: Equatable { - public enum Transaction: Equatable { - public enum WithdrawalStatus { - case succeed - case pending - case failed - } - case proceeds(amount: Int64, fromDate: Int32, toDate: Int32) - case withdrawal(status: WithdrawalStatus, amount: Int64, date: Int32, provider: String, transactionDate: Int32?, transactionUrl: String?) - case refund(amount: Int64, date: Int32, provider: String) - - public var amount: Int64 { - switch self { - case let .proceeds(amount, _, _), let .withdrawal(_, amount, _, _, _, _), let .refund(amount, _, _): - return amount - } - } - } - public var transactions: [Transaction] - public var isLoadingMore: Bool - public var hasLoadedOnce: Bool - public var canLoadMore: Bool - public var count: Int32 - - public static var Empty = State(transactions: [], isLoadingMore: false, hasLoadedOnce: true, canLoadMore: false, count: 0) - public static var Loading = State(transactions: [], isLoadingMore: false, hasLoadedOnce: false, canLoadMore: false, count: 0) - } - - - private let queue: Queue = Queue() - private let impl: QueueLocalObject - - public var state: Signal { - return Signal { subscriber in - let disposable = MetaDisposable() - self.impl.with { impl in - disposable.set(impl.state.get().start(next: { value in - subscriber.putNext(value) - })) - } - return disposable - } - } - - public init(account: Account, peerId: EnginePeer.Id) { - let queue = self.queue - self.impl = QueueLocalObject(queue: queue, generate: { - return RevenueStatsTransactionsContextImpl(queue: queue, account: account, peerId: peerId) - }) - } - - public func loadMore() { - self.impl.with { impl in - impl.loadMore() - } - } - - public func reload() { - self.impl.with { impl in - impl.reload() - } - } -} - -public enum RequestRevenueWithdrawalError : Equatable { - case generic - case twoStepAuthMissing - case twoStepAuthTooFresh(Int32) - case authSessionTooFresh(Int32) - case limitExceeded - case requestPassword - case invalidPassword -} - -func _internal_checkChannelRevenueWithdrawalAvailability(account: Account) -> Signal { - return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(peer: .inputPeerEmpty, password: .inputCheckPasswordEmpty)) - |> mapError { error -> RequestRevenueWithdrawalError in - if error.errorDescription == "PASSWORD_HASH_INVALID" { - return .requestPassword - } else if error.errorDescription == "PASSWORD_MISSING" { - return .twoStepAuthMissing - } else if error.errorDescription.hasPrefix("PASSWORD_TOO_FRESH_") { - let timeout = String(error.errorDescription[error.errorDescription.index(error.errorDescription.startIndex, offsetBy: "PASSWORD_TOO_FRESH_".count)...]) - if let value = Int32(timeout) { - return .twoStepAuthTooFresh(value) - } - } else if error.errorDescription.hasPrefix("SESSION_TOO_FRESH_") { - let timeout = String(error.errorDescription[error.errorDescription.index(error.errorDescription.startIndex, offsetBy: "SESSION_TOO_FRESH_".count)...]) - if let value = Int32(timeout) { - return .authSessionTooFresh(value) - } - } - return .generic - } - |> ignoreValues -} - -func _internal_requestChannelRevenueWithdrawalUrl(account: Account, peerId: PeerId, password: String) -> Signal { - guard !password.isEmpty else { - return .fail(.invalidPassword) - } - - return account.postbox.transaction { transaction -> Signal in - guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else { - return .fail(.generic) - } - - let checkPassword = _internal_twoStepAuthData(account.network) - |> mapError { error -> RequestRevenueWithdrawalError in - if error.errorDescription.hasPrefix("FLOOD_WAIT") { - return .limitExceeded - } else { - return .generic - } - } - |> mapToSignal { authData -> Signal in - if let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData { - guard let kdfResult = passwordKDF(encryptionProvider: account.network.encryptionProvider, password: password, derivation: currentPasswordDerivation, srpSessionData: srpSessionData) else { - return .fail(.generic) - } - return .single(.inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))) - } else { - return .fail(.twoStepAuthMissing) - } - } - - return checkPassword - |> mapToSignal { password -> Signal in - return account.network.request(Api.functions.stats.getBroadcastRevenueWithdrawalUrl(peer: inputPeer, password: password), automaticFloodWait: false) - |> mapError { error -> RequestRevenueWithdrawalError in - if error.errorDescription.hasPrefix("FLOOD_WAIT") { - return .limitExceeded - } else if error.errorDescription == "PASSWORD_HASH_INVALID" { - return .invalidPassword - } else if error.errorDescription == "PASSWORD_MISSING" { - return .twoStepAuthMissing - } else if error.errorDescription.hasPrefix("PASSWORD_TOO_FRESH_") { - let timeout = String(error.errorDescription[error.errorDescription.index(error.errorDescription.startIndex, offsetBy: "PASSWORD_TOO_FRESH_".count)...]) - if let value = Int32(timeout) { - return .twoStepAuthTooFresh(value) - } - } else if error.errorDescription.hasPrefix("SESSION_TOO_FRESH_") { - let timeout = String(error.errorDescription[error.errorDescription.index(error.errorDescription.startIndex, offsetBy: "SESSION_TOO_FRESH_".count)...]) - if let value = Int32(timeout) { - return .authSessionTooFresh(value) - } - } - return .generic - } - |> map { result -> String in - switch result { - case let .broadcastRevenueWithdrawalUrl(url): - return url - } - } - } - } - |> mapError { _ -> RequestRevenueWithdrawalError in } - |> switchToLatest -} diff --git a/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift b/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift index 5ef2303728..5bc1125d60 100644 --- a/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift +++ b/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift @@ -6,6 +6,7 @@ import MtProtoKit public struct StarsRevenueStats: Equatable, Codable { private enum CodingKeys: String, CodingKey { + case topHoursGraph case revenueGraph case balances case usdRate @@ -24,21 +25,22 @@ public struct StarsRevenueStats: Equatable, Codable { case overallRevenue case withdrawEnabled case nextWithdrawalTimestamp + case currentBalanceStars case availableBalanceStars case overallRevenueStars } - public let currentBalance: StarsAmount - public let availableBalance: StarsAmount - public let overallRevenue: StarsAmount + public let currentBalance: CurrencyAmount + public let availableBalance: CurrencyAmount + public let overallRevenue: CurrencyAmount public let withdrawEnabled: Bool public let nextWithdrawalTimestamp: Int32? public init( - currentBalance: StarsAmount, - availableBalance: StarsAmount, - overallRevenue: StarsAmount, + currentBalance: CurrencyAmount, + availableBalance: CurrencyAmount, + overallRevenue: CurrencyAmount, withdrawEnabled: Bool, nextWithdrawalTimestamp: Int32? ) { @@ -52,23 +54,22 @@ public struct StarsRevenueStats: Equatable, Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - if let legacyCurrentBalance = try container.decodeIfPresent(Int64.self, forKey: .currentBalance) { - self.currentBalance = StarsAmount(value: legacyCurrentBalance, nanos: 0) + if let legacyCurrentBalance = try container.decodeIfPresent(StarsAmount.self, forKey: .currentBalanceStars) { + self.currentBalance = CurrencyAmount(amount: legacyCurrentBalance, currency: .stars) } else { - self.currentBalance = try container.decode(StarsAmount.self, forKey: .currentBalanceStars) + self.currentBalance = try container.decode(CurrencyAmount.self, forKey: .currentBalance) } - if let legacyAvailableBalance = try container.decodeIfPresent(Int64.self, forKey: .availableBalance) { - self.availableBalance = StarsAmount(value: legacyAvailableBalance, nanos: 0) + if let legacyAvailableBalance = try container.decodeIfPresent(StarsAmount.self, forKey: .availableBalanceStars) { + self.availableBalance = CurrencyAmount(amount: legacyAvailableBalance, currency: .stars) } else { - self.availableBalance = try container.decode(StarsAmount.self, forKey: .availableBalanceStars) + self.availableBalance = try container.decode(CurrencyAmount.self, forKey: .availableBalance) } - - if let legacyOverallRevenue = try container.decodeIfPresent(Int64.self, forKey: .overallRevenue) { - self.overallRevenue = StarsAmount(value: legacyOverallRevenue, nanos: 0) + if let legacyOverallRevenue = try container.decodeIfPresent(StarsAmount.self, forKey: .overallRevenueStars) { + self.overallRevenue = CurrencyAmount(amount: legacyOverallRevenue, currency: .stars) } else { - self.overallRevenue = try container.decode(StarsAmount.self, forKey: .overallRevenueStars) + self.overallRevenue = try container.decode(CurrencyAmount.self, forKey: .overallRevenue) } self.withdrawEnabled = try container.decode(Bool.self, forKey: .withdrawEnabled) @@ -77,19 +78,21 @@ public struct StarsRevenueStats: Equatable, Codable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(self.currentBalance, forKey: .currentBalanceStars) - try container.encode(self.availableBalance, forKey: .availableBalanceStars) - try container.encode(self.overallRevenue, forKey: .overallRevenueStars) + try container.encode(self.currentBalance, forKey: .currentBalance) + try container.encode(self.availableBalance, forKey: .availableBalance) + try container.encode(self.overallRevenue, forKey: .overallRevenue) try container.encode(self.withdrawEnabled, forKey: .withdrawEnabled) try container.encodeIfPresent(self.nextWithdrawalTimestamp, forKey: .nextWithdrawalTimestamp) } } + public let topHoursGraph: StatsGraph? public let revenueGraph: StatsGraph public let balances: Balances public let usdRate: Double - init(revenueGraph: StatsGraph, balances: Balances, usdRate: Double) { + init(topHoursGraph: StatsGraph?, revenueGraph: StatsGraph, balances: Balances, usdRate: Double) { + self.topHoursGraph = topHoursGraph self.revenueGraph = revenueGraph self.balances = balances self.usdRate = usdRate @@ -97,6 +100,7 @@ public struct StarsRevenueStats: Equatable, Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + self.topHoursGraph = try container.decodeIfPresent(StatsGraph.self, forKey: .topHoursGraph) self.revenueGraph = try container.decode(StatsGraph.self, forKey: .revenueGraph) self.balances = try container.decode(Balances.self, forKey: .balances) self.usdRate = try container.decode(Double.self, forKey: .usdRate) @@ -104,12 +108,16 @@ public struct StarsRevenueStats: Equatable, Codable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(self.topHoursGraph, forKey: .topHoursGraph) try container.encode(self.revenueGraph, forKey: .revenueGraph) try container.encode(self.balances, forKey: .balances) try container.encode(self.usdRate, forKey: .usdRate) } public static func == (lhs: StarsRevenueStats, rhs: StarsRevenueStats) -> Bool { + if lhs.topHoursGraph != rhs.topHoursGraph { + return false + } if lhs.revenueGraph != rhs.revenueGraph { return false } @@ -126,6 +134,7 @@ public struct StarsRevenueStats: Equatable, Codable { public extension StarsRevenueStats { func withUpdated(balances: StarsRevenueStats.Balances) -> StarsRevenueStats { return StarsRevenueStats( + topHoursGraph: self.topHoursGraph, revenueGraph: self.revenueGraph, balances: balances, usdRate: self.usdRate @@ -136,8 +145,8 @@ public extension StarsRevenueStats { extension StarsRevenueStats { init(apiStarsRevenueStats: Api.payments.StarsRevenueStats, peerId: PeerId) { switch apiStarsRevenueStats { - case let .starsRevenueStats(revenueGraph, balances, usdRate): - self.init(revenueGraph: StatsGraph(apiStatsGraph: revenueGraph), balances: StarsRevenueStats.Balances(apiStarsRevenueStatus: balances), usdRate: usdRate) + case let .starsRevenueStats(_, topHoursGraph, revenueGraph, balances, usdRate): + self.init(topHoursGraph: topHoursGraph.flatMap { StatsGraph(apiStatsGraph: $0) }, revenueGraph: StatsGraph(apiStatsGraph: revenueGraph), balances: StarsRevenueStats.Balances(apiStarsRevenueStatus: balances), usdRate: usdRate) } } } @@ -146,7 +155,7 @@ extension StarsRevenueStats.Balances { init(apiStarsRevenueStatus: Api.StarsRevenueStatus) { switch apiStarsRevenueStatus { case let .starsRevenueStatus(flags, currentBalance, availableBalance, overallRevenue, nextWithdrawalAt): - self.init(currentBalance: StarsAmount(apiAmount: currentBalance), availableBalance: StarsAmount(apiAmount: availableBalance), overallRevenue: StarsAmount(apiAmount: overallRevenue), withdrawEnabled: ((flags & (1 << 0)) != 0), nextWithdrawalTimestamp: nextWithdrawalAt) + self.init(currentBalance: CurrencyAmount(apiAmount: currentBalance), availableBalance: CurrencyAmount(apiAmount: availableBalance), overallRevenue: CurrencyAmount(apiAmount: overallRevenue), withdrawEnabled: ((flags & (1 << 0)) != 0), nextWithdrawalTimestamp: nextWithdrawalAt) } } } @@ -155,7 +164,7 @@ public struct StarsRevenueStatsContextState: Equatable { public var stats: StarsRevenueStats? } -private func requestStarsRevenueStats(postbox: Postbox, network: Network, peerId: PeerId, dark: Bool = false) -> Signal { +private func requestStarsRevenueStats(postbox: Postbox, network: Network, peerId: PeerId, ton: Bool, dark: Bool = false) -> Signal { return postbox.transaction { transaction -> Peer? in if let peer = transaction.getPeer(peerId) { return peer @@ -167,9 +176,12 @@ private func requestStarsRevenueStats(postbox: Postbox, network: Network, peerId } var flags: Int32 = 0 - if dark { + if ton { flags |= (1 << 1) } + if dark { + flags |= (1 << 0) + } return network.request(Api.functions.payments.getStarsRevenueStats(flags: flags, peer: inputPeer)) |> retryRequestIfNotFrozen @@ -186,6 +198,7 @@ private func requestStarsRevenueStats(postbox: Postbox, network: Network, peerId private final class StarsRevenueStatsContextImpl { private let account: Account private let peerId: PeerId + private let ton: Bool private var _state: StarsRevenueStatsContextState { didSet { @@ -202,11 +215,12 @@ private final class StarsRevenueStatsContextImpl { private let disposable = MetaDisposable() private let updateDisposable = MetaDisposable() - init(account: Account, peerId: PeerId) { + init(account: Account, peerId: PeerId, ton: Bool) { assert(Queue.mainQueue().isCurrent()) self.account = account self.peerId = peerId + self.ton = ton self._state = StarsRevenueStatsContextState(stats: nil) self._statePromise.set(.single(self._state)) @@ -245,7 +259,7 @@ private final class StarsRevenueStatsContextImpl { let account = self.account let peerId = self.peerId - let signal = requestStarsRevenueStats(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId) + let signal = requestStarsRevenueStats(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId, ton: self.ton) |> mapToSignal { initial -> Signal in guard let initial else { return .single(nil) @@ -303,9 +317,9 @@ public final class StarsRevenueStatsContext { } } - public init(account: Account, peerId: PeerId) { + public init(account: Account, peerId: PeerId, ton: Bool) { self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: { - return StarsRevenueStatsContextImpl(account: account, peerId: peerId) + return StarsRevenueStatsContextImpl(account: account, peerId: peerId, ton: ton) }) } @@ -347,7 +361,7 @@ public enum RequestStarsRevenueWithdrawalError : Equatable { } func _internal_checkStarsRevenueWithdrawalAvailability(account: Account) -> Signal { - return account.network.request(Api.functions.payments.getStarsRevenueWithdrawalUrl(peer: .inputPeerEmpty, stars: 0, password: .inputCheckPasswordEmpty)) + return account.network.request(Api.functions.payments.getStarsRevenueWithdrawalUrl(flags: 0, peer: .inputPeerEmpty, amount: nil, password: .inputCheckPasswordEmpty)) |> mapError { error -> RequestStarsRevenueWithdrawalError in if error.errorDescription == "PASSWORD_HASH_INVALID" { return .requestPassword @@ -369,7 +383,7 @@ func _internal_checkStarsRevenueWithdrawalAvailability(account: Account) -> Sign |> ignoreValues } -func _internal_requestStarsRevenueWithdrawalUrl(account: Account, peerId: PeerId, amount: Int64, password: String) -> Signal { +func _internal_requestStarsRevenueWithdrawalUrl(account: Account, ton: Bool, peerId: PeerId, amount: Int64?, password: String) -> Signal { guard !password.isEmpty else { return .fail(.invalidPassword) } @@ -400,7 +414,13 @@ func _internal_requestStarsRevenueWithdrawalUrl(account: Account, peerId: PeerId return checkPassword |> mapToSignal { password -> Signal in - return account.network.request(Api.functions.payments.getStarsRevenueWithdrawalUrl(peer: inputPeer, stars: amount, password: password), automaticFloodWait: false) + var flags: Int32 = 0 + if ton { + flags |= 1 << 0 + } else { + flags |= 1 << 1 + } + return account.network.request(Api.functions.payments.getStarsRevenueWithdrawalUrl(flags: flags, peer: inputPeer, amount: amount, password: password), automaticFloodWait: false) |> mapError { error -> RequestStarsRevenueWithdrawalError in if error.errorCode == 406 { return .serverProvided(text: error.errorDescription) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift index 2321c6c6dd..6d38eb8972 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/PeersData.swift @@ -2405,6 +2405,62 @@ public extension TelegramEngine.EngineData.Item { } } + public struct BotGroupAdminRights: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public typealias Result = Optional + + fileprivate var id: EnginePeer.Id + public var mapKey: EnginePeer.Id { + return self.id + } + + public init(id: EnginePeer.Id) { + self.id = id + } + + var key: PostboxViewKey { + return .cachedPeerData(peerId: self.id) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? CachedPeerDataView else { + preconditionFailure() + } + if let cachedData = view.cachedPeerData as? CachedUserData { + return cachedData.botGroupAdminRights + } else { + return nil + } + } + } + + public struct BotChannelAdminRights: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem { + public typealias Result = Optional + + fileprivate var id: EnginePeer.Id + public var mapKey: EnginePeer.Id { + return self.id + } + + public init(id: EnginePeer.Id) { + self.id = id + } + + var key: PostboxViewKey { + return .cachedPeerData(peerId: self.id) + } + + func extract(view: PostboxView) -> Result { + guard let view = view as? CachedPeerDataView else { + preconditionFailure() + } + if let cachedData = view.cachedPeerData as? CachedUserData { + return cachedData.botChannelAdminRights + } else { + return nil + } + } + } + public struct StarsReactionDefaultPrivacy: TelegramEngineDataItem, PostboxViewDataItem { public typealias Result = TelegramPaidReactionPrivacy diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift index 7b947a4e7d..1d118f3cdb 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift @@ -462,7 +462,7 @@ private func _internal_requestStarsState(account: Account, peerId: EnginePeer.Id |> mapToSignal { result -> Signal in return account.postbox.transaction { transaction -> InternalStarsStatus in switch result { - case let .starsStatus(flags: _, balance, _, _, subscriptionsMissingBalance, transactions, nextTransactionsOffset, chats, users): + case let .starsStatus(_, balance, _, _, subscriptionsMissingBalance, transactions, nextTransactionsOffset, chats, users): let peers = AccumulatedPeers(chats: chats, users: users) updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers) @@ -570,9 +570,9 @@ private final class StarsContextImpl { self.load(force: true) - self.updateDisposable = (account.stateManager.updatedStarsBalance() + self.updateDisposable = ((ton ? account.stateManager.updatedTonBalance() : account.stateManager.updatedStarsBalance()) |> deliverOnMainQueue).startStrict(next: { [weak self] balances in - guard let self, let state = self._state, let balance = balances[peerId] else { + guard let self, let state = self._state, let balance = balances[self.peerId] else { return } self.updateState(StarsContext.State(flags: [], balance: balance, subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: state.transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: false)) @@ -619,7 +619,7 @@ private final class StarsContextImpl { var transactions = state.transactions if addTransaction { let count = CurrencyAmount(amount: balance, currency: self.ton ? .ton : .stars) - transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: count, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil, floodskipNumber: nil, starrefCommissionPermille: nil, starrefPeerId: nil, starrefAmount: nil, paidMessageCount: nil, premiumGiftMonths: nil), at: 0) + transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: count, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil, floodskipNumber: nil, starrefCommissionPermille: nil, starrefPeerId: nil, starrefAmount: nil, paidMessageCount: nil, premiumGiftMonths: nil, adsProceedsFromDate: nil, adsProceedsToDate: nil), at: 0) } self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: max(StarsAmount(value: 0, nanos: 0), state.balance + balance), subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading)) } @@ -655,7 +655,7 @@ private final class StarsContextImpl { private extension StarsContext.State.Transaction { init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) { switch apiTransaction { - case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod, giveawayPostId, starGift, floodskipNumber, starrefCommissionPermille, starrefPeer, starrefAmount, paidMessageCount, premiumGiftMonths): + case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod, giveawayPostId, starGift, floodskipNumber, starrefCommissionPermille, starrefPeer, starrefAmount, paidMessageCount, premiumGiftMonths, adsProceedsFromDate, adsProceedsToDate): let parsedPeer: StarsContext.State.Transaction.Peer var paidMessageId: MessageId? var giveawayMessageId: MessageId? @@ -724,7 +724,7 @@ private extension StarsContext.State.Transaction { let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? [] let _ = subscriptionPeriod - self.init(flags: flags, id: id, count: CurrencyAmount(apiAmount: stars), date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) }, floodskipNumber: floodskipNumber, starrefCommissionPermille: starrefCommissionPermille, starrefPeerId: starrefPeer?.peerId, starrefAmount: starrefAmount.flatMap(StarsAmount.init(apiAmount:)), paidMessageCount: paidMessageCount, premiumGiftMonths: premiumGiftMonths) + self.init(flags: flags, id: id, count: CurrencyAmount(apiAmount: stars), date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) }, floodskipNumber: floodskipNumber, starrefCommissionPermille: starrefCommissionPermille, starrefPeerId: starrefPeer?.peerId, starrefAmount: starrefAmount.flatMap(StarsAmount.init(apiAmount:)), paidMessageCount: paidMessageCount, premiumGiftMonths: premiumGiftMonths, adsProceedsFromDate: adsProceedsFromDate, adsProceedsToDate: adsProceedsToDate) } } } @@ -808,6 +808,8 @@ public final class StarsContext { public let starrefAmount: StarsAmount? public let paidMessageCount: Int32? public let premiumGiftMonths: Int32? + public let adsProceedsFromDate: Int32? + public let adsProceedsToDate: Int32? public init( flags: Flags, @@ -830,7 +832,9 @@ public final class StarsContext { starrefPeerId: PeerId?, starrefAmount: StarsAmount?, paidMessageCount: Int32?, - premiumGiftMonths: Int32? + premiumGiftMonths: Int32?, + adsProceedsFromDate: Int32?, + adsProceedsToDate: Int32? ) { self.flags = flags self.id = id @@ -853,6 +857,8 @@ public final class StarsContext { self.starrefAmount = starrefAmount self.paidMessageCount = paidMessageCount self.premiumGiftMonths = premiumGiftMonths + self.adsProceedsFromDate = adsProceedsFromDate + self.adsProceedsToDate = adsProceedsToDate } public static func == (lhs: Transaction, rhs: Transaction) -> Bool { @@ -919,6 +925,12 @@ public final class StarsContext { if lhs.premiumGiftMonths != rhs.premiumGiftMonths { return false } + if lhs.adsProceedsFromDate != rhs.adsProceedsFromDate { + return false + } + if lhs.adsProceedsToDate != rhs.adsProceedsToDate { + return false + } return true } } @@ -1663,23 +1675,27 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot public struct StarsTransactionReference: PostboxCoding, Hashable, Equatable { public let peerId: EnginePeer.Id + public let ton: Bool public let id: String public let isRefund: Bool - public init(peerId: EnginePeer.Id, id: String, isRefund: Bool) { + public init(peerId: EnginePeer.Id, ton: Bool, id: String, isRefund: Bool) { self.peerId = peerId + self.ton = ton self.id = id self.isRefund = isRefund } public init(decoder: PostboxDecoder) { self.peerId = EnginePeer.Id(decoder.decodeInt64ForKey("peerId", orElse: 0)) + self.ton = decoder.decodeBoolForKey("ton", orElse: false) self.id = decoder.decodeStringForKey("id", orElse: "") self.isRefund = decoder.decodeBoolForKey("refund", orElse: false) } public func encode(_ encoder: PostboxEncoder) { encoder.encodeInt64(self.peerId.toInt64(), forKey: "peerId") + encoder.encodeBool(self.ton, forKey: "ton") encoder.encodeString(self.id, forKey: "id") encoder.encodeBool(self.isRefund, forKey: "refund") } @@ -1695,6 +1711,7 @@ func _internal_getStarsTransaction(accountPeerId: PeerId, postbox: Postbox, netw } return network.request( Api.functions.payments.getStarsTransactionsByID( + flags: transactionReference.ton ? 1 << 0 : 0, peer: inputPeer, id: [.inputStarsTransaction(flags: transactionReference.isRefund ? (1 << 0) : 0, id: transactionReference.id)] ) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift index cb887658a1..262cd8a681 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift @@ -86,8 +86,8 @@ public extension TelegramEngine { return StarsContext(account: self.account, ton: true) } - public func peerStarsRevenueContext(peerId: EnginePeer.Id) -> StarsRevenueStatsContext { - return StarsRevenueStatsContext(account: self.account, peerId: peerId) + public func peerStarsRevenueContext(peerId: EnginePeer.Id, ton: Bool) -> StarsRevenueStatsContext { + return StarsRevenueStatsContext(account: self.account, peerId: peerId, ton: ton) } public func peerStarsTransactionsContext(subject: StarsTransactionsContext.Subject, mode: StarsTransactionsContext.Mode) -> StarsTransactionsContext { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 0c04c5439d..466ec24a13 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -889,21 +889,13 @@ public extension TelegramEngine { public func updatePeerStarGiftStatus(peerId: EnginePeer.Id, starGift: StarGift.UniqueGift, expirationDate: Int32?) -> Signal { return _internal_updatePeerStarGiftStatus(account: self.account, peerId: peerId, starGift: starGift, expirationDate: expirationDate) } - - public func checkChannelRevenueWithdrawalAvailability() -> Signal { - return _internal_checkChannelRevenueWithdrawalAvailability(account: self.account) - } - - public func requestChannelRevenueWithdrawalUrl(peerId: EnginePeer.Id, password: String) -> Signal { - return _internal_requestChannelRevenueWithdrawalUrl(account: self.account, peerId: peerId, password: password) - } - + public func checkStarsRevenueWithdrawalAvailability() -> Signal { return _internal_checkStarsRevenueWithdrawalAvailability(account: self.account) } - public func requestStarsRevenueWithdrawalUrl(peerId: EnginePeer.Id, amount: Int64, password: String) -> Signal { - return _internal_requestStarsRevenueWithdrawalUrl(account: self.account, peerId: peerId, amount: amount, password: password) + public func requestStarsRevenueWithdrawalUrl(peerId: EnginePeer.Id, ton: Bool, amount: Int64?, password: String) -> Signal { + return _internal_requestStarsRevenueWithdrawalUrl(account: self.account, ton: ton, peerId: peerId, amount: amount, password: password) } public func requestStarsRevenueAdsAccountlUrl(peerId: EnginePeer.Id) -> Signal { diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index 49b197b86f..fd1a7213c5 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -173,6 +173,10 @@ public enum PresentationResourceKey: Int32 { case chatBubbleTodoCheckIncomingIcon case chatBubbleTodoCheckOutgoingIcon + case chatServiceMessageTodoCompletedIcon + case chatServiceMessageTodoIncompletedIcon + case chatServiceMessageTodoAppendedIcon + case chatBubbleReplyThumbnailPlayImage case chatBubbleDeliveryFailedIcon diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift index 65f4204d5c..f61320c87b 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift @@ -1433,6 +1433,24 @@ public struct PresentationResourcesChat { }) } + public static func chatServiceMessageTodoCompletedIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.chatServiceMessageTodoCompletedIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/ServiceTodoCompleted"), color: .white) + }) + } + + public static func chatServiceMessageTodoIncompletedIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.chatServiceMessageTodoIncompletedIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/ServiceTodoIncompleted"), color: .white) + }) + } + + public static func chatServiceMessageTodoAppendedIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.chatServiceMessageTodoAppendedIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/ServiceTodoIncompleted"), color: .white) + }) + } + public static func messageButtonsPostReject(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.messageButtonsPostReject.rawValue, { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/SuggestPostDecline"), color: .white) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift index c6673ec321..3eecc1b6f1 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift @@ -200,8 +200,10 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { let attributedString = attributedServiceMessageString(theme: item.presentationData.theme, strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, dateTimeFormat: item.presentationData.dateTimeFormat, message: item.message, messageCount: messageCount, accountPeerId: item.context.account.peerId, forForumOverview: forForumOverview) var image: TelegramMediaImage? - var story: TelegramMediaStory? var suggestedPost: TelegramMediaActionType.SuggestedPostApprovalStatus? + + var leadingIcon: UIImage? + var isStory = false for media in item.message.media { if let action = media as? TelegramMediaAction { switch action.action { @@ -209,20 +211,29 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { image = img case let .suggestedPostApprovalStatus(status): suggestedPost = status + case let .todoCompletions(completed, _): + if !completed.isEmpty { + leadingIcon = PresentationResourcesChat.chatServiceMessageTodoCompletedIcon(item.presentationData.theme.theme) + } else { + leadingIcon = PresentationResourcesChat.chatServiceMessageTodoIncompletedIcon(item.presentationData.theme.theme) + } + case .todoAppendTasks: + leadingIcon = PresentationResourcesChat.chatServiceMessageTodoAppendedIcon(item.presentationData.theme.theme) default: break } - } else if let media = media as? TelegramMediaStory { - story = media + } else if media is TelegramMediaStory { + leadingIcon = PresentationResourcesChat.chatExpiredStoryIndicatorIcon(item.presentationData.theme.theme, type: .free) + isStory = true } } let imageSize = CGSize(width: 212.0, height: 212.0) var updatedAttributedString = attributedString - if story != nil, let attributedString { + if leadingIcon != nil, let attributedString { let mutableString = NSMutableAttributedString(attributedString: attributedString) - mutableString.insert(NSAttributedString(string: " ", font: Font.regular(13.0), textColor: .clear), at: 0) + mutableString.insert(NSAttributedString(string: isStory ? " " : " ", font: Font.regular(13.0), textColor: .clear), at: 0) updatedAttributedString = mutableString } @@ -426,8 +437,8 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { } } for i in 0 ..< labelRects.count { - labelRects[i] = labelRects[i].insetBy(dx: -6.0, dy: floor((labelRects[i].height - 20.0) / 2.0)) - labelRects[i].size.height = 20.0 + labelRects[i] = labelRects[i].insetBy(dx: -6.0, dy: floor((labelRects[i].height - 22.0) / 2.0)) + labelRects[i].size.height = 22.0 labelRects[i].origin.x = floor((labelLayout.size.width - labelRects[i].width) / 2.0) } @@ -677,7 +688,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { } } - if story != nil { + if let leadingIcon { let leadingIconView: UIImageView if let current = strongSelf.leadingIconView { leadingIconView = current @@ -687,11 +698,15 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { strongSelf.view.addSubview(leadingIconView) } - leadingIconView.image = PresentationResourcesChat.chatExpiredStoryIndicatorIcon(item.presentationData.theme.theme, type: .free) + leadingIconView.image = leadingIcon if let lineRect = labelLayout.linesRects().first, let iconImage = leadingIconView.image { let iconSize = iconImage.size - leadingIconView.frame = CGRect(origin: CGPoint(x: lineRect.minX + labelFrame.minX - 1.0, y: labelFrame.minY), size: iconSize) + var iconFrame = CGRect(origin: CGPoint(x: lineRect.minX + labelFrame.minX - 1.0, y: labelFrame.minY), size: iconSize) + if !isStory { + iconFrame.origin.x += 3.0 + } + leadingIconView.frame = iconFrame } } else if let leadingIconView = strongSelf.leadingIconView { strongSelf.leadingIconView = nil diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift index 8fe7861387..44bf777edc 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift @@ -418,6 +418,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { title = item.presentationData.strings.Notification_StarsGift_Title(Int32(count)) text = incoming ? item.presentationData.strings.Notification_StarsGift_Subtitle : item.presentationData.strings.Notification_StarsGift_SubtitleYou(peerName).string case let .giftTon(currency, amount, cryptoCurrency, cryptoAmount, _): + months = 1000 + var peerName = "" if let peer = item.message.peers[item.message.id.peerId] { peerName = EnginePeer(peer).compactDisplayTitle @@ -431,6 +433,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { title = "$ \(formatTonAmountText(cryptoAmount, dateTimeFormat: item.presentationData.dateTimeFormat))" text = incoming ? "Use TON to submit post suggestions to channels." : "With TON, \(peerName) will be able to submit post suggestions to channels." + buttonTitle = "" case let .prizeStars(count, _, channelId, _, _): if count <= 1000 { months = 3 @@ -640,6 +643,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { } switch months { + case 1000: + animationName = "GiftDiamond" case 12: animationName = "Gift12" case 6: diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift index 8ca3596d8b..3cd40d5a24 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift @@ -375,7 +375,10 @@ private func generatePercentageAnimationImages(presentationData: ChatPresentatio private final class ChatMessageTodoItemNode: ASDisplayNode { private var backgroundWallpaperNode: ChatMessageBubbleBackdrop? private var backgroundNode: ChatMessageBackground? - private var snapshotView: UIView? + private var extractedRadioView: UIView? + private var extractedAvatarView: UIView? + private var extractedTitleNode: TextNodeWithEntities? + private var extractedNameView: UIView? fileprivate let contextSourceNode: ContextExtractedContentContainingNode fileprivate let containerNode: ASDisplayNode @@ -385,6 +388,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { private var iconNode: ASImageNode? fileprivate var titleNode: TextNodeWithEntities? fileprivate var nameNode: TextNode? + private let buttonNode: HighlightTrackingButtonNode let separatorNode: ASDisplayNode @@ -545,16 +549,48 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { // self.backgroundWallpaperNode?.update(rect: mappedRect, within: containerSize) // } - if let snapshotView = self.containerNode.view.snapshotContentTree() { - self.snapshotView = snapshotView - self.contextSourceNode.contentNode.view.addSubview(snapshotView) + if let extractedRadioView = self.radioNode?.view.snapshotContentTree() { + self.extractedRadioView = extractedRadioView + self.contextSourceNode.contentNode.view.addSubview(extractedRadioView) + } + + if let extractedAvatarView = self.avatarNode?.view.snapshotContentTree() { + self.extractedAvatarView = extractedAvatarView + self.contextSourceNode.contentNode.view.addSubview(extractedAvatarView) + } + + if let titleNode = self.titleNode, let context = self.context, let presentationData = self.presentationData { + let titleConstrainedWidth = titleNode.textNode.cachedLayout?.size.width ?? 1.0 + let makeTitleLayout = TextNodeWithEntities.asyncLayout(self.extractedTitleNode) + let (_, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: self.titleNode?.textNode.cachedLayout?.attributedString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: titleConstrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .left, cutout: nil, insets: UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0))) + let extractedTitleNode = titleApply(TextNodeWithEntities.Arguments( + context: context, + cache: context.animationCache, + renderer: context.animationRenderer, + placeholderColor: incoming ? presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor, + attemptSynchronous: true + )) + extractedTitleNode.textNode.frame = titleNode.textNode.frame + self.contextSourceNode.contentNode.addSubnode(extractedTitleNode.textNode) + self.extractedTitleNode = extractedTitleNode + } + + if let extractedNameView = self.nameNode?.view.snapshotContentTree() { + self.extractedNameView = extractedNameView + self.contextSourceNode.contentNode.view.addSubview(extractedNameView) } } else { if let backgroundNode = self.backgroundNode { self.backgroundNode = nil transition.updateAlpha(node: backgroundNode, alpha: 0.0, completion: { [weak backgroundNode] _ in - self.snapshotView?.removeFromSuperview() - self.snapshotView = nil + self.extractedRadioView?.removeFromSuperview() + self.extractedRadioView = nil + self.extractedAvatarView?.removeFromSuperview() + self.extractedAvatarView = nil + self.extractedTitleNode?.textNode.removeFromSupernode() + self.extractedTitleNode = nil + self.extractedNameView?.removeFromSuperview() + self.extractedNameView = nil backgroundNode?.removeFromSupernode() }) @@ -596,7 +632,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { return { context, presentationData, presentationContext, message, todo, option, completion, translation, constrainedWidth in var canMark = false if (todo.flags.contains(.othersCanComplete) || message.author?.id == context.account.peerId) { - if let forwardInfo = message.forwardInfo, let authorId = forwardInfo.author?.id, authorId != context.account.peerId { + if let _ = message.forwardInfo { } else { canMark = true } @@ -725,9 +761,9 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { if let (nameLayout, nameApply) = nameLayoutAndApply { var nameNodeFrame: CGRect if titleLayout.hasRTL { - nameNodeFrame = CGRect(origin: CGPoint(x: width - rightInset - nameLayout.size.width, y: 26.0), size: nameLayout.size) + nameNodeFrame = CGRect(origin: CGPoint(x: width - rightInset - nameLayout.size.width, y: titleNodeFrame.maxY - 4.0), size: nameLayout.size) } else { - nameNodeFrame = CGRect(origin: CGPoint(x: leftInset, y: 26.0), size: nameLayout.size) + nameNodeFrame = CGRect(origin: CGPoint(x: leftInset, y: titleNodeFrame.maxY - 4.0), size: nameLayout.size) } let nameNode = nameApply() if node.nameNode !== nameNode { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoData.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoData.swift index fe4168a2ef..d8774b4f45 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoData.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoData.swift @@ -385,8 +385,8 @@ final class PeerInfoScreenData { let tonState: StarsContext.State? let starsRevenueStatsState: StarsRevenueStats? let starsRevenueStatsContext: StarsRevenueStatsContext? - let revenueStatsState: RevenueStats? - let revenueStatsContext: RevenueStatsContext? + let revenueStatsState: StarsRevenueStats? + let revenueStatsContext: StarsRevenueStatsContext? let profileGiftsContext: ProfileGiftsContext? let premiumGiftOptions: [PremiumGiftCodeOption] let webAppPermissions: WebAppPermissionsState? @@ -437,8 +437,8 @@ final class PeerInfoScreenData { tonState: StarsContext.State?, starsRevenueStatsState: StarsRevenueStats?, starsRevenueStatsContext: StarsRevenueStatsContext?, - revenueStatsState: RevenueStats?, - revenueStatsContext: RevenueStatsContext?, + revenueStatsState: StarsRevenueStats?, + revenueStatsContext: StarsRevenueStatsContext?, profileGiftsContext: ProfileGiftsContext?, premiumGiftOptions: [PremiumGiftCodeOption], webAppPermissions: WebAppPermissionsState? @@ -1300,7 +1300,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen guard canViewStarsRevenue else { return .single((nil, nil)) } - let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId) + let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId, ton: false) return starsRevenueStatsContext.state |> map { state -> (StarsRevenueStatsContext?, StarsRevenueStats?) in return (starsRevenueStatsContext, state.stats) @@ -1313,7 +1313,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.CanViewRevenue(id: peerId)) |> distinctUntilChanged ) - |> mapToSignal { peer, canViewRevenue -> Signal<(RevenueStatsContext?, RevenueStats?), NoError> in + |> mapToSignal { peer, canViewRevenue -> Signal<(StarsRevenueStatsContext?, StarsRevenueStats?), NoError> in var canViewRevenue = canViewRevenue if let peer, case let .user(user) = peer, let _ = user.botInfo, context.sharedContext.applicationBindings.appBuildType == .internal || context.sharedContext.immediateExperimentalUISettings.devRequests { canViewRevenue = true @@ -1324,9 +1324,9 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen guard canViewRevenue else { return .single((nil, nil)) } - let revenueStatsContext = RevenueStatsContext(account: context.account, peerId: peerId) + let revenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId, ton: true) return revenueStatsContext.state - |> map { state -> (RevenueStatsContext?, RevenueStats?) in + |> map { state -> (StarsRevenueStatsContext?, StarsRevenueStats?) in return (revenueStatsContext, state.stats) } } @@ -1572,7 +1572,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen guard canViewStarsRevenue else { return .single((nil, nil)) } - let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId) + let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId, ton: false) return starsRevenueStatsContext.state |> map { state -> (StarsRevenueStatsContext?, StarsRevenueStats?) in return (starsRevenueStatsContext, state.stats) @@ -1583,13 +1583,13 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen TelegramEngine.EngineData.Item.Peer.CanViewRevenue(id: peerId) ) |> distinctUntilChanged - |> mapToSignal { canViewRevenue -> Signal<(RevenueStatsContext?, RevenueStats?), NoError> in + |> mapToSignal { canViewRevenue -> Signal<(StarsRevenueStatsContext?, StarsRevenueStats?), NoError> in guard canViewRevenue else { return .single((nil, nil)) } - let revenueStatsContext = RevenueStatsContext(account: context.account, peerId: peerId) + let revenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId, ton: true) return revenueStatsContext.state - |> map { state -> (RevenueStatsContext?, RevenueStats?) in + |> map { state -> (StarsRevenueStatsContext?, StarsRevenueStats?) in return (revenueStatsContext, state.stats) } } @@ -1911,7 +1911,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen guard canViewStarsRevenue else { return .single((nil, nil)) } - let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId) + let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: peerId, ton: false) return starsRevenueStatsContext.state |> map { state -> (StarsRevenueStatsContext?, StarsRevenueStats?) in return (starsRevenueStatsContext, state.stats) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 0ade9c5412..51bfcc130d 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -1597,11 +1597,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese })) } - let revenueBalance = data.revenueStatsState?.balances.currentBalance ?? 0 - let overallRevenueBalance = data.revenueStatsState?.balances.overallRevenue ?? 0 + let revenueBalance = data.revenueStatsState?.balances.currentBalance.amount.value ?? 0 + let overallRevenueBalance = data.revenueStatsState?.balances.overallRevenue.amount.value ?? 0 - let starsBalance = data.starsRevenueStatsState?.balances.currentBalance ?? StarsAmount.zero - let overallStarsBalance = data.starsRevenueStatsState?.balances.overallRevenue ?? StarsAmount.zero + let starsBalance = data.starsRevenueStatsState?.balances.currentBalance.amount ?? StarsAmount.zero + let overallStarsBalance = data.starsRevenueStatsState?.balances.overallRevenue.amount ?? StarsAmount.zero if overallRevenueBalance > 0 || overallStarsBalance > StarsAmount.zero { items[.balances]!.append(PeerInfoScreenHeaderItem(id: 20, text: presentationData.strings.PeerInfo_BotBalance_Title)) @@ -1907,11 +1907,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese section = .peerMembers } if cachedData.flags.contains(.canViewRevenue) || cachedData.flags.contains(.canViewStarsRevenue) { - let revenueBalance = data.revenueStatsState?.balances.currentBalance ?? 0 - let starsBalance = data.starsRevenueStatsState?.balances.currentBalance ?? StarsAmount.zero + let revenueBalance = data.revenueStatsState?.balances.currentBalance.amount.value ?? 0 + let starsBalance = data.starsRevenueStatsState?.balances.currentBalance.amount ?? StarsAmount.zero - let overallRevenueBalance = data.revenueStatsState?.balances.overallRevenue ?? 0 - let overallStarsBalance = data.starsRevenueStatsState?.balances.overallRevenue ?? StarsAmount.zero + let overallRevenueBalance = data.revenueStatsState?.balances.overallRevenue.amount.value ?? 0 + let overallStarsBalance = data.starsRevenueStatsState?.balances.overallRevenue.amount ?? StarsAmount.zero if overallRevenueBalance > 0 || overallStarsBalance > StarsAmount.zero { let smallLabelFont = Font.regular(floor(presentationData.listsFontSize.itemListBaseFontSize / 17.0 * 13.0)) diff --git a/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/BUILD b/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/BUILD index 567ee0e5c9..540c6c2ba6 100644 --- a/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/BUILD +++ b/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/BUILD @@ -62,6 +62,7 @@ swift_library( "//submodules/AppBundle", "//submodules/GZip", "//submodules/LegacyComponents", + "//submodules/TelegramPresentationData", "//submodules/Components/MultilineTextComponent:MultilineTextComponent", "//submodules/TelegramUI/Components/Premium/PremiumStarComponent", "//submodules/TelegramUI/Components/Utils/AnimatableProperty", diff --git a/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/Sources/PremiumDiamondComponent.swift b/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/Sources/PremiumDiamondComponent.swift index 3a62fc5987..ffa39db961 100644 --- a/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/Sources/PremiumDiamondComponent.swift +++ b/submodules/TelegramUI/Components/Premium/PremiumDiamondComponent/Sources/PremiumDiamondComponent.swift @@ -8,6 +8,7 @@ import GZip import AppBundle import LegacyComponents import PremiumStarComponent +import TelegramPresentationData private let sceneVersion: Int = 5 @@ -20,11 +21,14 @@ private func rad2deg(_ number: Float) -> Float { } public final class PremiumDiamondComponent: Component { - public init() { + let theme: PresentationTheme + + public init(theme: PresentationTheme) { + self.theme = theme } public static func ==(lhs: PremiumDiamondComponent, rhs: PremiumDiamondComponent) -> Bool { - return true + return lhs.theme === rhs.theme } public final class View: UIView, SCNSceneRendererDelegate, ComponentTaggedView { @@ -88,14 +92,47 @@ public final class PremiumDiamondComponent: Component { } private func setup() { - guard let scene = loadCompressedScene(name: "diamond", version: sceneVersion) else { + guard let scene = loadCompressedScene(name: "gift2", version: sceneVersion) else { return } self.sceneView.scene = scene self.sceneView.delegate = self - let _ = self.sceneView.snapshot() + let names: [String] = [ + "particles_left", + "particles_right", + "particles_left_bottom", + "particles_right_bottom", + "particles_center" + ] + + let particleColor = UIColor(rgb: 0x428df4) //0x3b9bff) + for name in names { + if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first { + particleSystem.particleIntensity = min(1.0, 2.0 * particleSystem.particleIntensity) + particleSystem.particleIntensityVariation = 0.05 + particleSystem.particleColor = particleColor + particleSystem.particleColorVariation = SCNVector4Make(0.0, 0.0, 0.1, 0.0) + + if let propertyControllers = particleSystem.propertyControllers, let sizeController = propertyControllers[.size], let colorController = propertyControllers[.color] { + let animation = CAKeyframeAnimation() + if let existing = colorController.animation as? CAKeyframeAnimation { + animation.keyTimes = existing.keyTimes + animation.values = existing.values?.compactMap { ($0 as? UIColor)?.alpha } ?? [] + } else { + animation.values = [ 0.0, 1.0, 1.0, 0.0 ] + } + let opacityController = SCNParticlePropertyController(animation: animation) + particleSystem.propertyControllers = [ + .size: sizeController, + .opacity: opacityController + ] + } + } + } + + //let _ = self.sceneView.snapshot() } private var didSetReady = false @@ -214,6 +251,8 @@ public final class PremiumDiamondComponent: Component { func update(component: PremiumDiamondComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize { self.component = component + self.sceneView.backgroundColor = component.theme.list.blocksBackgroundColor + self.sceneView.bounds = CGRect(origin: .zero, size: CGSize(width: availableSize.width * 2.0, height: availableSize.height * 2.0)) self.sceneView.center = CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0) diff --git a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/GiftAvatarComponent.swift b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/GiftAvatarComponent.swift index ca67a9589a..d0a78d1da8 100644 --- a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/GiftAvatarComponent.swift +++ b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/GiftAvatarComponent.swift @@ -158,22 +158,7 @@ public final class GiftAvatarComponent: Component { self.sceneView.scene = scene self.sceneView.delegate = self - if let color = self.component?.color { -// let names: [String] = [ -// "particles_left", -// "particles_right", -// "particles_left_bottom", -// "particles_right_bottom", -// "particles_center" -// ] -// -// for name in names { -// if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first { -// particleSystem.particleColor = color -// particleSystem.particleColorVariation = SCNVector4Make(0, 0, 0, 0) -// } -// } - + if let color = self.component?.color { let names: [String] = [ "particles_left", "particles_right", diff --git a/submodules/TelegramUI/Components/Settings/LanguageSelectionScreen/Sources/LanguageSelectionScreenNode.swift b/submodules/TelegramUI/Components/Settings/LanguageSelectionScreen/Sources/LanguageSelectionScreenNode.swift index cd14148e2e..5cf8f19747 100644 --- a/submodules/TelegramUI/Components/Settings/LanguageSelectionScreen/Sources/LanguageSelectionScreenNode.swift +++ b/submodules/TelegramUI/Components/Settings/LanguageSelectionScreen/Sources/LanguageSelectionScreenNode.swift @@ -347,7 +347,7 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode { let openSearch: () -> Void = { requestActivateSearch() } - + let previousState = Atomic(value: nil) let previousEntriesHolder = Atomic<([LanguageListEntry], PresentationTheme, PresentationStrings)?>(value: nil) self.listDisposable = combineLatest( @@ -360,7 +360,7 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - + var entries: [LanguageListEntry] = [] var existingIds = Set() diff --git a/submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent/Sources/StarsBalanceOverlayComponent.swift b/submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent/Sources/StarsBalanceOverlayComponent.swift index 197912cf55..4eb482d0a8 100644 --- a/submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent/Sources/StarsBalanceOverlayComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent/Sources/StarsBalanceOverlayComponent.swift @@ -103,12 +103,12 @@ public final class StarsBalanceOverlayComponent: Component { }) } } else { - let starsRevenueStatsContext = StarsRevenueStatsContext(account: component.context.account, peerId: component.peerId) + let starsRevenueStatsContext = StarsRevenueStatsContext(account: component.context.account, peerId: component.peerId, ton: false) self.starsRevenueStatsContext = starsRevenueStatsContext self.balanceDisposable = (starsRevenueStatsContext.state |> map { state -> Int64 in - return state.stats?.balances.currentBalance.value ?? 0 + return state.stats?.balances.currentBalance.amount.value ?? 0 } |> distinctUntilChanged |> deliverOnMainQueue).start(next: { [weak self] balance in diff --git a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift index 36380871b8..01e9437a83 100644 --- a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift @@ -851,7 +851,7 @@ public final class StarsImageComponent: Component { if let current = self.animationNode { animationNode = current } else { - let stickerName: String = "Gift\(count)" + let stickerName: String = count == 1000 ? "GiftDiamond" : "Gift\(count)" animationNode = DefaultAnimatedStickerNodeImpl() animationNode.autoplay = true animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: stickerName), width: 384, height: 384, playbackMode: .still(.end), mode: .direct(cachePathPrefix: nil)) diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift index 55867970ea..dbab78d84a 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift @@ -416,8 +416,15 @@ private final class StarsTransactionSheetContent: CombinedComponent { isSubscriptionFee = true } else if transaction.flags.contains(.isGift) { titleText = strings.Stars_Gift_Received_Title - descriptionText = strings.Stars_Gift_Received_Text count = transaction.count + + //TODO:localize + if count.currency == .ton { + descriptionText = "Use TON to submit post suggestions to channels on Telegram." + } else { + descriptionText = strings.Stars_Gift_Received_Text + } + countOnTop = true transactionId = transaction.id date = transaction.date @@ -552,7 +559,7 @@ private final class StarsTransactionSheetContent: CombinedComponent { toPeer = peer } transactionPeer = transaction.peer - media = transaction.media.map { AnyMediaReference.starsTransaction(transaction: StarsTransactionReference(peerId: parentPeer.id, id: transaction.id, isRefund: transaction.flags.contains(.isRefund)), media: $0) } + media = transaction.media.map { AnyMediaReference.starsTransaction(transaction: StarsTransactionReference(peerId: parentPeer.id, ton: false, id: transaction.id, isRefund: transaction.flags.contains(.isRefund)), media: $0) } photo = transaction.photo if transaction.flags.contains(.isRefund) { @@ -706,6 +713,10 @@ private final class StarsTransactionSheetContent: CombinedComponent { transition: .immediate ) + if count.currency == .ton { + premiumGiftMonths = 1000 + } + let imageSubject: StarsImageComponent.Subject var imageIcon: StarsImageComponent.Icon? if let premiumGiftMonths { @@ -732,9 +743,9 @@ private final class StarsTransactionSheetContent: CombinedComponent { imageSubject = .none } if isSubscription || isSubscriber || isSubscriptionFee || giveawayMessageId != nil { - imageIcon = count.currency == .ton ? .ton : .star + imageIcon = count.currency == .ton ? nil : .star } else { - imageIcon = count.currency == .ton ? .ton : nil + imageIcon = nil } if isSubscription && "".isEmpty { diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift index 1c16a1db28..49ef7dc8c0 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsStatisticsScreen.swift @@ -522,21 +522,21 @@ final class StarsStatisticsScreenComponent: Component { theme: environment.theme, dateTimeFormat: environment.dateTimeFormat, title: strings.Stars_BotRevenue_Proceeds_Available, - value: starsState?.balances.availableBalance ?? StarsAmount.zero, + value: starsState?.balances.availableBalance.amount ?? StarsAmount.zero, rate: starsState?.usdRate ?? 0.0 ))), AnyComponentWithIdentity(id: 1, component: AnyComponent(StarsOverviewItemComponent( theme: environment.theme, dateTimeFormat: environment.dateTimeFormat, title: strings.Stars_BotRevenue_Proceeds_Current, - value: starsState?.balances.currentBalance ?? StarsAmount.zero, + value: starsState?.balances.currentBalance.amount ?? StarsAmount.zero, rate: starsState?.usdRate ?? 0.0 ))), AnyComponentWithIdentity(id: 2, component: AnyComponent(StarsOverviewItemComponent( theme: environment.theme, dateTimeFormat: environment.dateTimeFormat, title: strings.Stars_BotRevenue_Proceeds_Total, - value: starsState?.balances.overallRevenue ?? StarsAmount.zero, + value: starsState?.balances.overallRevenue.amount ?? StarsAmount.zero, rate: starsState?.usdRate ?? 0.0 ))) ], @@ -579,7 +579,7 @@ final class StarsStatisticsScreenComponent: Component { theme: environment.theme, strings: strings, dateTimeFormat: environment.dateTimeFormat, - count: self.starsState?.balances.availableBalance ?? StarsAmount.zero, + count: self.starsState?.balances.availableBalance.amount ?? StarsAmount.zero, currency: .stars, rate: self.starsState?.usdRate ?? 0, actionTitle: strings.Stars_Intro_BuyShort, @@ -623,7 +623,7 @@ final class StarsStatisticsScreenComponent: Component { theme: environment.theme, strings: strings, dateTimeFormat: environment.dateTimeFormat, - count: self.starsState?.balances.availableBalance ?? StarsAmount.zero, + count: self.starsState?.balances.availableBalance.amount ?? StarsAmount.zero, currency: .stars, rate: self.starsState?.usdRate ?? 0, actionTitle: strings.Stars_BotRevenue_Withdraw_WithdrawShort, diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift index 6f2f6d2faf..539c5481e3 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift @@ -501,7 +501,7 @@ final class StarsTransactionsScreenComponent: Component { let headerComponent: AnyComponent if component.starsContext.ton { - headerComponent = AnyComponent(PremiumDiamondComponent()) + headerComponent = AnyComponent(PremiumDiamondComponent(theme: environment.theme)) } else { headerComponent = AnyComponent(PremiumStarComponent( theme: environment.theme, @@ -667,9 +667,8 @@ final class StarsTransactionsScreenComponent: Component { contentHeight += descriptionSize.height contentHeight += 29.0 - let withdrawAvailable = component.starsContext.ton ? (self.starsState?.balance.value ?? 0) > 0 : (self.revenueState?.balances.overallRevenue.value ?? 0) > 0 + let withdrawAvailable = (self.revenueState?.balances.overallRevenue.amount.value ?? 0) > 0 - //TODO:localize let premiumConfiguration = PremiumConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 }) let balanceSize = self.balanceView.update( transition: .immediate, @@ -685,8 +684,8 @@ final class StarsTransactionsScreenComponent: Component { count: self.starsState?.balance ?? StarsAmount.zero, currency: component.starsContext.ton ? .ton : .stars, rate: nil, - actionTitle: component.starsContext.ton ? "Withdraw via Fragment" : (withdrawAvailable ? environment.strings.Stars_Intro_BuyShort : environment.strings.Stars_Intro_Buy), - actionAvailable: (component.starsContext.ton && withdrawAvailable) || (!premiumConfiguration.areStarsDisabled && !premiumConfiguration.isPremiumDisabled), + actionTitle: (withdrawAvailable ? environment.strings.Stars_Intro_BuyShort : environment.strings.Stars_Intro_Buy), + actionAvailable: (!component.starsContext.ton && !premiumConfiguration.areStarsDisabled && !premiumConfiguration.isPremiumDisabled), actionIsEnabled: true, actionIcon: component.starsContext.ton ? nil : PresentationResourcesItemList.itemListRoundTopupIcon(environment.theme), action: { [weak self] in @@ -1139,7 +1138,7 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer { self.context = context self.starsContext = starsContext - self.starsRevenueStatsContext = context.engine.payments.peerStarsRevenueContext(peerId: context.account.peerId) + self.starsRevenueStatsContext = context.engine.payments.peerStarsRevenueContext(peerId: context.account.peerId, ton: false) if !starsContext.ton { self.subscriptionsContext = context.engine.payments.peerStarsSubscriptionsContext(starsContext: starsContext) } else { diff --git a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsRevenueWithdrawalController.swift b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsRevenueWithdrawalController.swift index 4f52ba6b87..cc62907d39 100644 --- a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsRevenueWithdrawalController.swift +++ b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsRevenueWithdrawalController.swift @@ -46,7 +46,7 @@ public func confirmStarsRevenueWithdrawalController(context: AccountContext, upd } contentNode.updateIsChecking(true) - let signal = context.engine.peers.requestStarsRevenueWithdrawalUrl(peerId: peerId, amount: amount, password: contentNode.password) + let signal = context.engine.peers.requestStarsRevenueWithdrawalUrl(peerId: peerId, ton: false, amount: amount, password: contentNode.password) disposable.set((signal |> deliverOnMainQueue).start(next: { url in dismissImpl?() completion(url) diff --git a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift index 5f6153be25..540792b660 100644 --- a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift @@ -162,7 +162,7 @@ private final class SheetContent: CombinedComponent { amountPlaceholder = environment.strings.Stars_Withdraw_AmountPlaceholder minAmount = withdrawConfiguration.minWithdrawAmount.flatMap { StarsAmount(value: $0, nanos: 0) } - maxAmount = status.balances.availableBalance + maxAmount = status.balances.availableBalance.amount case .accountWithdraw: titleString = environment.strings.Stars_Withdraw_Title amountTitle = environment.strings.Stars_Withdraw_AmountTitle @@ -241,7 +241,7 @@ private final class SheetContent: CombinedComponent { } else if case .reaction = component.mode { balance = state.starsBalance } else if case let .withdraw(starsState, _) = component.mode { - balance = starsState.balances.availableBalance + balance = starsState.balances.availableBalance.amount } else { balance = nil } @@ -785,7 +785,7 @@ private final class SheetContent: CombinedComponent { var currency: CurrencyAmount.Currency = .stars switch mode { case let .withdraw(stats, _): - amount = StarsAmount(value: stats.balances.availableBalance.value, nanos: 0) + amount = StarsAmount(value: stats.balances.availableBalance.amount.value, nanos: 0) case .accountWithdraw: amount = context.starsContext?.currentState.flatMap { StarsAmount(value: $0.balance.value, nanos: 0) } case let .paidMedia(initialValue, _): diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/Contents.json new file mode 100644 index 0000000000..dd0e81618e --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sistemplus_16.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/sistemplus_16.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/sistemplus_16.pdf new file mode 100644 index 0000000000..410c86c7db Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoAppended.imageset/sistemplus_16.pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/Contents.json new file mode 100644 index 0000000000..7a7eabb25d --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sistemdone_16.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/sistemdone_16.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/sistemdone_16.pdf new file mode 100644 index 0000000000..13d65863ca Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoCompleted.imageset/sistemdone_16.pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/Contents.json new file mode 100644 index 0000000000..33a80c1c9a --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sistemundone_16.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/sistemundone_16.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/sistemundone_16.pdf new file mode 100644 index 0000000000..86308a8fa1 Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Message/ServiceTodoIncompleted.imageset/sistemundone_16.pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/Contents.json new file mode 100644 index 0000000000..2f8a451be0 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "checks.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/checks.pdf b/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/checks.pdf new file mode 100644 index 0000000000..eded18842e Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Premium/Perk/Todo.imageset/checks.pdf differ diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index 5109478202..5863cbb9d1 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -611,15 +611,9 @@ extension ChatControllerImpl { } if #available(iOS 18.0, *) { - if self.context.sharedContext.immediateExperimentalUISettings.enableLocalTranslation { - if engineExperimentalInternalTranslationService == nil, let hostView = self.context.sharedContext.mainWindow?.hostView { - let translationService = ExperimentalInternalTranslationServiceImpl(view: hostView.containerView) - engineExperimentalInternalTranslationService = translationService - } - } else { - if engineExperimentalInternalTranslationService != nil { - engineExperimentalInternalTranslationService = nil - } + if engineExperimentalInternalTranslationService == nil, let hostView = self.context.sharedContext.mainWindow?.hostView { + let translationService = ExperimentalInternalTranslationServiceImpl(view: hostView.containerView) + engineExperimentalInternalTranslationService = translationService } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 5183326007..d9d294768d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -3582,15 +3582,23 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: context.sharedContext.accountManager, timestamp: Int32(Date().timeIntervalSince1970)).startStandalone() - let controller = TranslateScreen(context: context, text: text.string, canCopy: canCopy, fromLanguage: language, ignoredLanguages: translationSettings.ignoredLanguages) - controller.pushController = { [weak self] c in - self?.effectiveNavigationController?._keepModalDismissProgress = true - self?.push(c) - } - controller.presentController = { [weak self] c in - self?.present(c, in: .window(.root)) - } - strongSelf.present(controller, in: .window(.root)) + presentTranslateScreen( + context: context, + text: text.string, + canCopy: canCopy, + fromLanguage: language, + ignoredLanguages: translationSettings.ignoredLanguages, + pushController: { [weak self] c in + self?.effectiveNavigationController?._keepModalDismissProgress = true + self?.push(c) + }, + presentController: { [weak self] c in + self?.present(c, in: .window(.root)) + }, + display: { [weak self] c in + self?.present(c, in: .window(.root)) + } + ) }) } if let currentContextController = strongSelf.currentContextController { diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 4c7b67c473..f24d0624f1 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -98,6 +98,21 @@ func openResolvedUrlImpl( case let .botStart(peer, payload): openPeer(EnginePeer(peer), .withBotStartPayload(ChatControllerInitialBotStart(payload: payload, behavior: .interactive))) case let .groupBotStart(botPeerId, payload, adminRights, peerType): + let defaultAdminRights = Promise<(group: TelegramChatAdminRights?, channel: TelegramChatAdminRights?)?>(nil) + if adminRights == nil { + defaultAdminRights.set( + context.engine.peers.fetchAndUpdateCachedPeerData(peerId: botPeerId) + |> mapToSignal { _ in + return context.engine.data.get( + TelegramEngine.EngineData.Item.Peer.BotGroupAdminRights(id: botPeerId), + TelegramEngine.EngineData.Item.Peer.BotChannelAdminRights(id: botPeerId) + ) |> map { groupRights, channelRights in + return (groupRights, channelRights) + } + } + ) + } + var filter: ChatListNodePeersFilter = [.onlyGroupsAndChannels, .onlyManageable, .excludeDisabled, .excludeRecent, .doNotSearchMessages] var title: String = presentationData.strings.Bot_AddToChat_Title switch peerType { @@ -179,11 +194,20 @@ func openResolvedUrlImpl( } if case let .channel(peer) = peer { + var isGroup = false + if case .group = peer.info { + isGroup = true + } if peer.flags.contains(.isCreator) || peer.adminRights?.rights.contains(.canAddAdmins) == true { - let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: adminRights?.chatAdminRights, updated: { _ in - controller?.dismiss() - }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) - navigationController?.pushViewController(controller) + let _ = (defaultAdminRights.get() + |> take(1) + |> deliverOnMainQueue).start(next: { defaultAdminRights in + let initialAdminRights = adminRights?.chatAdminRights ?? (isGroup ? defaultAdminRights?.group?.rights : defaultAdminRights?.channel?.rights) + let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: initialAdminRights, updated: { _ in + controller?.dismiss() + }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) + navigationController?.pushViewController(controller) + }) } else { addMemberImpl() } @@ -191,10 +215,15 @@ func openResolvedUrlImpl( if case .member = peer.role { addMemberImpl() } else { - let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: adminRights?.chatAdminRights, updated: { _ in - controller?.dismiss() - }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) - navigationController?.pushViewController(controller) + let _ = (defaultAdminRights.get() + |> take(1) + |> deliverOnMainQueue).start(next: { defaultAdminRights in + let initialAdminRights = adminRights?.chatAdminRights ?? defaultAdminRights?.group?.rights + let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: initialAdminRights, updated: { _ in + controller?.dismiss() + }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) + navigationController?.pushViewController(controller) + }) } } } diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 98b317cd03..bef45d63c7 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -180,7 +180,8 @@ public func translateMessageIds(context: AccountContext, messageIds: [EngineMess } } } - return context.engine.messages.translateMessages(messageIds: messageIdsToTranslate, fromLang: fromLang, toLang: toLang, enableLocalIfPossible: context.sharedContext.immediateExperimentalUISettings.enableLocalTranslation) + + return context.engine.messages.translateMessages(messageIds: messageIdsToTranslate, fromLang: fromLang, toLang: toLang, enableLocalIfPossible: true) //context.sharedContext.immediateExperimentalUISettings.enableLocalTranslation) |> `catch` { _ -> Signal in return .complete() } diff --git a/submodules/TranslateUI/Sources/Translate.swift b/submodules/TranslateUI/Sources/Translate.swift index 4d48f66e10..9c9d211952 100644 --- a/submodules/TranslateUI/Sources/Translate.swift +++ b/submodules/TranslateUI/Sources/Translate.swift @@ -176,6 +176,21 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat return (false, nil) } + let translationConfiguration = TranslationConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + var translateButtonAvailable = false + switch translationConfiguration.manual { + case .enabled, .alternative: + translateButtonAvailable = true + case .system: + if #available(iOS 18.0, *) { + translateButtonAvailable = true + } + default: + break + } + + let showTranslate = showTranslate && translateButtonAvailable + if #available(iOS 12.0, *) { if context.sharedContext.immediateExperimentalUISettings.disableLanguageRecognition { return (true, nil) @@ -403,3 +418,121 @@ public final class ExperimentalInternalTranslationServiceImpl: ExperimentalInter } } } + +func alternativeTranslateText(text: String, fromLang: String?, toLang: String) -> Signal<(String, [MessageTextEntity])?, TelegramCore.TranslationError> { + return Signal { subscriber in + var task: URLSessionTask? + Queue.concurrentDefaultQueue().async { + let effectiveFromLang: String + if let fromLang { + effectiveFromLang = fromLang + } else { + languageRecognizer.processString(text) + let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 3) + languageRecognizer.reset() + + let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalizeTranslationLanguage($0.key.rawValue)) }.sorted(by: { $0.value > $1.value }) + if let language = filteredLanguages.first { + let languageCode = normalizeTranslationLanguage(language.key.rawValue) + effectiveFromLang = languageCode + } else { + effectiveFromLang = "en" + } + } + + var uri = "https://translate.goo" + uri += "gleapis.com/transl" + uri += "ate_a" + uri += "/singl" + uri += "e?client=gtx&sl=\(effectiveFromLang.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")" + uri += "&tl=\(toLang.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")" + uri += "&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=0&tsel=0&kc=7&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&q=" + uri += text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "" + + guard let url = URL(string: uri) else { + subscriber.putError(.generic) + return + } + + var request = URLRequest(url: url) + request.httpMethod = "GET" + request.setValue(getRandomUserAgent(), forHTTPHeaderField: "User-Agent") + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + task = URLSession.shared.dataTask(with: request) { data, response, error in + if let error = error { + print("Translation failed: \(error.localizedDescription)") + subscriber.putError(.generic) + return + } + + guard let httpResponse = response as? HTTPURLResponse else { + subscriber.putError(.generic) + return + } + + if httpResponse.statusCode != 200 { + print("Translation failed with status code: \(httpResponse.statusCode)") + let isRateLimit = httpResponse.statusCode == 429 + subscriber.putError(isRateLimit ? .limitExceeded : .generic) + return + } + + guard let data = data else { + subscriber.putError(.generic) + return + } + + do { + guard let jsonArray = try JSONSerialization.jsonObject(with: data) as? [Any] else { + subscriber.putError(.generic) + return + } + + guard let translationArray = jsonArray.first as? [Any] else { + subscriber.putError(.generic) + return + } + +// var sourceLanguage: String? = nil +// if jsonArray.count > 2, let lang = jsonArray[2] as? String { +// sourceLanguage = lang.contains("-") ? String(lang.prefix(while: { $0 != "-" })) : lang +// } + + var result = "" + for element in translationArray { + if let translationBlock = element as? [Any], + translationBlock.count > 0, + let blockText = translationBlock[0] as? String, + blockText != "null" && !blockText.isEmpty { + result += blockText + } + } + + if text.hasPrefix("\n") { + result = "\n" + result + } + + subscriber.putNext((result, [])) + subscriber.putCompletion() + } catch { + print("JSON parsing error: \(error)") + subscriber.putError(.generic) + } + } + task?.resume() + } + return ActionDisposable { + task?.cancel() + } + } +} + +func getRandomUserAgent() -> String { + let userAgents = [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Safari/605.1.15", + "Mozilla/5.0 (iPhone; CPU iPhone OS 18_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Mobile/15E148 Safari/604.1" + ] + return userAgents.randomElement() ?? userAgents[0] +} diff --git a/submodules/TranslateUI/Sources/TranslateScreen.swift b/submodules/TranslateUI/Sources/TranslateScreen.swift index 5ed5c5c428..d246a19ad3 100644 --- a/submodules/TranslateUI/Sources/TranslateScreen.swift +++ b/submodules/TranslateUI/Sources/TranslateScreen.swift @@ -14,6 +14,7 @@ import MultilineTextComponent import MultilineTextWithEntitiesComponent import BundleIconComponent import UndoUI +import SwiftUI private func generateExpandBackground(size: CGSize, color: UIColor) -> UIImage { return generateImage(size, rotatedContext: { size, context in @@ -94,6 +95,8 @@ private final class TranslateScreenComponent: CombinedComponent { fileprivate var moreBackgroundImage: (CGSize, UIImage, UIColor)? + private let useAlternativeTranslation: Bool + init(context: AccountContext, fromLanguage: String?, text: String, toLanguage: String, expand: @escaping () -> Void) { self.context = context self.text = text @@ -102,9 +105,19 @@ private final class TranslateScreenComponent: CombinedComponent { self.expand = expand self.availableSpeakLanguages = supportedSpeakLanguages() + let translationConfiguration = TranslationConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + var useAlternativeTranslation = false + switch translationConfiguration.manual { + case .alternative: + useAlternativeTranslation = true + default: + break + } + self.useAlternativeTranslation = useAlternativeTranslation + super.init() - self.translationDisposable.set((context.engine.messages.translate(text: text, toLang: toLanguage) |> deliverOnMainQueue).start(next: { [weak self] text in + self.translationDisposable.set((self.translate(text: text, fromLang: fromLanguage, toLang: toLanguage) |> deliverOnMainQueue).start(next: { [weak self] text in guard let strongSelf = self else { return } @@ -120,6 +133,14 @@ private final class TranslateScreenComponent: CombinedComponent { self.translationDisposable.dispose() } + func translate(text: String, fromLang: String?, toLang: String) -> Signal<(String, [MessageTextEntity])?, TranslationError> { + if self.useAlternativeTranslation { + return alternativeTranslateText(text: text, fromLang: fromLang, toLang: toLang) + } else { + return self.context.engine.messages.translate(text: text, toLang: toLang) + } + } + func changeLanguage(fromLanguage: String, toLanguage: String) { guard self.fromLanguage != fromLanguage || self.toLanguage != toLanguage else { return @@ -129,7 +150,7 @@ private final class TranslateScreenComponent: CombinedComponent { self.translatedText = nil self.updated(transition: .immediate) - self.translationDisposable.set((self.context.engine.messages.translate(text: text, toLang: toLanguage) |> deliverOnMainQueue).start(next: { [weak self] text in + self.translationDisposable.set((self.translate(text: text, fromLang: fromLanguage, toLang: toLanguage) |> deliverOnMainQueue).start(next: { [weak self] text in guard let strongSelf = self else { return } @@ -1163,3 +1184,85 @@ public class TranslateScreen: ViewController { self.node.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: ComponentTransition(transition)) } } + +public func presentTranslateScreen( + context: AccountContext, + text: String, + entities: [MessageTextEntity] = [], + canCopy: Bool, + fromLanguage: String?, + toLanguage: String? = nil, + isExpanded: Bool = false, + ignoredLanguages: [String]? = nil, + pushController: @escaping (ViewController) -> Void = { _ in }, + presentController: @escaping (ViewController) -> Void = { _ in }, + wasDismissed: (() -> Void)? = nil, + display: (ViewController) -> Void +) { + let translationConfiguration = TranslationConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + var useSystemTranslation = false + switch translationConfiguration.manual { + case .system: + if #available(iOS 18.0, *) { + useSystemTranslation = true + } + default: + break + } + + if useSystemTranslation { + presentSystemTranslateScreen(context: context, text: text) + } else { + let controller = TranslateScreen(context: context, text: text, canCopy: canCopy, fromLanguage: fromLanguage, toLanguage: toLanguage, isExpanded: isExpanded, ignoredLanguages: ignoredLanguages) + controller.pushController = pushController + controller.presentController = presentController + controller.wasDismissed = wasDismissed + display(controller) + } +} + +private func presentSystemTranslateScreen(context: AccountContext, text: String) { + if #available(iOS 18.0, *), let rootViewController = context.sharedContext.mainWindow?.viewController?.view.window?.rootViewController { + var dismissImpl: (() -> Void)? + let pickerView = TranslateScreenHostingView(text: text, completionHandler: { [weak rootViewController] in + DispatchQueue.main.async(execute: { + guard let presentedController = rootViewController?.presentedViewController, presentedController.isBeingDismissed == false else { return } + dismissImpl?() + }) + }) + let hostingController = UIHostingController(rootView: pickerView) + hostingController.view.isHidden = true + hostingController.modalPresentationStyle = .overCurrentContext + rootViewController.present(hostingController, animated: true) + dismissImpl = { [weak hostingController] in + Queue.mainQueue().after(0.4, { + hostingController?.dismiss(animated: false) + }) + } + } +} + +@available(iOS 18.0, *) +struct TranslateScreenHostingView: View { + @State var presented = true + var text: String + var handler: () -> Void + + init(text: String, completionHandler: @escaping () -> Void) { + self.text = text + self.handler = completionHandler + } + + var body: some View { + Spacer() + .translationPresentation( + isPresented: $presented, + text: text + ) + .onChange(of: presented) { newValue in + if newValue == false { + handler() + } + } + } +}