mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch '189layer'
This commit is contained in:
commit
848d8939f1
99 changed files with 9632 additions and 2002 deletions
|
|
@ -12941,3 +12941,8 @@ Sorry for the inconvenience.";
|
|||
"VerificationCodes.DescriptionText" = "This chat is used to receive verification codes from third-party services.";
|
||||
|
||||
"Conversation.CodeCopied" = "Code copied to clipboard";
|
||||
|
||||
"Stars.Purchase.StarGiftInfo" = "Buy Stars to send **%@** gifts that can be kept on the profile or converted to Stars.";
|
||||
|
||||
"SharedMedia.GiftCount_1" = "%@ gift";
|
||||
"SharedMedia.GiftCount_any" = "%@ gifts";
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,8 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func makeStarsWithdrawalScreen(context: AccountContext, stats: StarsRevenueStats, completion: @escaping (Int64) -> Void) -> ViewController
|
||||
func makeStarsGiftScreen(context: AccountContext, message: EngineMessage) -> ViewController
|
||||
func makeStarsGiveawayBoostScreen(context: AccountContext, peerId: EnginePeer.Id, boost: ChannelBoostersContext.State.Boost) -> ViewController
|
||||
func makeStarsIntroScreen(context: AccountContext) -> ViewController
|
||||
func makeGiftViewScreen(context: AccountContext, message: EngineMessage) -> ViewController
|
||||
|
||||
func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError>
|
||||
func makeMiniAppListScreen(context: AccountContext, initialData: MiniAppListScreenInitialData) -> ViewController
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public final class ChatMessageItemAssociatedData: Equatable {
|
|||
public let isStandalone: Bool
|
||||
public let isInline: Bool
|
||||
public let showSensitiveContent: Bool
|
||||
public let starGifts: [Int64: TelegramMediaFile]
|
||||
|
||||
public init(
|
||||
automaticDownloadPeerType: MediaAutoDownloadPeerType,
|
||||
|
|
@ -96,7 +97,8 @@ public final class ChatMessageItemAssociatedData: Equatable {
|
|||
deviceContactsNumbers: Set<String> = Set(),
|
||||
isStandalone: Bool = false,
|
||||
isInline: Bool = false,
|
||||
showSensitiveContent: Bool = false
|
||||
showSensitiveContent: Bool = false,
|
||||
starGifts: [Int64: TelegramMediaFile] = [:]
|
||||
) {
|
||||
self.automaticDownloadPeerType = automaticDownloadPeerType
|
||||
self.automaticDownloadPeerId = automaticDownloadPeerId
|
||||
|
|
@ -130,6 +132,7 @@ public final class ChatMessageItemAssociatedData: Equatable {
|
|||
self.isStandalone = isStandalone
|
||||
self.isInline = isInline
|
||||
self.showSensitiveContent = showSensitiveContent
|
||||
self.starGifts = starGifts
|
||||
}
|
||||
|
||||
public static func == (lhs: ChatMessageItemAssociatedData, rhs: ChatMessageItemAssociatedData) -> Bool {
|
||||
|
|
@ -223,6 +226,9 @@ public final class ChatMessageItemAssociatedData: Equatable {
|
|||
if lhs.showSensitiveContent != rhs.showSensitiveContent {
|
||||
return false
|
||||
}
|
||||
if lhs.starGifts != rhs.starGifts {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ public final class ContactSelectionControllerParams {
|
|||
public let multipleSelection: Bool
|
||||
public let requirePhoneNumbers: Bool
|
||||
public let confirmation: (ContactListPeer) -> Signal<Bool, NoError>
|
||||
public let openProfile: ((EnginePeer) -> Void)?
|
||||
public let sendMessage: ((EnginePeer) -> Void)?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: ContactSelectionControllerMode = .generic, autoDismiss: Bool = true, title: @escaping (PresentationStrings) -> String, options: Signal<[ContactListAdditionalOption], NoError> = .single([]), displayDeviceContacts: Bool = false, displayCallIcons: Bool = false, multipleSelection: Bool = false, requirePhoneNumbers: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal<Bool, NoError> = { _ in .single(true) }) {
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: ContactSelectionControllerMode = .generic, autoDismiss: Bool = true, title: @escaping (PresentationStrings) -> String, options: Signal<[ContactListAdditionalOption], NoError> = .single([]), displayDeviceContacts: Bool = false, displayCallIcons: Bool = false, multipleSelection: Bool = false, requirePhoneNumbers: Bool = false, confirmation: @escaping (ContactListPeer) -> Signal<Bool, NoError> = { _ in .single(true) }, openProfile: ((EnginePeer) -> Void)? = nil, sendMessage: ((EnginePeer) -> Void)? = nil) {
|
||||
self.context = context
|
||||
self.updatedPresentationData = updatedPresentationData
|
||||
self.mode = mode
|
||||
|
|
@ -114,5 +116,7 @@ public final class ContactSelectionControllerParams {
|
|||
self.multipleSelection = multipleSelection
|
||||
self.requirePhoneNumbers = requirePhoneNumbers
|
||||
self.confirmation = confirmation
|
||||
self.openProfile = openProfile
|
||||
self.sendMessage = sendMessage
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ public enum StarsPurchasePurpose: Equatable {
|
|||
case subscription(peerId: EnginePeer.Id, requiredStars: Int64, renew: Bool)
|
||||
case gift(peerId: EnginePeer.Id)
|
||||
case unlockMedia(requiredStars: Int64)
|
||||
case starGift(peerId: EnginePeer.Id, requiredStars: Int64)
|
||||
}
|
||||
|
||||
public struct PremiumConfiguration {
|
||||
|
|
@ -276,3 +277,7 @@ public struct PremiumConfiguration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public protocol GiftOptionsScreenProtocol {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -992,7 +992,7 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
|||
sendWhenOnlineAvailable = true
|
||||
}
|
||||
}
|
||||
if peer.id.namespace == Namespaces.Peer.CloudUser && peer.id.id._internalGetInt64Value() == 777000 {
|
||||
if peer.id.isTelegramNotifications {
|
||||
sendWhenOnlineAvailable = false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,30 +29,41 @@ public final class BotCheckoutController: ViewController {
|
|||
|
||||
public static func fetch(context: AccountContext, source: BotPaymentInvoiceSource) -> Signal<InputData, FetchError> {
|
||||
let theme = context.sharedContext.currentPresentationData.with { $0 }.theme
|
||||
let themeParams: [String: Any] = [
|
||||
"bg_color": Int32(bitPattern: theme.list.plainBackgroundColor.rgb),
|
||||
"secondary_bg_color": Int32(bitPattern: theme.list.blocksBackgroundColor.rgb),
|
||||
"text_color": Int32(bitPattern: theme.list.itemPrimaryTextColor.rgb),
|
||||
"hint_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||
"link_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||
"button_color": Int32(bitPattern: theme.list.itemCheckColors.fillColor.rgb),
|
||||
"button_text_color": Int32(bitPattern: theme.list.itemCheckColors.foregroundColor.rgb),
|
||||
"header_bg_color": Int32(bitPattern: theme.rootController.navigationBar.opaqueBackgroundColor.rgb),
|
||||
"accent_text_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||
"section_bg_color": Int32(bitPattern: theme.list.itemBlocksBackgroundColor.rgb),
|
||||
"section_header_text_color": Int32(bitPattern: theme.list.freeTextColor.rgb),
|
||||
"subtitle_text_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||
"destructive_text_color": Int32(bitPattern: theme.list.itemDestructiveColor.rgb),
|
||||
"section_separator_color": Int32(bitPattern: theme.list.itemBlocksSeparatorColor.rgb)
|
||||
]
|
||||
let themeParams: [String: Any]?
|
||||
if case .starGift = source {
|
||||
themeParams = nil
|
||||
} else {
|
||||
themeParams = [
|
||||
"bg_color": Int32(bitPattern: theme.list.plainBackgroundColor.rgb),
|
||||
"secondary_bg_color": Int32(bitPattern: theme.list.blocksBackgroundColor.rgb),
|
||||
"text_color": Int32(bitPattern: theme.list.itemPrimaryTextColor.rgb),
|
||||
"hint_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||
"link_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||
"button_color": Int32(bitPattern: theme.list.itemCheckColors.fillColor.rgb),
|
||||
"button_text_color": Int32(bitPattern: theme.list.itemCheckColors.foregroundColor.rgb),
|
||||
"header_bg_color": Int32(bitPattern: theme.rootController.navigationBar.opaqueBackgroundColor.rgb),
|
||||
"accent_text_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||
"section_bg_color": Int32(bitPattern: theme.list.itemBlocksBackgroundColor.rgb),
|
||||
"section_header_text_color": Int32(bitPattern: theme.list.freeTextColor.rgb),
|
||||
"subtitle_text_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||
"destructive_text_color": Int32(bitPattern: theme.list.itemDestructiveColor.rgb),
|
||||
"section_separator_color": Int32(bitPattern: theme.list.itemBlocksSeparatorColor.rgb)
|
||||
]
|
||||
}
|
||||
|
||||
return context.engine.payments.fetchBotPaymentForm(source: source, themeParams: themeParams)
|
||||
|> mapError { _ -> FetchError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { paymentForm -> Signal<InputData, FetchError> in
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: paymentForm.paymentBotId))
|
||||
|> castError(FetchError.self)
|
||||
let botPeer: Signal<EnginePeer?, FetchError>
|
||||
if let paymentBotId = paymentForm.paymentBotId {
|
||||
botPeer = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: paymentBotId))
|
||||
|> castError(FetchError.self)
|
||||
} else {
|
||||
botPeer = .single(nil)
|
||||
}
|
||||
return botPeer
|
||||
|> mapToSignal { botPeer -> Signal<InputData, FetchError> in
|
||||
if let current = paymentForm.savedInfo {
|
||||
return context.engine.payments.validateBotPaymentForm(saveInfo: true, source: source, formInfo: current)
|
||||
|
|
|
|||
|
|
@ -1389,6 +1389,9 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||
}
|
||||
|
||||
let botPeerId = paymentForm.paymentBotId
|
||||
guard let botPeerId else {
|
||||
return
|
||||
}
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: botPeerId)
|
||||
)
|
||||
|
|
@ -1460,15 +1463,15 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||
}
|
||||
}
|
||||
|
||||
if !liabilityNoticeAccepted {
|
||||
if !liabilityNoticeAccepted, let paymentBotId = paymentForm.paymentBotId {
|
||||
let botPeer: Signal<EnginePeer?, NoError> = self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: paymentForm.paymentBotId)
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: paymentBotId)
|
||||
)
|
||||
let providerPeer: Signal<EnginePeer?, NoError> = paymentForm.providerId.flatMap {
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: $0))
|
||||
} ?? .single(nil)
|
||||
let _ = (combineLatest(
|
||||
ApplicationSpecificNotice.getBotPaymentLiability(accountManager: self.context.sharedContext.accountManager, peerId: paymentForm.paymentBotId),
|
||||
ApplicationSpecificNotice.getBotPaymentLiability(accountManager: self.context.sharedContext.accountManager, peerId: paymentBotId),
|
||||
botPeer,
|
||||
providerPeer
|
||||
)
|
||||
|
|
@ -1489,7 +1492,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||
|
||||
strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Checkout_LiabilityAlertTitle, text: paymentText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
||||
if let strongSelf = self {
|
||||
let _ = ApplicationSpecificNotice.setBotPaymentLiability(accountManager: strongSelf.context.sharedContext.accountManager, peerId: paymentForm.paymentBotId).start()
|
||||
let _ = ApplicationSpecificNotice.setBotPaymentLiability(accountManager: strongSelf.context.sharedContext.accountManager, peerId: paymentBotId).start()
|
||||
strongSelf.pay(savedCredentialsToken: savedCredentialsToken, liabilityNoticeAccepted: true)
|
||||
}
|
||||
})]), nil)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/SaveProgressScreen",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/Utils/DeviceModel",
|
||||
"//submodules/LegacyMediaPickerUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import UrlEscaping
|
|||
import UrlHandling
|
||||
import SaveProgressScreen
|
||||
import DeviceModel
|
||||
import LegacyMediaPickerUI
|
||||
|
||||
private final class TonSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
private final class PendingTask {
|
||||
|
|
@ -170,7 +171,7 @@ private func computedUserAgent() -> String {
|
|||
return DeviceModel.current.isIpad ? "Version/\(osVersion) Safari/605.1.15" : "Version/\(osVersion) Mobile/\(firmwareVersion) Safari/604.1"
|
||||
}
|
||||
|
||||
final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate {
|
||||
final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate, WKDownloadDelegate {
|
||||
private let context: AccountContext
|
||||
private var presentationData: PresentationData
|
||||
|
||||
|
|
@ -733,15 +734,15 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||
|
||||
@available(iOS 13.0, *)
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
|
||||
// if #available(iOS 14.5, *), navigationAction.shouldPerformDownload {
|
||||
// self.presentDownloadConfirmation(fileName: navigationAction.request.mainDocumentURL?.lastPathComponent ?? "file", proceed: { download in
|
||||
// if download {
|
||||
// decisionHandler(.download, preferences)
|
||||
// } else {
|
||||
//// decisionHandler(.cancel, preferences)
|
||||
// }
|
||||
// })
|
||||
// } else {
|
||||
if #available(iOS 14.5, *), navigationAction.shouldPerformDownload {
|
||||
self.presentDownloadConfirmation(fileName: navigationAction.request.mainDocumentURL?.lastPathComponent ?? "file", proceed: { download in
|
||||
if download {
|
||||
decisionHandler(.download, preferences)
|
||||
} else {
|
||||
decisionHandler(.cancel, preferences)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if let url = navigationAction.request.url?.absoluteString {
|
||||
if (navigationAction.targetFrame == nil || navigationAction.targetFrame?.isMainFrame == true) && (isTelegramMeLink(url) || isTelegraPhLink(url) || url.hasPrefix("tg://")) && !url.contains("/auth/push?") && !self._state.url.contains("/auth/push?") {
|
||||
decisionHandler(.cancel, preferences)
|
||||
|
|
@ -758,24 +759,25 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||
} else {
|
||||
decisionHandler(.allow, preferences)
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||
// if navigationResponse.canShowMIMEType {
|
||||
// decisionHandler(.allow)
|
||||
// } else if #available(iOS 14.5, *) {
|
||||
// self.presentDownloadConfirmation(fileName: navigationResponse.response.suggestedFilename ?? "file", proceed: { download in
|
||||
// if download {
|
||||
// decisionHandler(.download)
|
||||
// } else {
|
||||
// decisionHandler(.cancel)
|
||||
// }
|
||||
// })
|
||||
// } else {
|
||||
// decisionHandler(.cancel)
|
||||
// }
|
||||
// }
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||
if navigationResponse.canShowMIMEType {
|
||||
decisionHandler(.allow)
|
||||
} else if #available(iOS 14.5, *) {
|
||||
// decisionHandler(.download)
|
||||
self.presentDownloadConfirmation(fileName: navigationResponse.response.suggestedFilename ?? "file", proceed: { download in
|
||||
if download {
|
||||
decisionHandler(.download)
|
||||
} else {
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
if let url = navigationAction.request.url?.absoluteString {
|
||||
|
|
@ -790,6 +792,101 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||
decisionHandler(.allow)
|
||||
}
|
||||
}
|
||||
|
||||
private var downloadArguments: (String, String)?
|
||||
private var downloadController: (AlertController, (Int64, Int64) -> Void)?
|
||||
private var downloadProgressObserver: Any?
|
||||
|
||||
@available(iOS 14.5, *)
|
||||
func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) {
|
||||
download.delegate = self
|
||||
}
|
||||
|
||||
@available(iOS 14.5, *)
|
||||
func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) {
|
||||
download.delegate = self
|
||||
}
|
||||
|
||||
@available(iOS 14.5, *)
|
||||
func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
|
||||
let path = NSTemporaryDirectory() + NSUUID().uuidString
|
||||
self.downloadArguments = (path, suggestedFilename)
|
||||
completionHandler(URL(fileURLWithPath: path))
|
||||
|
||||
let downloadController = progressAlertController(sharedContext: self.context.sharedContext, title: "", cancel: { [weak download] in
|
||||
download?.cancel()
|
||||
})
|
||||
self.downloadController = downloadController
|
||||
self.present(downloadController.0, nil)
|
||||
downloadController.1(download.progress.completedUnitCount, download.progress.totalUnitCount)
|
||||
|
||||
self.downloadProgressObserver = download.progress.observe(\.fractionCompleted) { [weak self] progress, _ in
|
||||
if let (_, update) = self?.downloadController {
|
||||
update(progress.completedUnitCount, progress.totalUnitCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.5, *)
|
||||
func downloadDidFinish(_ download: WKDownload) {
|
||||
if let (controller, _ ) = self.downloadController {
|
||||
controller.dismissAnimated()
|
||||
self.downloadController = nil
|
||||
}
|
||||
|
||||
if let (path, fileName) = self.downloadArguments {
|
||||
let tempFile = TempBox.shared.file(path: path, fileName: fileName)
|
||||
let url = URL(fileURLWithPath: tempFile.path)
|
||||
|
||||
let controller = legacyICloudFilePicker(theme: self.presentationData.theme, mode: .export, url: url, documentTypes: [], forceDarkTheme: false, dismissed: {}, completion: { _ in
|
||||
|
||||
})
|
||||
self.present(controller, nil)
|
||||
|
||||
self.downloadArguments = nil
|
||||
self.downloadProgressObserver = nil
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.5, *)
|
||||
func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
|
||||
self.downloadArguments = nil
|
||||
self.downloadProgressObserver = nil
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
||||
if let url = webView.url, !url.absoluteString.contains("beatsnvibes") {
|
||||
completionHandler(.performDefaultHandling, nil)
|
||||
return
|
||||
}
|
||||
var completed = false
|
||||
|
||||
let host = webView.url?.host ?? ""
|
||||
let authController = authController(sharedContext: self.context.sharedContext, updatedPresentationData: nil, title: "Sign in to \(host)", text: "Your login information will be sent securely.", apply: { result in
|
||||
if !completed {
|
||||
completed = true
|
||||
if let (login, password) = result {
|
||||
let credential = URLCredential(
|
||||
user: login,
|
||||
password: password,
|
||||
persistence: .permanent
|
||||
)
|
||||
completionHandler(.useCredential, credential)
|
||||
} else {
|
||||
completionHandler(.cancelAuthenticationChallenge, nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
authController.dismissed = { byOutsideTap in
|
||||
if byOutsideTap {
|
||||
if !completed {
|
||||
completed = true
|
||||
completionHandler(.cancelAuthenticationChallenge, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.present(authController, nil)
|
||||
}
|
||||
|
||||
private let isLoaded = ValuePromise<Bool>(false)
|
||||
private var instantPageDisposable = MetaDisposable()
|
||||
|
|
@ -880,7 +977,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
|
||||
if [-1003, -1100, 102].contains((error as NSError).code) {
|
||||
if [-1003, -1100].contains((error as NSError).code) {
|
||||
if let url = (error as NSError).userInfo["NSErrorFailingURLKey"] as? URL, url.absoluteString.hasPrefix("itms-appss:") {
|
||||
} else {
|
||||
self.currentError = error
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ swift_library(
|
|||
"//submodules/TelegramCore:TelegramCore",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import Postbox
|
|||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import TelegramStringFormatting
|
||||
|
||||
private final class PromptInputFieldNode: ASDisplayNode, ASEditableTextNodeDelegate {
|
||||
private var theme: PresentationTheme
|
||||
|
|
@ -39,7 +40,7 @@ private final class PromptInputFieldNode: ASDisplayNode, ASEditableTextNodeDeleg
|
|||
}
|
||||
}
|
||||
|
||||
init(theme: PresentationTheme, placeholder: String, characterLimit: Int) {
|
||||
init(theme: PresentationTheme, placeholder: String, characterLimit: Int, isPassword: Bool = false) {
|
||||
self.theme = theme
|
||||
self.characterLimit = characterLimit
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ private final class PromptInputFieldNode: ASDisplayNode, ASEditableTextNodeDeleg
|
|||
self.textInputNode.returnKeyType = .done
|
||||
self.textInputNode.autocorrectionType = .default
|
||||
self.textInputNode.tintColor = theme.actionSheet.controlAccentColor
|
||||
self.textInputNode.isSecureTextEntry = isPassword
|
||||
|
||||
self.placeholderNode = ASTextNode()
|
||||
self.placeholderNode.isUserInteractionEnabled = false
|
||||
|
|
@ -448,3 +450,538 @@ public func promptController(sharedContext: SharedAccountContext, updatedPresent
|
|||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
private final class AuthAlertContentNode: AlertContentNode {
|
||||
private let strings: PresentationStrings
|
||||
|
||||
private let title: String
|
||||
private let text: String
|
||||
|
||||
private let titleNode: ASTextNode
|
||||
private let textNode: ASTextNode
|
||||
let inputFieldNode: PromptInputFieldNode
|
||||
let passwordFieldNode: PromptInputFieldNode
|
||||
|
||||
private let actionNodesSeparator: ASDisplayNode
|
||||
private let actionNodes: [TextAlertContentActionNode]
|
||||
private let actionVerticalSeparators: [ASDisplayNode]
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
private var validLayout: CGSize?
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
var complete: (() -> Void)? {
|
||||
didSet {
|
||||
self.inputFieldNode.complete = self.complete
|
||||
}
|
||||
}
|
||||
|
||||
override var dismissOnOutsideTap: Bool {
|
||||
return self.isUserInteractionEnabled
|
||||
}
|
||||
|
||||
init(theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction], title: String, text: String) {
|
||||
self.strings = strings
|
||||
self.title = title
|
||||
self.text = text
|
||||
|
||||
self.titleNode = ASTextNode()
|
||||
self.titleNode.maximumNumberOfLines = 2
|
||||
|
||||
self.textNode = ASTextNode()
|
||||
self.textNode.maximumNumberOfLines = 2
|
||||
|
||||
self.inputFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: "User Name", characterLimit: 1024)
|
||||
self.passwordFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: "Password", characterLimit: 1024, isPassword: true)
|
||||
|
||||
self.actionNodesSeparator = ASDisplayNode()
|
||||
self.actionNodesSeparator.isLayerBacked = true
|
||||
|
||||
self.actionNodes = actions.map { action -> TextAlertContentActionNode in
|
||||
return TextAlertContentActionNode(theme: theme, action: action)
|
||||
}
|
||||
|
||||
var actionVerticalSeparators: [ASDisplayNode] = []
|
||||
if actions.count > 1 {
|
||||
for _ in 0 ..< actions.count - 1 {
|
||||
let separatorNode = ASDisplayNode()
|
||||
separatorNode.isLayerBacked = true
|
||||
actionVerticalSeparators.append(separatorNode)
|
||||
}
|
||||
}
|
||||
self.actionVerticalSeparators = actionVerticalSeparators
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.addSubnode(self.inputFieldNode)
|
||||
self.addSubnode(self.passwordFieldNode)
|
||||
|
||||
self.addSubnode(self.actionNodesSeparator)
|
||||
|
||||
for actionNode in self.actionNodes {
|
||||
self.addSubnode(actionNode)
|
||||
}
|
||||
self.actionNodes.last?.actionEnabled = true
|
||||
|
||||
for separatorNode in self.actionVerticalSeparators {
|
||||
self.addSubnode(separatorNode)
|
||||
}
|
||||
|
||||
self.inputFieldNode.updateHeight = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let _ = strongSelf.validLayout {
|
||||
strongSelf.requestLayout?(.animated(duration: 0.15, curve: .spring))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.updateTheme(theme)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable.dispose()
|
||||
}
|
||||
|
||||
var login: String {
|
||||
return self.inputFieldNode.text
|
||||
}
|
||||
|
||||
var password: String {
|
||||
return self.passwordFieldNode.text
|
||||
}
|
||||
|
||||
override func updateTheme(_ theme: AlertControllerTheme) {
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: Font.semibold(17.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
self.textNode.attributedText = NSAttributedString(string: self.text, font: Font.regular(13.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
|
||||
self.actionNodesSeparator.backgroundColor = theme.separatorColor
|
||||
for actionNode in self.actionNodes {
|
||||
actionNode.updateTheme(theme)
|
||||
}
|
||||
for separatorNode in self.actionVerticalSeparators {
|
||||
separatorNode.backgroundColor = theme.separatorColor
|
||||
}
|
||||
|
||||
if let size = self.validLayout {
|
||||
_ = self.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
override func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
var size = size
|
||||
size.width = min(size.width, 270.0)
|
||||
let measureSize = CGSize(width: size.width - 16.0 * 2.0, height: CGFloat.greatestFiniteMagnitude)
|
||||
|
||||
let hadValidLayout = self.validLayout != nil
|
||||
|
||||
self.validLayout = size
|
||||
|
||||
var origin: CGPoint = CGPoint(x: 0.0, y: 20.0)
|
||||
let spacing: CGFloat = 5.0
|
||||
|
||||
let titleSize = self.titleNode.measure(measureSize)
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: origin.y), size: titleSize))
|
||||
origin.y += titleSize.height + 4.0
|
||||
|
||||
let textSize = self.textNode.measure(measureSize)
|
||||
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: origin.y), size: textSize))
|
||||
origin.y += textSize.height + 6.0 + spacing
|
||||
|
||||
let actionButtonHeight: CGFloat = 44.0
|
||||
var minActionsWidth: CGFloat = 0.0
|
||||
let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count))
|
||||
let actionTitleInsets: CGFloat = 8.0
|
||||
|
||||
var effectiveActionLayout = TextAlertContentActionLayout.horizontal
|
||||
for actionNode in self.actionNodes {
|
||||
let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight))
|
||||
if case .horizontal = effectiveActionLayout, actionTitleSize.height > actionButtonHeight * 0.6667 {
|
||||
effectiveActionLayout = .vertical
|
||||
}
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
minActionsWidth += actionTitleSize.width + actionTitleInsets
|
||||
case .vertical:
|
||||
minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets)
|
||||
}
|
||||
}
|
||||
|
||||
let insets = UIEdgeInsets(top: 18.0, left: 18.0, bottom: 9.0, right: 18.0)
|
||||
|
||||
var contentWidth = max(titleSize.width, minActionsWidth)
|
||||
contentWidth = max(contentWidth, 234.0)
|
||||
|
||||
var actionsHeight: CGFloat = 0.0
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
actionsHeight = actionButtonHeight
|
||||
case .vertical:
|
||||
actionsHeight = actionButtonHeight * CGFloat(self.actionNodes.count)
|
||||
}
|
||||
|
||||
let resultWidth = contentWidth + insets.left + insets.right
|
||||
|
||||
let inputFieldWidth = resultWidth
|
||||
let inputFieldHeight = self.inputFieldNode.updateLayout(width: inputFieldWidth, transition: transition)
|
||||
let inputHeight = inputFieldHeight
|
||||
transition.updateFrame(node: self.inputFieldNode, frame: CGRect(x: 0.0, y: origin.y, width: resultWidth, height: inputFieldHeight))
|
||||
transition.updateAlpha(node: self.inputFieldNode, alpha: inputHeight > 0.0 ? 1.0 : 0.0)
|
||||
|
||||
let fieldSpacing: CGFloat = -11.0
|
||||
origin.y += inputFieldHeight + fieldSpacing
|
||||
|
||||
let passwordFieldHeight = self.passwordFieldNode.updateLayout(width: inputFieldWidth, transition: transition)
|
||||
transition.updateFrame(node: self.passwordFieldNode, frame: CGRect(x: 0.0, y: origin.y, width: resultWidth, height: passwordFieldHeight))
|
||||
|
||||
|
||||
let resultSize = CGSize(width: resultWidth, height: titleSize.height + textSize.height + spacing + inputHeight + fieldSpacing + passwordFieldHeight + actionsHeight + insets.top + insets.bottom)
|
||||
|
||||
transition.updateFrame(node: self.actionNodesSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||
|
||||
var actionOffset: CGFloat = 0.0
|
||||
let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count))
|
||||
var separatorIndex = -1
|
||||
var nodeIndex = 0
|
||||
for actionNode in self.actionNodes {
|
||||
if separatorIndex >= 0 {
|
||||
let separatorNode = self.actionVerticalSeparators[separatorIndex]
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: actionOffset - UIScreenPixel, y: resultSize.height - actionsHeight), size: CGSize(width: UIScreenPixel, height: actionsHeight - UIScreenPixel)))
|
||||
case .vertical:
|
||||
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||
}
|
||||
}
|
||||
separatorIndex += 1
|
||||
|
||||
let currentActionWidth: CGFloat
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
if nodeIndex == self.actionNodes.count - 1 {
|
||||
currentActionWidth = resultSize.width - actionOffset
|
||||
} else {
|
||||
currentActionWidth = actionWidth
|
||||
}
|
||||
case .vertical:
|
||||
currentActionWidth = resultSize.width
|
||||
}
|
||||
|
||||
let actionNodeFrame: CGRect
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
actionNodeFrame = CGRect(origin: CGPoint(x: actionOffset, y: resultSize.height - actionsHeight), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||
actionOffset += currentActionWidth
|
||||
case .vertical:
|
||||
actionNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||
actionOffset += actionButtonHeight
|
||||
}
|
||||
|
||||
transition.updateFrame(node: actionNode, frame: actionNodeFrame)
|
||||
|
||||
nodeIndex += 1
|
||||
}
|
||||
|
||||
if !hadValidLayout {
|
||||
self.inputFieldNode.activateInput()
|
||||
}
|
||||
|
||||
return resultSize
|
||||
}
|
||||
|
||||
func animateError() {
|
||||
self.inputFieldNode.layer.addShakeAnimation()
|
||||
self.hapticFeedback.error()
|
||||
}
|
||||
}
|
||||
|
||||
public func authController(sharedContext: SharedAccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, title: String, text: String, apply: @escaping ((String, String)?) -> Void) -> AlertController {
|
||||
let presentationData = updatedPresentationData?.initial ?? sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var dismissImpl: ((Bool) -> Void)?
|
||||
var applyImpl: (() -> Void)?
|
||||
|
||||
let actions: [TextAlertAction] = [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
dismissImpl?(true)
|
||||
apply(nil)
|
||||
}), TextAlertAction(type: .defaultAction, title: "Sign In", action: {
|
||||
dismissImpl?(true)
|
||||
applyImpl?()
|
||||
})]
|
||||
|
||||
let contentNode = AuthAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: presentationData.strings, actions: actions, title: title, text: text)
|
||||
contentNode.complete = {
|
||||
applyImpl?()
|
||||
}
|
||||
applyImpl = { [weak contentNode] in
|
||||
guard let contentNode = contentNode else {
|
||||
return
|
||||
}
|
||||
apply((contentNode.login, contentNode.password))
|
||||
}
|
||||
|
||||
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||
let presentationDataDisposable = (updatedPresentationData?.signal ?? sharedContext.presentationData).start(next: { [weak controller, weak contentNode] presentationData in
|
||||
controller?.theme = AlertControllerTheme(presentationData: presentationData)
|
||||
contentNode?.inputFieldNode.updateTheme(presentationData.theme)
|
||||
})
|
||||
controller.dismissed = { _ in
|
||||
presentationDataDisposable.dispose()
|
||||
}
|
||||
dismissImpl = { [weak controller] animated in
|
||||
contentNode.inputFieldNode.deactivateInput()
|
||||
if animated {
|
||||
controller?.dismissAnimated()
|
||||
} else {
|
||||
controller?.dismiss()
|
||||
}
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
|
||||
private final class ProgressAlertContentNode: AlertContentNode {
|
||||
private let theme: AlertControllerTheme
|
||||
private let strings: PresentationStrings
|
||||
|
||||
private let title: String
|
||||
var text: String {
|
||||
didSet {
|
||||
self.updateTheme(self.theme)
|
||||
}
|
||||
}
|
||||
|
||||
private let titleNode: ASTextNode
|
||||
private let textNode: ASTextNode
|
||||
|
||||
private let actionNodesSeparator: ASDisplayNode
|
||||
private let actionNodes: [TextAlertContentActionNode]
|
||||
private let actionVerticalSeparators: [ASDisplayNode]
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
private var validLayout: CGSize?
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
override var dismissOnOutsideTap: Bool {
|
||||
return self.isUserInteractionEnabled
|
||||
}
|
||||
|
||||
init(theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction], title: String, text: String) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.title = title
|
||||
self.text = text
|
||||
|
||||
self.titleNode = ASTextNode()
|
||||
self.titleNode.maximumNumberOfLines = 2
|
||||
|
||||
self.textNode = ASTextNode()
|
||||
self.textNode.maximumNumberOfLines = 2
|
||||
|
||||
self.actionNodesSeparator = ASDisplayNode()
|
||||
self.actionNodesSeparator.isLayerBacked = true
|
||||
|
||||
self.actionNodes = actions.map { action -> TextAlertContentActionNode in
|
||||
return TextAlertContentActionNode(theme: theme, action: action)
|
||||
}
|
||||
|
||||
var actionVerticalSeparators: [ASDisplayNode] = []
|
||||
if actions.count > 1 {
|
||||
for _ in 0 ..< actions.count - 1 {
|
||||
let separatorNode = ASDisplayNode()
|
||||
separatorNode.isLayerBacked = true
|
||||
actionVerticalSeparators.append(separatorNode)
|
||||
}
|
||||
}
|
||||
self.actionVerticalSeparators = actionVerticalSeparators
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.addSubnode(self.actionNodesSeparator)
|
||||
|
||||
for actionNode in self.actionNodes {
|
||||
self.addSubnode(actionNode)
|
||||
}
|
||||
self.actionNodes.last?.actionEnabled = true
|
||||
|
||||
for separatorNode in self.actionVerticalSeparators {
|
||||
self.addSubnode(separatorNode)
|
||||
}
|
||||
|
||||
|
||||
self.updateTheme(theme)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable.dispose()
|
||||
}
|
||||
|
||||
override func updateTheme(_ theme: AlertControllerTheme) {
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: Font.semibold(17.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
self.textNode.attributedText = NSAttributedString(string: self.text, font: Font.regular(13.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
|
||||
self.actionNodesSeparator.backgroundColor = theme.separatorColor
|
||||
for actionNode in self.actionNodes {
|
||||
actionNode.updateTheme(theme)
|
||||
}
|
||||
for separatorNode in self.actionVerticalSeparators {
|
||||
separatorNode.backgroundColor = theme.separatorColor
|
||||
}
|
||||
|
||||
if let size = self.validLayout {
|
||||
_ = self.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
override func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
var size = size
|
||||
size.width = min(size.width, 270.0)
|
||||
let measureSize = CGSize(width: size.width - 16.0 * 2.0, height: CGFloat.greatestFiniteMagnitude)
|
||||
|
||||
self.validLayout = size
|
||||
|
||||
var origin: CGPoint = CGPoint(x: 0.0, y: 20.0)
|
||||
let spacing: CGFloat = 5.0
|
||||
|
||||
let titleSize = self.titleNode.measure(measureSize)
|
||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: origin.y), size: titleSize))
|
||||
origin.y += titleSize.height + 4.0
|
||||
|
||||
let textSize = self.textNode.measure(measureSize)
|
||||
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: origin.y), size: textSize))
|
||||
origin.y += textSize.height + 6.0 + spacing
|
||||
|
||||
let actionButtonHeight: CGFloat = 44.0
|
||||
var minActionsWidth: CGFloat = 0.0
|
||||
let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count))
|
||||
let actionTitleInsets: CGFloat = 8.0
|
||||
|
||||
var effectiveActionLayout = TextAlertContentActionLayout.horizontal
|
||||
for actionNode in self.actionNodes {
|
||||
let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight))
|
||||
if case .horizontal = effectiveActionLayout, actionTitleSize.height > actionButtonHeight * 0.6667 {
|
||||
effectiveActionLayout = .vertical
|
||||
}
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
minActionsWidth += actionTitleSize.width + actionTitleInsets
|
||||
case .vertical:
|
||||
minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets)
|
||||
}
|
||||
}
|
||||
|
||||
let insets = UIEdgeInsets(top: 18.0, left: 18.0, bottom: 9.0, right: 18.0)
|
||||
|
||||
var contentWidth = max(titleSize.width, minActionsWidth)
|
||||
contentWidth = max(contentWidth, 234.0)
|
||||
|
||||
var actionsHeight: CGFloat = 0.0
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
actionsHeight = actionButtonHeight
|
||||
case .vertical:
|
||||
actionsHeight = actionButtonHeight * CGFloat(self.actionNodes.count)
|
||||
}
|
||||
|
||||
let resultWidth = contentWidth + insets.left + insets.right
|
||||
|
||||
let resultSize = CGSize(width: resultWidth, height: titleSize.height + textSize.height + spacing + actionsHeight + insets.top + insets.bottom)
|
||||
|
||||
transition.updateFrame(node: self.actionNodesSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||
|
||||
var actionOffset: CGFloat = 0.0
|
||||
let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count))
|
||||
var separatorIndex = -1
|
||||
var nodeIndex = 0
|
||||
for actionNode in self.actionNodes {
|
||||
if separatorIndex >= 0 {
|
||||
let separatorNode = self.actionVerticalSeparators[separatorIndex]
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: actionOffset - UIScreenPixel, y: resultSize.height - actionsHeight), size: CGSize(width: UIScreenPixel, height: actionsHeight - UIScreenPixel)))
|
||||
case .vertical:
|
||||
transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel)))
|
||||
}
|
||||
}
|
||||
separatorIndex += 1
|
||||
|
||||
let currentActionWidth: CGFloat
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
if nodeIndex == self.actionNodes.count - 1 {
|
||||
currentActionWidth = resultSize.width - actionOffset
|
||||
} else {
|
||||
currentActionWidth = actionWidth
|
||||
}
|
||||
case .vertical:
|
||||
currentActionWidth = resultSize.width
|
||||
}
|
||||
|
||||
let actionNodeFrame: CGRect
|
||||
switch effectiveActionLayout {
|
||||
case .horizontal:
|
||||
actionNodeFrame = CGRect(origin: CGPoint(x: actionOffset, y: resultSize.height - actionsHeight), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||
actionOffset += currentActionWidth
|
||||
case .vertical:
|
||||
actionNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset), size: CGSize(width: currentActionWidth, height: actionButtonHeight))
|
||||
actionOffset += actionButtonHeight
|
||||
}
|
||||
|
||||
transition.updateFrame(node: actionNode, frame: actionNodeFrame)
|
||||
|
||||
nodeIndex += 1
|
||||
}
|
||||
|
||||
return resultSize
|
||||
}
|
||||
}
|
||||
|
||||
public func progressAlertController(sharedContext: SharedAccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, title: String, cancel: @escaping () -> Void) -> (AlertController, (Int64, Int64) -> Void) {
|
||||
let presentationData = updatedPresentationData?.initial ?? sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var dismissImpl: ((Bool) -> Void)?
|
||||
var applyImpl: (() -> Void)?
|
||||
|
||||
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: "Cancel", action: {
|
||||
dismissImpl?(true)
|
||||
applyImpl?()
|
||||
})]
|
||||
|
||||
let contentNode = ProgressAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: presentationData.strings, actions: actions, title: "Downloading...", text: " ")
|
||||
|
||||
let updateProgress: (Int64, Int64) -> Void = { [weak contentNode] current, total in
|
||||
if let contentNode {
|
||||
contentNode.text = "\(dataSizeString(Int(current), formatting: DataSizeStringFormatting(presentationData: presentationData))) of \(dataSizeString(Int(total), formatting: DataSizeStringFormatting(presentationData: presentationData)))"
|
||||
}
|
||||
}
|
||||
applyImpl = {
|
||||
dismissImpl?(true)
|
||||
cancel()
|
||||
}
|
||||
|
||||
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||
let presentationDataDisposable = (updatedPresentationData?.signal ?? sharedContext.presentationData).start(next: { [weak controller] presentationData in
|
||||
controller?.theme = AlertControllerTheme(presentationData: presentationData)
|
||||
})
|
||||
controller.dismissed = { _ in
|
||||
presentationDataDisposable.dispose()
|
||||
}
|
||||
dismissImpl = { [weak controller] animated in
|
||||
if animated {
|
||||
controller?.dismissAnimated()
|
||||
} else {
|
||||
controller?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
return (controller, updateProgress)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,12 @@ public func combineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13
|
|||
}, initialValues: [:], queue: queue)
|
||||
}
|
||||
|
||||
public func combineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, E>(queue: Queue? = nil, _ s1: Signal<T1, E>, _ s2: Signal<T2, E>, _ s3: Signal<T3, E>, _ s4: Signal<T4, E>, _ s5: Signal<T5, E>, _ s6: Signal<T6, E>, _ s7: Signal<T7, E>, _ s8: Signal<T8, E>, _ s9: Signal<T9, E>, _ s10: Signal<T10, E>, _ s11: Signal<T11, E>, _ s12: Signal<T12, E>, _ s13: Signal<T13, E>, _ s14: Signal<T14, E>, _ s15: Signal<T15, E>, _ s16: Signal<T16, E>, _ s17: Signal<T17, E>, _ s18: Signal<T18, E>, _ s19: Signal<T19, E>, _ s20: Signal<T20, E>, _ s21: Signal<T21, E>, _ s22: Signal<T22, E>, _ s23: Signal<T23, E>, _ s24: Signal<T24, E>, _ s25: Signal<T25, E>, _ s26: Signal<T26, E>) -> Signal<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26), E> {
|
||||
return combineLatestAny([signalOfAny(s1), signalOfAny(s2), signalOfAny(s3), signalOfAny(s4), signalOfAny(s5), signalOfAny(s6), signalOfAny(s7), signalOfAny(s8), signalOfAny(s9), signalOfAny(s10), signalOfAny(s11), signalOfAny(s12), signalOfAny(s13), signalOfAny(s14), signalOfAny(s15), signalOfAny(s16), signalOfAny(s17), signalOfAny(s18), signalOfAny(s19), signalOfAny(s20), signalOfAny(s21), signalOfAny(s22), signalOfAny(s23), signalOfAny(s24), signalOfAny(s25), signalOfAny(s26)], combine: { values in
|
||||
return (values[0] as! T1, values[1] as! T2, values[2] as! T3, values[3] as! T4, values[4] as! T5, values[5] as! T6, values[6] as! T7, values[7] as! T8, values[8] as! T9, values[9] as! T10, values[10] as! T11, values[11] as! T12, values[12] as! T13, values[13] as! T14, values[14] as! T15, values[15] as! T16, values[16] as! T17, values[17] as! T18, values[18] as! T19, values[19] as! T20, values[20] as! T21, values[21] as! T22, values[22] as! T23, values[23] as! T24, values[24] as! T25, values[25] as! T26)
|
||||
}, initialValues: [:], queue: queue)
|
||||
}
|
||||
|
||||
public func combineLatest<T, E>(queue: Queue? = nil, _ signals: [Signal<T, E>]) -> Signal<[T], E> {
|
||||
if signals.count == 0 {
|
||||
return single([T](), E.self)
|
||||
|
|
|
|||
|
|
@ -378,6 +378,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
|
||||
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
|
||||
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
|
||||
dict[634962392] = { return Api.InputInvoice.parse_inputInvoiceStarGift($0) }
|
||||
dict[1710230755] = { return Api.InputInvoice.parse_inputInvoiceStars($0) }
|
||||
dict[-122978821] = { return Api.InputMedia.parse_inputMediaContact($0) }
|
||||
dict[-428884101] = { return Api.InputMedia.parse_inputMediaDice($0) }
|
||||
|
|
@ -573,6 +574,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1434950843] = { return Api.MessageAction.parse_messageActionSetChatTheme($0) }
|
||||
dict[1348510708] = { return Api.MessageAction.parse_messageActionSetChatWallPaper($0) }
|
||||
dict[1007897979] = { return Api.MessageAction.parse_messageActionSetMessagesTTL($0) }
|
||||
dict[-1682706620] = { return Api.MessageAction.parse_messageActionStarGift($0) }
|
||||
dict[1474192222] = { return Api.MessageAction.parse_messageActionSuggestProfilePhoto($0) }
|
||||
dict[228168278] = { return Api.MessageAction.parse_messageActionTopicCreate($0) }
|
||||
dict[-1064024032] = { return Api.MessageAction.parse_messageActionTopicEdit($0) }
|
||||
|
|
@ -888,6 +890,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) }
|
||||
dict[1301522832] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||
dict[-1365150482] = { return Api.StarGift.parse_starGift($0) }
|
||||
dict[1577421297] = { return Api.StarsGiftOption.parse_starsGiftOption($0) }
|
||||
dict[-1798404822] = { return Api.StarsGiveawayOption.parse_starsGiveawayOption($0) }
|
||||
dict[1411605001] = { return Api.StarsGiveawayWinnersOption.parse_starsGiveawayWinnersOption($0) }
|
||||
|
|
@ -1100,9 +1103,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1831650802] = { return Api.UrlAuthResult.parse_urlAuthResultRequest($0) }
|
||||
dict[-2093920310] = { return Api.User.parse_user($0) }
|
||||
dict[-742634630] = { return Api.User.parse_userEmpty($0) }
|
||||
dict[-862357728] = { return Api.UserFull.parse_userFull($0) }
|
||||
dict[525919081] = { return Api.UserFull.parse_userFull($0) }
|
||||
dict[-2100168954] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
|
||||
dict[1326562017] = { return Api.UserProfilePhoto.parse_userProfilePhotoEmpty($0) }
|
||||
dict[-291202450] = { return Api.UserStarGift.parse_userStarGift($0) }
|
||||
dict[164646985] = { return Api.UserStatus.parse_userStatusEmpty($0) }
|
||||
dict[1703516023] = { return Api.UserStatus.parse_userStatusLastMonth($0) }
|
||||
dict[1410997530] = { return Api.UserStatus.parse_userStatusLastWeek($0) }
|
||||
|
|
@ -1333,16 +1337,20 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1130879648] = { return Api.payments.GiveawayInfo.parse_giveawayInfo($0) }
|
||||
dict[-512366993] = { return Api.payments.GiveawayInfo.parse_giveawayInfoResults($0) }
|
||||
dict[-1610250415] = { return Api.payments.PaymentForm.parse_paymentForm($0) }
|
||||
dict[-1272590367] = { return Api.payments.PaymentForm.parse_paymentFormStarGift($0) }
|
||||
dict[2079764828] = { return Api.payments.PaymentForm.parse_paymentFormStars($0) }
|
||||
dict[1891958275] = { return Api.payments.PaymentReceipt.parse_paymentReceipt($0) }
|
||||
dict[-625215430] = { return Api.payments.PaymentReceipt.parse_paymentReceiptStars($0) }
|
||||
dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) }
|
||||
dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) }
|
||||
dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
|
||||
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[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) }
|
||||
dict[-1141231252] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
|
||||
dict[1801827607] = { return Api.payments.UserStarGifts.parse_userStarGifts($0) }
|
||||
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
|
||||
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
|
||||
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
|
||||
|
|
@ -2013,6 +2021,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.SponsoredMessageReportOption:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarGift:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarsGiftOption:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.StarsGiveawayOption:
|
||||
|
|
@ -2093,6 +2103,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.UserProfilePhoto:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.UserStarGift:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.UserStatus:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.Username:
|
||||
|
|
@ -2385,6 +2397,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.SavedInfo:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarGifts:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarsRevenueAdsAccountUrl:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarsRevenueStats:
|
||||
|
|
@ -2393,6 +2407,8 @@ public extension Api {
|
|||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.StarsStatus:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.UserStarGifts:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.payments.ValidatedRequestedInfo:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.phone.ExportedGroupCallInvite:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ public extension Api {
|
|||
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
|
||||
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
|
||||
case inputInvoiceSlug(slug: String)
|
||||
case inputInvoiceStarGift(flags: Int32, userId: Api.InputUser, giftId: Int64, message: Api.TextWithEntities?)
|
||||
case inputInvoiceStars(purpose: Api.InputStorePaymentPurpose)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
|
|
@ -34,6 +35,15 @@ public extension Api {
|
|||
}
|
||||
serializeString(slug, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .inputInvoiceStarGift(let flags, let userId, let giftId, let message):
|
||||
if boxed {
|
||||
buffer.appendInt32(634962392)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
userId.serialize(buffer, true)
|
||||
serializeInt64(giftId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {message!.serialize(buffer, true)}
|
||||
break
|
||||
case .inputInvoiceStars(let purpose):
|
||||
if boxed {
|
||||
buffer.appendInt32(1710230755)
|
||||
|
|
@ -53,6 +63,8 @@ public extension Api {
|
|||
return ("inputInvoicePremiumGiftCode", [("purpose", purpose as Any), ("option", option as Any)])
|
||||
case .inputInvoiceSlug(let slug):
|
||||
return ("inputInvoiceSlug", [("slug", slug as Any)])
|
||||
case .inputInvoiceStarGift(let flags, let userId, let giftId, let message):
|
||||
return ("inputInvoiceStarGift", [("flags", flags as Any), ("userId", userId as Any), ("giftId", giftId as Any), ("message", message as Any)])
|
||||
case .inputInvoiceStars(let purpose):
|
||||
return ("inputInvoiceStars", [("purpose", purpose as Any)])
|
||||
}
|
||||
|
|
@ -114,6 +126,30 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputInvoiceStarGift(_ reader: BufferReader) -> InputInvoice? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.InputUser?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.InputUser
|
||||
}
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Api.TextWithEntities?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.InputInvoice.inputInvoiceStarGift(flags: _1!, userId: _2!, giftId: _3!, message: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_inputInvoiceStars(_ reader: BufferReader) -> InputInvoice? {
|
||||
var _1: Api.InputStorePaymentPurpose?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
|
|||
|
|
@ -1009,6 +1009,7 @@ public extension Api {
|
|||
case messageActionSetChatTheme(emoticon: String)
|
||||
case messageActionSetChatWallPaper(flags: Int32, wallpaper: Api.WallPaper)
|
||||
case messageActionSetMessagesTTL(flags: Int32, period: Int32, autoSettingFrom: Int64?)
|
||||
case messageActionStarGift(flags: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, convertStars: Int64)
|
||||
case messageActionSuggestProfilePhoto(photo: Api.Photo)
|
||||
case messageActionTopicCreate(flags: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?)
|
||||
case messageActionTopicEdit(flags: Int32, title: String?, iconEmojiId: Int64?, closed: Api.Bool?, hidden: Api.Bool?)
|
||||
|
|
@ -1350,6 +1351,15 @@ public extension Api {
|
|||
serializeInt32(period, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(autoSettingFrom!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1682706620)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
gift.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 1) != 0 {message!.serialize(buffer, true)}
|
||||
serializeInt64(convertStars, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageActionSuggestProfilePhoto(let photo):
|
||||
if boxed {
|
||||
buffer.appendInt32(1474192222)
|
||||
|
|
@ -1475,6 +1485,8 @@ public extension Api {
|
|||
return ("messageActionSetChatWallPaper", [("flags", flags as Any), ("wallpaper", wallpaper as Any)])
|
||||
case .messageActionSetMessagesTTL(let flags, let period, let autoSettingFrom):
|
||||
return ("messageActionSetMessagesTTL", [("flags", flags as Any), ("period", period as Any), ("autoSettingFrom", autoSettingFrom as Any)])
|
||||
case .messageActionStarGift(let flags, let gift, let message, let convertStars):
|
||||
return ("messageActionStarGift", [("flags", flags as Any), ("gift", gift as Any), ("message", message as Any), ("convertStars", convertStars as Any)])
|
||||
case .messageActionSuggestProfilePhoto(let photo):
|
||||
return ("messageActionSuggestProfilePhoto", [("photo", photo as Any)])
|
||||
case .messageActionTopicCreate(let flags, let title, let iconColor, let iconEmojiId):
|
||||
|
|
@ -2106,6 +2118,30 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionStarGift(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.StarGift?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarGift
|
||||
}
|
||||
var _3: Api.TextWithEntities?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
||||
} }
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.MessageAction.messageActionStarGift(flags: _1!, gift: _2!, message: _3, convertStars: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageActionSuggestProfilePhoto(_ reader: BufferReader) -> MessageAction? {
|
||||
var _1: Api.Photo?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
|
|||
|
|
@ -572,6 +572,68 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarGift: TypeConstructorDescription {
|
||||
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, convertStars: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let convertStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1365150482)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
sticker.serialize(buffer, true)
|
||||
serializeInt64(stars, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(availabilityRemains!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(availabilityTotal!, buffer: buffer, boxed: false)}
|
||||
serializeInt64(convertStars, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let convertStars):
|
||||
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("convertStars", convertStars as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starGift(_ reader: BufferReader) -> StarGift? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Api.Document?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
}
|
||||
var _4: Int64?
|
||||
_4 = reader.readInt64()
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt32() }
|
||||
var _7: Int64?
|
||||
_7 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.StarGift.starGift(flags: _1!, id: _2!, sticker: _3!, stars: _4!, availabilityRemains: _5, availabilityTotal: _6, convertStars: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsGiftOption: TypeConstructorDescription {
|
||||
case starsGiftOption(flags: Int32, stars: Int64, storeProduct: String?, currency: String, amount: Int64)
|
||||
|
|
@ -1040,113 +1102,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StarsTransactionPeer: TypeConstructorDescription {
|
||||
case starsTransactionPeer(peer: Api.Peer)
|
||||
case starsTransactionPeerAds
|
||||
case starsTransactionPeerAppStore
|
||||
case starsTransactionPeerFragment
|
||||
case starsTransactionPeerPlayMarket
|
||||
case starsTransactionPeerPremiumBot
|
||||
case starsTransactionPeerUnsupported
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsTransactionPeer(let peer):
|
||||
if boxed {
|
||||
buffer.appendInt32(-670195363)
|
||||
}
|
||||
peer.serialize(buffer, true)
|
||||
break
|
||||
case .starsTransactionPeerAds:
|
||||
if boxed {
|
||||
buffer.appendInt32(1617438738)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerAppStore:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1269320843)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerFragment:
|
||||
if boxed {
|
||||
buffer.appendInt32(-382740222)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerPlayMarket:
|
||||
if boxed {
|
||||
buffer.appendInt32(2069236235)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerPremiumBot:
|
||||
if boxed {
|
||||
buffer.appendInt32(621656824)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerUnsupported:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1779253276)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsTransactionPeer(let peer):
|
||||
return ("starsTransactionPeer", [("peer", peer as Any)])
|
||||
case .starsTransactionPeerAds:
|
||||
return ("starsTransactionPeerAds", [])
|
||||
case .starsTransactionPeerAppStore:
|
||||
return ("starsTransactionPeerAppStore", [])
|
||||
case .starsTransactionPeerFragment:
|
||||
return ("starsTransactionPeerFragment", [])
|
||||
case .starsTransactionPeerPlayMarket:
|
||||
return ("starsTransactionPeerPlayMarket", [])
|
||||
case .starsTransactionPeerPremiumBot:
|
||||
return ("starsTransactionPeerPremiumBot", [])
|
||||
case .starsTransactionPeerUnsupported:
|
||||
return ("starsTransactionPeerUnsupported", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsTransactionPeer(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
var _1: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeer(peer: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_starsTransactionPeerAds(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerAds
|
||||
}
|
||||
public static func parse_starsTransactionPeerAppStore(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerAppStore
|
||||
}
|
||||
public static func parse_starsTransactionPeerFragment(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerFragment
|
||||
}
|
||||
public static func parse_starsTransactionPeerPlayMarket(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerPlayMarket
|
||||
}
|
||||
public static func parse_starsTransactionPeerPremiumBot(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerPremiumBot
|
||||
}
|
||||
public static func parse_starsTransactionPeerUnsupported(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerUnsupported
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,113 @@
|
|||
public extension Api {
|
||||
enum StarsTransactionPeer: TypeConstructorDescription {
|
||||
case starsTransactionPeer(peer: Api.Peer)
|
||||
case starsTransactionPeerAds
|
||||
case starsTransactionPeerAppStore
|
||||
case starsTransactionPeerFragment
|
||||
case starsTransactionPeerPlayMarket
|
||||
case starsTransactionPeerPremiumBot
|
||||
case starsTransactionPeerUnsupported
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsTransactionPeer(let peer):
|
||||
if boxed {
|
||||
buffer.appendInt32(-670195363)
|
||||
}
|
||||
peer.serialize(buffer, true)
|
||||
break
|
||||
case .starsTransactionPeerAds:
|
||||
if boxed {
|
||||
buffer.appendInt32(1617438738)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerAppStore:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1269320843)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerFragment:
|
||||
if boxed {
|
||||
buffer.appendInt32(-382740222)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerPlayMarket:
|
||||
if boxed {
|
||||
buffer.appendInt32(2069236235)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerPremiumBot:
|
||||
if boxed {
|
||||
buffer.appendInt32(621656824)
|
||||
}
|
||||
|
||||
break
|
||||
case .starsTransactionPeerUnsupported:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1779253276)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsTransactionPeer(let peer):
|
||||
return ("starsTransactionPeer", [("peer", peer as Any)])
|
||||
case .starsTransactionPeerAds:
|
||||
return ("starsTransactionPeerAds", [])
|
||||
case .starsTransactionPeerAppStore:
|
||||
return ("starsTransactionPeerAppStore", [])
|
||||
case .starsTransactionPeerFragment:
|
||||
return ("starsTransactionPeerFragment", [])
|
||||
case .starsTransactionPeerPlayMarket:
|
||||
return ("starsTransactionPeerPlayMarket", [])
|
||||
case .starsTransactionPeerPremiumBot:
|
||||
return ("starsTransactionPeerPremiumBot", [])
|
||||
case .starsTransactionPeerUnsupported:
|
||||
return ("starsTransactionPeerUnsupported", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsTransactionPeer(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
var _1: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeer(peer: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_starsTransactionPeerAds(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerAds
|
||||
}
|
||||
public static func parse_starsTransactionPeerAppStore(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerAppStore
|
||||
}
|
||||
public static func parse_starsTransactionPeerFragment(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerFragment
|
||||
}
|
||||
public static func parse_starsTransactionPeerPlayMarket(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerPlayMarket
|
||||
}
|
||||
public static func parse_starsTransactionPeerPremiumBot(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerPremiumBot
|
||||
}
|
||||
public static func parse_starsTransactionPeerUnsupported(_ reader: BufferReader) -> StarsTransactionPeer? {
|
||||
return Api.StarsTransactionPeer.starsTransactionPeerUnsupported
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StatsAbsValueAndPrev: TypeConstructorDescription {
|
||||
case statsAbsValueAndPrev(current: Double, previous: Double)
|
||||
|
|
@ -1056,367 +1166,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum StoryView: TypeConstructorDescription {
|
||||
case storyView(flags: Int32, userId: Int64, date: Int32, reaction: Api.Reaction?)
|
||||
case storyViewPublicForward(flags: Int32, message: Api.Message)
|
||||
case storyViewPublicRepost(flags: Int32, peerId: Api.Peer, story: Api.StoryItem)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyView(let flags, let userId, let date, let reaction):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1329730875)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(userId, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {reaction!.serialize(buffer, true)}
|
||||
break
|
||||
case .storyViewPublicForward(let flags, let message):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1870436597)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
message.serialize(buffer, true)
|
||||
break
|
||||
case .storyViewPublicRepost(let flags, let peerId, let story):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1116418231)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
peerId.serialize(buffer, true)
|
||||
story.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyView(let flags, let userId, let date, let reaction):
|
||||
return ("storyView", [("flags", flags as Any), ("userId", userId as Any), ("date", date as Any), ("reaction", reaction as Any)])
|
||||
case .storyViewPublicForward(let flags, let message):
|
||||
return ("storyViewPublicForward", [("flags", flags as Any), ("message", message as Any)])
|
||||
case .storyViewPublicRepost(let flags, let peerId, let story):
|
||||
return ("storyViewPublicRepost", [("flags", flags as Any), ("peerId", peerId as Any), ("story", story as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyView(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Api.Reaction?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryView.storyView(flags: _1!, userId: _2!, date: _3!, reaction: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyViewPublicForward(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Message?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Message
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.StoryView.storyViewPublicForward(flags: _1!, message: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyViewPublicRepost(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _3: Api.StoryItem?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StoryItem
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.StoryView.storyViewPublicRepost(flags: _1!, peerId: _2!, story: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StoryViews: TypeConstructorDescription {
|
||||
case storyViews(flags: Int32, viewsCount: Int32, forwardsCount: Int32?, reactions: [Api.ReactionCount]?, reactionsCount: Int32?, recentViewers: [Int64]?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyViews(let flags, let viewsCount, let forwardsCount, let reactions, let reactionsCount, let recentViewers):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1923523370)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(viewsCount, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(forwardsCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions!.count))
|
||||
for item in reactions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(reactionsCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(recentViewers!.count))
|
||||
for item in recentViewers! {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyViews(let flags, let viewsCount, let forwardsCount, let reactions, let reactionsCount, let recentViewers):
|
||||
return ("storyViews", [("flags", flags as Any), ("viewsCount", viewsCount as Any), ("forwardsCount", forwardsCount as Any), ("reactions", reactions as Any), ("reactionsCount", reactionsCount as Any), ("recentViewers", recentViewers as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyViews(_ reader: BufferReader) -> StoryViews? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
||||
var _4: [Api.ReactionCount]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ReactionCount.self)
|
||||
} }
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Int64]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 3) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.StoryViews.storyViews(flags: _1!, viewsCount: _2!, forwardsCount: _3, reactions: _4, reactionsCount: _5, recentViewers: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum TextWithEntities: TypeConstructorDescription {
|
||||
case textWithEntities(text: String, entities: [Api.MessageEntity])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .textWithEntities(let text, let entities):
|
||||
if boxed {
|
||||
buffer.appendInt32(1964978502)
|
||||
}
|
||||
serializeString(text, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities.count))
|
||||
for item in entities {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .textWithEntities(let text, let entities):
|
||||
return ("textWithEntities", [("text", text as Any), ("entities", entities as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_textWithEntities(_ reader: BufferReader) -> TextWithEntities? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: [Api.MessageEntity]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.TextWithEntities.textWithEntities(text: _1!, entities: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Theme: TypeConstructorDescription {
|
||||
case theme(flags: Int32, id: Int64, accessHash: Int64, slug: String, title: String, document: Api.Document?, settings: [Api.ThemeSettings]?, emoticon: String?, installsCount: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let emoticon, let installsCount):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1609668650)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||
serializeString(slug, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {document!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(settings!.count))
|
||||
for item in settings! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeString(emoticon!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(installsCount!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let emoticon, let installsCount):
|
||||
return ("theme", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("slug", slug as Any), ("title", title as Any), ("document", document as Any), ("settings", settings as Any), ("emoticon", emoticon as Any), ("installsCount", installsCount as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_theme(_ reader: BufferReader) -> Theme? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
var _5: String?
|
||||
_5 = parseString(reader)
|
||||
var _6: Api.Document?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _7: [Api.ThemeSettings]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ThemeSettings.self)
|
||||
} }
|
||||
var _8: String?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_8 = parseString(reader) }
|
||||
var _9: Int32?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_9 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 6) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 4) == 0) || _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.Theme.theme(flags: _1!, id: _2!, accessHash: _3!, slug: _4!, title: _5!, document: _6, settings: _7, emoticon: _8, installsCount: _9)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum ThemeSettings: TypeConstructorDescription {
|
||||
case themeSettings(flags: Int32, baseTheme: Api.BaseTheme, accentColor: Int32, outboxAccentColor: Int32?, messageColors: [Int32]?, wallpaper: Api.WallPaper?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .themeSettings(let flags, let baseTheme, let accentColor, let outboxAccentColor, let messageColors, let wallpaper):
|
||||
if boxed {
|
||||
buffer.appendInt32(-94849324)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
baseTheme.serialize(buffer, true)
|
||||
serializeInt32(accentColor, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(outboxAccentColor!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messageColors!.count))
|
||||
for item in messageColors! {
|
||||
serializeInt32(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 1) != 0 {wallpaper!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .themeSettings(let flags, let baseTheme, let accentColor, let outboxAccentColor, let messageColors, let wallpaper):
|
||||
return ("themeSettings", [("flags", flags as Any), ("baseTheme", baseTheme as Any), ("accentColor", accentColor as Any), ("outboxAccentColor", outboxAccentColor as Any), ("messageColors", messageColors as Any), ("wallpaper", wallpaper as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_themeSettings(_ reader: BufferReader) -> ThemeSettings? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.BaseTheme?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.BaseTheme
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Int32]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||
} }
|
||||
var _6: Api.WallPaper?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.WallPaper
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 3) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.ThemeSettings.themeSettings(flags: _1!, baseTheme: _2!, accentColor: _3!, outboxAccentColor: _4, messageColors: _5, wallpaper: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,367 @@
|
|||
public extension Api {
|
||||
indirect enum StoryView: TypeConstructorDescription {
|
||||
case storyView(flags: Int32, userId: Int64, date: Int32, reaction: Api.Reaction?)
|
||||
case storyViewPublicForward(flags: Int32, message: Api.Message)
|
||||
case storyViewPublicRepost(flags: Int32, peerId: Api.Peer, story: Api.StoryItem)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyView(let flags, let userId, let date, let reaction):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1329730875)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(userId, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {reaction!.serialize(buffer, true)}
|
||||
break
|
||||
case .storyViewPublicForward(let flags, let message):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1870436597)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
message.serialize(buffer, true)
|
||||
break
|
||||
case .storyViewPublicRepost(let flags, let peerId, let story):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1116418231)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
peerId.serialize(buffer, true)
|
||||
story.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyView(let flags, let userId, let date, let reaction):
|
||||
return ("storyView", [("flags", flags as Any), ("userId", userId as Any), ("date", date as Any), ("reaction", reaction as Any)])
|
||||
case .storyViewPublicForward(let flags, let message):
|
||||
return ("storyViewPublicForward", [("flags", flags as Any), ("message", message as Any)])
|
||||
case .storyViewPublicRepost(let flags, let peerId, let story):
|
||||
return ("storyViewPublicRepost", [("flags", flags as Any), ("peerId", peerId as Any), ("story", story as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyView(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Api.Reaction?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.StoryView.storyView(flags: _1!, userId: _2!, date: _3!, reaction: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyViewPublicForward(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Message?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Message
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.StoryView.storyViewPublicForward(flags: _1!, message: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_storyViewPublicRepost(_ reader: BufferReader) -> StoryView? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _3: Api.StoryItem?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StoryItem
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.StoryView.storyViewPublicRepost(flags: _1!, peerId: _2!, story: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum StoryViews: TypeConstructorDescription {
|
||||
case storyViews(flags: Int32, viewsCount: Int32, forwardsCount: Int32?, reactions: [Api.ReactionCount]?, reactionsCount: Int32?, recentViewers: [Int64]?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .storyViews(let flags, let viewsCount, let forwardsCount, let reactions, let reactionsCount, let recentViewers):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1923523370)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(viewsCount, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(forwardsCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(reactions!.count))
|
||||
for item in reactions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(reactionsCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(recentViewers!.count))
|
||||
for item in recentViewers! {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .storyViews(let flags, let viewsCount, let forwardsCount, let reactions, let reactionsCount, let recentViewers):
|
||||
return ("storyViews", [("flags", flags as Any), ("viewsCount", viewsCount as Any), ("forwardsCount", forwardsCount as Any), ("reactions", reactions as Any), ("reactionsCount", reactionsCount as Any), ("recentViewers", recentViewers as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_storyViews(_ reader: BufferReader) -> StoryViews? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
||||
var _4: [Api.ReactionCount]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ReactionCount.self)
|
||||
} }
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Int64]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 3) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.StoryViews.storyViews(flags: _1!, viewsCount: _2!, forwardsCount: _3, reactions: _4, reactionsCount: _5, recentViewers: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum TextWithEntities: TypeConstructorDescription {
|
||||
case textWithEntities(text: String, entities: [Api.MessageEntity])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .textWithEntities(let text, let entities):
|
||||
if boxed {
|
||||
buffer.appendInt32(1964978502)
|
||||
}
|
||||
serializeString(text, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(entities.count))
|
||||
for item in entities {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .textWithEntities(let text, let entities):
|
||||
return ("textWithEntities", [("text", text as Any), ("entities", entities as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_textWithEntities(_ reader: BufferReader) -> TextWithEntities? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: [Api.MessageEntity]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.TextWithEntities.textWithEntities(text: _1!, entities: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Theme: TypeConstructorDescription {
|
||||
case theme(flags: Int32, id: Int64, accessHash: Int64, slug: String, title: String, document: Api.Document?, settings: [Api.ThemeSettings]?, emoticon: String?, installsCount: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let emoticon, let installsCount):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1609668650)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||
serializeString(slug, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 2) != 0 {document!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(settings!.count))
|
||||
for item in settings! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeString(emoticon!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(installsCount!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .theme(let flags, let id, let accessHash, let slug, let title, let document, let settings, let emoticon, let installsCount):
|
||||
return ("theme", [("flags", flags as Any), ("id", id as Any), ("accessHash", accessHash as Any), ("slug", slug as Any), ("title", title as Any), ("document", document as Any), ("settings", settings as Any), ("emoticon", emoticon as Any), ("installsCount", installsCount as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_theme(_ reader: BufferReader) -> Theme? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
var _5: String?
|
||||
_5 = parseString(reader)
|
||||
var _6: Api.Document?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _7: [Api.ThemeSettings]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ThemeSettings.self)
|
||||
} }
|
||||
var _8: String?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_8 = parseString(reader) }
|
||||
var _9: Int32?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_9 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 6) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 4) == 0) || _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.Theme.theme(flags: _1!, id: _2!, accessHash: _3!, slug: _4!, title: _5!, document: _6, settings: _7, emoticon: _8, installsCount: _9)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum ThemeSettings: TypeConstructorDescription {
|
||||
case themeSettings(flags: Int32, baseTheme: Api.BaseTheme, accentColor: Int32, outboxAccentColor: Int32?, messageColors: [Int32]?, wallpaper: Api.WallPaper?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .themeSettings(let flags, let baseTheme, let accentColor, let outboxAccentColor, let messageColors, let wallpaper):
|
||||
if boxed {
|
||||
buffer.appendInt32(-94849324)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
baseTheme.serialize(buffer, true)
|
||||
serializeInt32(accentColor, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(outboxAccentColor!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messageColors!.count))
|
||||
for item in messageColors! {
|
||||
serializeInt32(item, buffer: buffer, boxed: false)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 1) != 0 {wallpaper!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .themeSettings(let flags, let baseTheme, let accentColor, let outboxAccentColor, let messageColors, let wallpaper):
|
||||
return ("themeSettings", [("flags", flags as Any), ("baseTheme", baseTheme as Any), ("accentColor", accentColor as Any), ("outboxAccentColor", outboxAccentColor as Any), ("messageColors", messageColors as Any), ("wallpaper", wallpaper as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_themeSettings(_ reader: BufferReader) -> ThemeSettings? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.BaseTheme?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.BaseTheme
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_4 = reader.readInt32() }
|
||||
var _5: [Int32]?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||
} }
|
||||
var _6: Api.WallPaper?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.WallPaper
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 3) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.ThemeSettings.themeSettings(flags: _1!, baseTheme: _2!, accentColor: _3!, outboxAccentColor: _4, messageColors: _5, wallpaper: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Timezone: TypeConstructorDescription {
|
||||
case timezone(id: String, name: String, utcOffset: Int32)
|
||||
|
|
|
|||
|
|
@ -606,13 +606,13 @@ public extension Api {
|
|||
}
|
||||
public extension Api {
|
||||
enum UserFull: TypeConstructorDescription {
|
||||
case userFull(flags: Int32, flags2: Int32, id: Int64, about: String?, settings: Api.PeerSettings, personalPhoto: Api.Photo?, profilePhoto: Api.Photo?, fallbackPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?, botGroupAdminRights: Api.ChatAdminRights?, botBroadcastAdminRights: Api.ChatAdminRights?, premiumGifts: [Api.PremiumGiftOption]?, wallpaper: Api.WallPaper?, stories: Api.PeerStories?, businessWorkHours: Api.BusinessWorkHours?, businessLocation: Api.BusinessLocation?, businessGreetingMessage: Api.BusinessGreetingMessage?, businessAwayMessage: Api.BusinessAwayMessage?, businessIntro: Api.BusinessIntro?, birthday: Api.Birthday?, personalChannelId: Int64?, personalChannelMessage: Int32?)
|
||||
case userFull(flags: Int32, flags2: Int32, id: Int64, about: String?, settings: Api.PeerSettings, personalPhoto: Api.Photo?, profilePhoto: Api.Photo?, fallbackPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?, botGroupAdminRights: Api.ChatAdminRights?, botBroadcastAdminRights: Api.ChatAdminRights?, premiumGifts: [Api.PremiumGiftOption]?, wallpaper: Api.WallPaper?, stories: Api.PeerStories?, businessWorkHours: Api.BusinessWorkHours?, businessLocation: Api.BusinessLocation?, businessGreetingMessage: Api.BusinessGreetingMessage?, businessAwayMessage: Api.BusinessAwayMessage?, businessIntro: Api.BusinessIntro?, birthday: Api.Birthday?, personalChannelId: Int64?, personalChannelMessage: Int32?, stargiftsCount: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation, let businessGreetingMessage, let businessAwayMessage, let businessIntro, let birthday, let personalChannelId, let personalChannelMessage):
|
||||
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation, let businessGreetingMessage, let businessAwayMessage, let businessIntro, let birthday, let personalChannelId, let personalChannelMessage, let stargiftsCount):
|
||||
if boxed {
|
||||
buffer.appendInt32(-862357728)
|
||||
buffer.appendInt32(525919081)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(flags2, buffer: buffer, boxed: false)
|
||||
|
|
@ -647,14 +647,15 @@ public extension Api {
|
|||
if Int(flags2) & Int(1 << 5) != 0 {birthday!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 6) != 0 {serializeInt64(personalChannelId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags2) & Int(1 << 6) != 0 {serializeInt32(personalChannelMessage!, buffer: buffer, boxed: false)}
|
||||
if Int(flags2) & Int(1 << 8) != 0 {serializeInt32(stargiftsCount!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation, let businessGreetingMessage, let businessAwayMessage, let businessIntro, let birthday, let personalChannelId, let personalChannelMessage):
|
||||
return ("userFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("settings", settings as Any), ("personalPhoto", personalPhoto as Any), ("profilePhoto", profilePhoto as Any), ("fallbackPhoto", fallbackPhoto as Any), ("notifySettings", notifySettings as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("commonChatsCount", commonChatsCount as Any), ("folderId", folderId as Any), ("ttlPeriod", ttlPeriod as Any), ("themeEmoticon", themeEmoticon as Any), ("privateForwardName", privateForwardName as Any), ("botGroupAdminRights", botGroupAdminRights as Any), ("botBroadcastAdminRights", botBroadcastAdminRights as Any), ("premiumGifts", premiumGifts as Any), ("wallpaper", wallpaper as Any), ("stories", stories as Any), ("businessWorkHours", businessWorkHours as Any), ("businessLocation", businessLocation as Any), ("businessGreetingMessage", businessGreetingMessage as Any), ("businessAwayMessage", businessAwayMessage as Any), ("businessIntro", businessIntro as Any), ("birthday", birthday as Any), ("personalChannelId", personalChannelId as Any), ("personalChannelMessage", personalChannelMessage as Any)])
|
||||
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation, let businessGreetingMessage, let businessAwayMessage, let businessIntro, let birthday, let personalChannelId, let personalChannelMessage, let stargiftsCount):
|
||||
return ("userFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("settings", settings as Any), ("personalPhoto", personalPhoto as Any), ("profilePhoto", profilePhoto as Any), ("fallbackPhoto", fallbackPhoto as Any), ("notifySettings", notifySettings as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("commonChatsCount", commonChatsCount as Any), ("folderId", folderId as Any), ("ttlPeriod", ttlPeriod as Any), ("themeEmoticon", themeEmoticon as Any), ("privateForwardName", privateForwardName as Any), ("botGroupAdminRights", botGroupAdminRights as Any), ("botBroadcastAdminRights", botBroadcastAdminRights as Any), ("premiumGifts", premiumGifts as Any), ("wallpaper", wallpaper as Any), ("stories", stories as Any), ("businessWorkHours", businessWorkHours as Any), ("businessLocation", businessLocation as Any), ("businessGreetingMessage", businessGreetingMessage as Any), ("businessAwayMessage", businessAwayMessage as Any), ("businessIntro", businessIntro as Any), ("birthday", birthday as Any), ("personalChannelId", personalChannelId as Any), ("personalChannelMessage", personalChannelMessage as Any), ("stargiftsCount", stargiftsCount as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -751,6 +752,8 @@ public extension Api {
|
|||
if Int(_2!) & Int(1 << 6) != 0 {_28 = reader.readInt64() }
|
||||
var _29: Int32?
|
||||
if Int(_2!) & Int(1 << 6) != 0 {_29 = reader.readInt32() }
|
||||
var _30: Int32?
|
||||
if Int(_2!) & Int(1 << 8) != 0 {_30 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
|
|
@ -780,8 +783,9 @@ public extension Api {
|
|||
let _c27 = (Int(_2!) & Int(1 << 5) == 0) || _27 != nil
|
||||
let _c28 = (Int(_2!) & Int(1 << 6) == 0) || _28 != nil
|
||||
let _c29 = (Int(_2!) & Int(1 << 6) == 0) || _29 != 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 && _c25 && _c26 && _c27 && _c28 && _c29 {
|
||||
return Api.UserFull.userFull(flags: _1!, flags2: _2!, id: _3!, about: _4, settings: _5!, personalPhoto: _6, profilePhoto: _7, fallbackPhoto: _8, notifySettings: _9!, botInfo: _10, pinnedMsgId: _11, commonChatsCount: _12!, folderId: _13, ttlPeriod: _14, themeEmoticon: _15, privateForwardName: _16, botGroupAdminRights: _17, botBroadcastAdminRights: _18, premiumGifts: _19, wallpaper: _20, stories: _21, businessWorkHours: _22, businessLocation: _23, businessGreetingMessage: _24, businessAwayMessage: _25, businessIntro: _26, birthday: _27, personalChannelId: _28, personalChannelMessage: _29)
|
||||
let _c30 = (Int(_2!) & Int(1 << 8) == 0) || _30 != 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 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 {
|
||||
return Api.UserFull.userFull(flags: _1!, flags2: _2!, id: _3!, about: _4, settings: _5!, personalPhoto: _6, profilePhoto: _7, fallbackPhoto: _8, notifySettings: _9!, botInfo: _10, pinnedMsgId: _11, commonChatsCount: _12!, folderId: _13, ttlPeriod: _14, themeEmoticon: _15, privateForwardName: _16, botGroupAdminRights: _17, botBroadcastAdminRights: _18, premiumGifts: _19, wallpaper: _20, stories: _21, businessWorkHours: _22, businessLocation: _23, businessGreetingMessage: _24, businessAwayMessage: _25, businessIntro: _26, birthday: _27, personalChannelId: _28, personalChannelMessage: _29, stargiftsCount: _30)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -850,6 +854,70 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum UserStarGift: TypeConstructorDescription {
|
||||
case userStarGift(flags: Int32, fromId: Int64?, date: Int32, gift: Api.StarGift, message: Api.TextWithEntities?, msgId: Int32?, convertStars: Int64?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .userStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let convertStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(-291202450)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt64(fromId!, buffer: buffer, boxed: false)}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
gift.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 2) != 0 {message!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(msgId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(convertStars!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .userStarGift(let flags, let fromId, let date, let gift, let message, let msgId, let convertStars):
|
||||
return ("userStarGift", [("flags", flags as Any), ("fromId", fromId as Any), ("date", date as Any), ("gift", gift as Any), ("message", message as Any), ("msgId", msgId as Any), ("convertStars", convertStars as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_userStarGift(_ reader: BufferReader) -> UserStarGift? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_2 = reader.readInt64() }
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Api.StarGift?
|
||||
if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.StarGift
|
||||
}
|
||||
var _5: Api.TextWithEntities?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
||||
} }
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_6 = reader.readInt32() }
|
||||
var _7: Int64?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_7 = reader.readInt64() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 1) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 4) == 0) || _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.UserStarGift.userStarGift(flags: _1!, fromId: _2, date: _3!, gift: _4!, message: _5, msgId: _6, convertStars: _7)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum UserStatus: TypeConstructorDescription {
|
||||
case userStatusEmpty
|
||||
|
|
@ -1458,207 +1526,3 @@ public extension Api {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum WebPage: TypeConstructorDescription {
|
||||
case webPage(flags: Int32, id: Int64, url: String, displayUrl: String, hash: Int32, type: String?, siteName: String?, title: String?, description: String?, photo: Api.Photo?, embedUrl: String?, embedType: String?, embedWidth: Int32?, embedHeight: Int32?, duration: Int32?, author: String?, document: Api.Document?, cachedPage: Api.Page?, attributes: [Api.WebPageAttribute]?)
|
||||
case webPageEmpty(flags: Int32, id: Int64, url: String?)
|
||||
case webPageNotModified(flags: Int32, cachedPageViews: Int32?)
|
||||
case webPagePending(flags: Int32, id: Int64, url: String?, date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .webPage(let flags, let id, let url, let displayUrl, let hash, let type, let siteName, let title, let description, let photo, let embedUrl, let embedType, let embedWidth, let embedHeight, let duration, let author, let document, let cachedPage, let attributes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-392411726)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(displayUrl, buffer: buffer, boxed: false)
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(type!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(siteName!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(description!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {photo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {serializeString(embedUrl!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {serializeString(embedType!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(embedWidth!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(embedHeight!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(duration!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeString(author!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 9) != 0 {document!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 10) != 0 {cachedPage!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(attributes!.count))
|
||||
for item in attributes! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
case .webPageEmpty(let flags, let id, let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(555358088)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .webPageNotModified(let flags, let cachedPageViews):
|
||||
if boxed {
|
||||
buffer.appendInt32(1930545681)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(cachedPageViews!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .webPagePending(let flags, let id, let url, let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1328464313)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .webPage(let flags, let id, let url, let displayUrl, let hash, let type, let siteName, let title, let description, let photo, let embedUrl, let embedType, let embedWidth, let embedHeight, let duration, let author, let document, let cachedPage, let attributes):
|
||||
return ("webPage", [("flags", flags as Any), ("id", id as Any), ("url", url as Any), ("displayUrl", displayUrl as Any), ("hash", hash as Any), ("type", type as Any), ("siteName", siteName as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("embedUrl", embedUrl as Any), ("embedType", embedType as Any), ("embedWidth", embedWidth as Any), ("embedHeight", embedHeight as Any), ("duration", duration as Any), ("author", author as Any), ("document", document as Any), ("cachedPage", cachedPage as Any), ("attributes", attributes as Any)])
|
||||
case .webPageEmpty(let flags, let id, let url):
|
||||
return ("webPageEmpty", [("flags", flags as Any), ("id", id as Any), ("url", url as Any)])
|
||||
case .webPageNotModified(let flags, let cachedPageViews):
|
||||
return ("webPageNotModified", [("flags", flags as Any), ("cachedPageViews", cachedPageViews as Any)])
|
||||
case .webPagePending(let flags, let id, let url, let date):
|
||||
return ("webPagePending", [("flags", flags as Any), ("id", id as Any), ("url", url as Any), ("date", date as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_webPage(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
var _5: Int32?
|
||||
_5 = reader.readInt32()
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_7 = parseString(reader) }
|
||||
var _8: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_8 = parseString(reader) }
|
||||
var _9: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_9 = parseString(reader) }
|
||||
var _10: Api.Photo?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
} }
|
||||
var _11: String?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {_11 = parseString(reader) }
|
||||
var _12: String?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {_12 = parseString(reader) }
|
||||
var _13: Int32?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_13 = reader.readInt32() }
|
||||
var _14: Int32?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_14 = reader.readInt32() }
|
||||
var _15: Int32?
|
||||
if Int(_1!) & Int(1 << 7) != 0 {_15 = reader.readInt32() }
|
||||
var _16: String?
|
||||
if Int(_1!) & Int(1 << 8) != 0 {_16 = parseString(reader) }
|
||||
var _17: Api.Document?
|
||||
if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() {
|
||||
_17 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _18: Api.Page?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
|
||||
_18 = Api.parse(reader, signature: signature) as? Api.Page
|
||||
} }
|
||||
var _19: [Api.WebPageAttribute]?
|
||||
if Int(_1!) & Int(1 << 12) != 0 {if let _ = reader.readInt32() {
|
||||
_19 = Api.parseVector(reader, elementSignature: 0, elementType: Api.WebPageAttribute.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 3) == 0) || _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 4) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 5) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 5) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 6) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 6) == 0) || _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 7) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 8) == 0) || _16 != nil
|
||||
let _c17 = (Int(_1!) & Int(1 << 9) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 10) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 12) == 0) || _19 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 {
|
||||
return Api.WebPage.webPage(flags: _1!, id: _2!, url: _3!, displayUrl: _4!, hash: _5!, type: _6, siteName: _7, title: _8, description: _9, photo: _10, embedUrl: _11, embedType: _12, embedWidth: _13, embedHeight: _14, duration: _15, author: _16, document: _17, cachedPage: _18, attributes: _19)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPageEmpty(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.WebPage.webPageEmpty(flags: _1!, id: _2!, url: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPageNotModified(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.WebPage.webPageNotModified(flags: _1!, cachedPageViews: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPagePending(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.WebPage.webPagePending(flags: _1!, id: _2!, url: _3, date: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,207 @@
|
|||
public extension Api {
|
||||
enum WebPage: TypeConstructorDescription {
|
||||
case webPage(flags: Int32, id: Int64, url: String, displayUrl: String, hash: Int32, type: String?, siteName: String?, title: String?, description: String?, photo: Api.Photo?, embedUrl: String?, embedType: String?, embedWidth: Int32?, embedHeight: Int32?, duration: Int32?, author: String?, document: Api.Document?, cachedPage: Api.Page?, attributes: [Api.WebPageAttribute]?)
|
||||
case webPageEmpty(flags: Int32, id: Int64, url: String?)
|
||||
case webPageNotModified(flags: Int32, cachedPageViews: Int32?)
|
||||
case webPagePending(flags: Int32, id: Int64, url: String?, date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .webPage(let flags, let id, let url, let displayUrl, let hash, let type, let siteName, let title, let description, let photo, let embedUrl, let embedType, let embedWidth, let embedHeight, let duration, let author, let document, let cachedPage, let attributes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-392411726)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(displayUrl, buffer: buffer, boxed: false)
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(type!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(siteName!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(description!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {photo!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {serializeString(embedUrl!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 5) != 0 {serializeString(embedType!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(embedWidth!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(embedHeight!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(duration!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeString(author!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 9) != 0 {document!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 10) != 0 {cachedPage!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(attributes!.count))
|
||||
for item in attributes! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
case .webPageEmpty(let flags, let id, let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(555358088)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .webPageNotModified(let flags, let cachedPageViews):
|
||||
if boxed {
|
||||
buffer.appendInt32(1930545681)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(cachedPageViews!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .webPagePending(let flags, let id, let url, let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1328464313)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .webPage(let flags, let id, let url, let displayUrl, let hash, let type, let siteName, let title, let description, let photo, let embedUrl, let embedType, let embedWidth, let embedHeight, let duration, let author, let document, let cachedPage, let attributes):
|
||||
return ("webPage", [("flags", flags as Any), ("id", id as Any), ("url", url as Any), ("displayUrl", displayUrl as Any), ("hash", hash as Any), ("type", type as Any), ("siteName", siteName as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("embedUrl", embedUrl as Any), ("embedType", embedType as Any), ("embedWidth", embedWidth as Any), ("embedHeight", embedHeight as Any), ("duration", duration as Any), ("author", author as Any), ("document", document as Any), ("cachedPage", cachedPage as Any), ("attributes", attributes as Any)])
|
||||
case .webPageEmpty(let flags, let id, let url):
|
||||
return ("webPageEmpty", [("flags", flags as Any), ("id", id as Any), ("url", url as Any)])
|
||||
case .webPageNotModified(let flags, let cachedPageViews):
|
||||
return ("webPageNotModified", [("flags", flags as Any), ("cachedPageViews", cachedPageViews as Any)])
|
||||
case .webPagePending(let flags, let id, let url, let date):
|
||||
return ("webPagePending", [("flags", flags as Any), ("id", id as Any), ("url", url as Any), ("date", date as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_webPage(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: String?
|
||||
_4 = parseString(reader)
|
||||
var _5: Int32?
|
||||
_5 = reader.readInt32()
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_7 = parseString(reader) }
|
||||
var _8: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_8 = parseString(reader) }
|
||||
var _9: String?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_9 = parseString(reader) }
|
||||
var _10: Api.Photo?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_10 = Api.parse(reader, signature: signature) as? Api.Photo
|
||||
} }
|
||||
var _11: String?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {_11 = parseString(reader) }
|
||||
var _12: String?
|
||||
if Int(_1!) & Int(1 << 5) != 0 {_12 = parseString(reader) }
|
||||
var _13: Int32?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_13 = reader.readInt32() }
|
||||
var _14: Int32?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {_14 = reader.readInt32() }
|
||||
var _15: Int32?
|
||||
if Int(_1!) & Int(1 << 7) != 0 {_15 = reader.readInt32() }
|
||||
var _16: String?
|
||||
if Int(_1!) & Int(1 << 8) != 0 {_16 = parseString(reader) }
|
||||
var _17: Api.Document?
|
||||
if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() {
|
||||
_17 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _18: Api.Page?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
|
||||
_18 = Api.parse(reader, signature: signature) as? Api.Page
|
||||
} }
|
||||
var _19: [Api.WebPageAttribute]?
|
||||
if Int(_1!) & Int(1 << 12) != 0 {if let _ = reader.readInt32() {
|
||||
_19 = Api.parseVector(reader, elementSignature: 0, elementType: Api.WebPageAttribute.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil
|
||||
let _c9 = (Int(_1!) & Int(1 << 3) == 0) || _9 != nil
|
||||
let _c10 = (Int(_1!) & Int(1 << 4) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 5) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 5) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 6) == 0) || _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 6) == 0) || _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 7) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 8) == 0) || _16 != nil
|
||||
let _c17 = (Int(_1!) & Int(1 << 9) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 10) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 12) == 0) || _19 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 {
|
||||
return Api.WebPage.webPage(flags: _1!, id: _2!, url: _3!, displayUrl: _4!, hash: _5!, type: _6, siteName: _7, title: _8, description: _9, photo: _10, embedUrl: _11, embedType: _12, embedWidth: _13, embedHeight: _14, duration: _15, author: _16, document: _17, cachedPage: _18, attributes: _19)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPageEmpty(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.WebPage.webPageEmpty(flags: _1!, id: _2!, url: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPageNotModified(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.WebPage.webPageNotModified(flags: _1!, cachedPageViews: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_webPagePending(_ reader: BufferReader) -> WebPage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.WebPage.webPagePending(flags: _1!, id: _2!, url: _3, date: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum WebPageAttribute: TypeConstructorDescription {
|
||||
case webPageAttributeStickerSet(flags: Int32, stickers: [Api.Document])
|
||||
|
|
@ -1230,137 +1434,3 @@ public extension Api.account {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum SentEmailCode: TypeConstructorDescription {
|
||||
case sentEmailCode(emailPattern: String, length: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEmailCode(let emailPattern, let length):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2128640689)
|
||||
}
|
||||
serializeString(emailPattern, buffer: buffer, boxed: false)
|
||||
serializeInt32(length, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEmailCode(let emailPattern, let length):
|
||||
return ("sentEmailCode", [("emailPattern", emailPattern as Any), ("length", length as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEmailCode(_ reader: BufferReader) -> SentEmailCode? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.account.SentEmailCode.sentEmailCode(emailPattern: _1!, length: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Takeout: TypeConstructorDescription {
|
||||
case takeout(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .takeout(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(1304052993)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .takeout(let id):
|
||||
return ("takeout", [("id", id as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_takeout(_ reader: BufferReader) -> Takeout? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.Takeout.takeout(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Themes: TypeConstructorDescription {
|
||||
case themes(hash: Int64, themes: [Api.Theme])
|
||||
case themesNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .themes(let hash, let themes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1707242387)
|
||||
}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(themes.count))
|
||||
for item in themes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .themesNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-199313886)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .themes(let hash, let themes):
|
||||
return ("themes", [("hash", hash as Any), ("themes", themes as Any)])
|
||||
case .themesNotModified:
|
||||
return ("themesNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_themes(_ reader: BufferReader) -> Themes? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: [Api.Theme]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Theme.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.account.Themes.themes(hash: _1!, themes: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_themesNotModified(_ reader: BufferReader) -> Themes? {
|
||||
return Api.account.Themes.themesNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,137 @@
|
|||
public extension Api.account {
|
||||
enum SentEmailCode: TypeConstructorDescription {
|
||||
case sentEmailCode(emailPattern: String, length: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEmailCode(let emailPattern, let length):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2128640689)
|
||||
}
|
||||
serializeString(emailPattern, buffer: buffer, boxed: false)
|
||||
serializeInt32(length, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEmailCode(let emailPattern, let length):
|
||||
return ("sentEmailCode", [("emailPattern", emailPattern as Any), ("length", length as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEmailCode(_ reader: BufferReader) -> SentEmailCode? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.account.SentEmailCode.sentEmailCode(emailPattern: _1!, length: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Takeout: TypeConstructorDescription {
|
||||
case takeout(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .takeout(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(1304052993)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .takeout(let id):
|
||||
return ("takeout", [("id", id as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_takeout(_ reader: BufferReader) -> Takeout? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.account.Takeout.takeout(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum Themes: TypeConstructorDescription {
|
||||
case themes(hash: Int64, themes: [Api.Theme])
|
||||
case themesNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .themes(let hash, let themes):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1707242387)
|
||||
}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(themes.count))
|
||||
for item in themes {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .themesNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-199313886)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .themes(let hash, let themes):
|
||||
return ("themes", [("hash", hash as Any), ("themes", themes as Any)])
|
||||
case .themesNotModified:
|
||||
return ("themesNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_themes(_ reader: BufferReader) -> Themes? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: [Api.Theme]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Theme.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.account.Themes.themes(hash: _1!, themes: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_themesNotModified(_ reader: BufferReader) -> Themes? {
|
||||
return Api.account.Themes.themesNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.account {
|
||||
enum TmpPassword: TypeConstructorDescription {
|
||||
case tmpPassword(tmpPassword: Buffer, validUntil: Int32)
|
||||
|
|
@ -876,97 +1010,3 @@ public extension Api.auth {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.bots {
|
||||
enum BotInfo: TypeConstructorDescription {
|
||||
case botInfo(name: String, about: String, description: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botInfo(let name, let about, let description):
|
||||
if boxed {
|
||||
buffer.appendInt32(-391678544)
|
||||
}
|
||||
serializeString(name, buffer: buffer, boxed: false)
|
||||
serializeString(about, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botInfo(let name, let about, let description):
|
||||
return ("botInfo", [("name", name as Any), ("about", about as Any), ("description", description as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botInfo(_ reader: BufferReader) -> BotInfo? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.bots.BotInfo.botInfo(name: _1!, about: _2!, description: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.bots {
|
||||
enum PopularAppBots: TypeConstructorDescription {
|
||||
case popularAppBots(flags: Int32, nextOffset: String?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .popularAppBots(let flags, let nextOffset, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(428978491)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
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 .popularAppBots(let flags, let nextOffset, let users):
|
||||
return ("popularAppBots", [("flags", flags as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_popularAppBots(_ reader: BufferReader) -> PopularAppBots? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.bots.PopularAppBots.popularAppBots(flags: _1!, nextOffset: _2, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,97 @@
|
|||
public extension Api.bots {
|
||||
enum BotInfo: TypeConstructorDescription {
|
||||
case botInfo(name: String, about: String, description: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botInfo(let name, let about, let description):
|
||||
if boxed {
|
||||
buffer.appendInt32(-391678544)
|
||||
}
|
||||
serializeString(name, buffer: buffer, boxed: false)
|
||||
serializeString(about, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botInfo(let name, let about, let description):
|
||||
return ("botInfo", [("name", name as Any), ("about", about as Any), ("description", description as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botInfo(_ reader: BufferReader) -> BotInfo? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.bots.BotInfo.botInfo(name: _1!, about: _2!, description: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.bots {
|
||||
enum PopularAppBots: TypeConstructorDescription {
|
||||
case popularAppBots(flags: Int32, nextOffset: String?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .popularAppBots(let flags, let nextOffset, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(428978491)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
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 .popularAppBots(let flags, let nextOffset, let users):
|
||||
return ("popularAppBots", [("flags", flags as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_popularAppBots(_ reader: BufferReader) -> PopularAppBots? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
|
||||
var _3: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.bots.PopularAppBots.popularAppBots(flags: _1!, nextOffset: _2, users: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.bots {
|
||||
enum PreviewInfo: TypeConstructorDescription {
|
||||
case previewInfo(media: [Api.BotPreviewMedia], langCodes: [String])
|
||||
|
|
@ -1398,61 +1492,3 @@ public extension Api.help {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum CountriesList: TypeConstructorDescription {
|
||||
case countriesList(countries: [Api.help.Country], hash: Int32)
|
||||
case countriesListNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .countriesList(let countries, let hash):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2016381538)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(countries.count))
|
||||
for item in countries {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .countriesListNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1815339214)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .countriesList(let countries, let hash):
|
||||
return ("countriesList", [("countries", countries as Any), ("hash", hash as Any)])
|
||||
case .countriesListNotModified:
|
||||
return ("countriesListNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_countriesList(_ reader: BufferReader) -> CountriesList? {
|
||||
var _1: [Api.help.Country]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.Country.self)
|
||||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.help.CountriesList.countriesList(countries: _1!, hash: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_countriesListNotModified(_ reader: BufferReader) -> CountriesList? {
|
||||
return Api.help.CountriesList.countriesListNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,61 @@
|
|||
public extension Api.help {
|
||||
enum CountriesList: TypeConstructorDescription {
|
||||
case countriesList(countries: [Api.help.Country], hash: Int32)
|
||||
case countriesListNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .countriesList(let countries, let hash):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2016381538)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(countries.count))
|
||||
for item in countries {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .countriesListNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1815339214)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .countriesList(let countries, let hash):
|
||||
return ("countriesList", [("countries", countries as Any), ("hash", hash as Any)])
|
||||
case .countriesListNotModified:
|
||||
return ("countriesListNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_countriesList(_ reader: BufferReader) -> CountriesList? {
|
||||
var _1: [Api.help.Country]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.Country.self)
|
||||
}
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.help.CountriesList.countriesList(countries: _1!, hash: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_countriesListNotModified(_ reader: BufferReader) -> CountriesList? {
|
||||
return Api.help.CountriesList.countriesListNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.help {
|
||||
enum Country: TypeConstructorDescription {
|
||||
case country(flags: Int32, iso2: String, defaultName: String, name: String?, countryCodes: [Api.help.CountryCode])
|
||||
|
|
@ -1236,117 +1294,3 @@ public extension Api.messages {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum ArchivedStickers: TypeConstructorDescription {
|
||||
case archivedStickers(count: Int32, sets: [Api.StickerSetCovered])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .archivedStickers(let count, let sets):
|
||||
if boxed {
|
||||
buffer.appendInt32(1338747336)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(sets.count))
|
||||
for item in sets {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .archivedStickers(let count, let sets):
|
||||
return ("archivedStickers", [("count", count as Any), ("sets", sets as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_archivedStickers(_ reader: BufferReader) -> ArchivedStickers? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.StickerSetCovered]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSetCovered.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.ArchivedStickers.archivedStickers(count: _1!, sets: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum AvailableEffects: TypeConstructorDescription {
|
||||
case availableEffects(hash: Int32, effects: [Api.AvailableEffect], documents: [Api.Document])
|
||||
case availableEffectsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .availableEffects(let hash, let effects, let documents):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1109696146)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(effects.count))
|
||||
for item in effects {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(documents.count))
|
||||
for item in documents {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .availableEffectsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-772957605)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .availableEffects(let hash, let effects, let documents):
|
||||
return ("availableEffects", [("hash", hash as Any), ("effects", effects as Any), ("documents", documents as Any)])
|
||||
case .availableEffectsNotModified:
|
||||
return ("availableEffectsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_availableEffects(_ reader: BufferReader) -> AvailableEffects? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.AvailableEffect]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableEffect.self)
|
||||
}
|
||||
var _3: [Api.Document]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.AvailableEffects.availableEffects(hash: _1!, effects: _2!, documents: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_availableEffectsNotModified(_ reader: BufferReader) -> AvailableEffects? {
|
||||
return Api.messages.AvailableEffects.availableEffectsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,117 @@
|
|||
public extension Api.messages {
|
||||
enum ArchivedStickers: TypeConstructorDescription {
|
||||
case archivedStickers(count: Int32, sets: [Api.StickerSetCovered])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .archivedStickers(let count, let sets):
|
||||
if boxed {
|
||||
buffer.appendInt32(1338747336)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(sets.count))
|
||||
for item in sets {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .archivedStickers(let count, let sets):
|
||||
return ("archivedStickers", [("count", count as Any), ("sets", sets as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_archivedStickers(_ reader: BufferReader) -> ArchivedStickers? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.StickerSetCovered]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSetCovered.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.ArchivedStickers.archivedStickers(count: _1!, sets: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum AvailableEffects: TypeConstructorDescription {
|
||||
case availableEffects(hash: Int32, effects: [Api.AvailableEffect], documents: [Api.Document])
|
||||
case availableEffectsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .availableEffects(let hash, let effects, let documents):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1109696146)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(effects.count))
|
||||
for item in effects {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(documents.count))
|
||||
for item in documents {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .availableEffectsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-772957605)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .availableEffects(let hash, let effects, let documents):
|
||||
return ("availableEffects", [("hash", hash as Any), ("effects", effects as Any), ("documents", documents as Any)])
|
||||
case .availableEffectsNotModified:
|
||||
return ("availableEffectsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_availableEffects(_ reader: BufferReader) -> AvailableEffects? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.AvailableEffect]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableEffect.self)
|
||||
}
|
||||
var _3: [Api.Document]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.messages.AvailableEffects.availableEffects(hash: _1!, effects: _2!, documents: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_availableEffectsNotModified(_ reader: BufferReader) -> AvailableEffects? {
|
||||
return Api.messages.AvailableEffects.availableEffectsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum AvailableReactions: TypeConstructorDescription {
|
||||
case availableReactions(hash: Int32, reactions: [Api.AvailableReaction])
|
||||
|
|
@ -1342,91 +1456,3 @@ public extension Api.messages {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum HighScores: TypeConstructorDescription {
|
||||
case highScores(scores: [Api.HighScore], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .highScores(let scores, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1707344487)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(scores.count))
|
||||
for item in scores {
|
||||
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 .highScores(let scores, let users):
|
||||
return ("highScores", [("scores", scores as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_highScores(_ reader: BufferReader) -> HighScores? {
|
||||
var _1: [Api.HighScore]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.HighScore.self)
|
||||
}
|
||||
var _2: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.HighScores.highScores(scores: _1!, users: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum HistoryImport: TypeConstructorDescription {
|
||||
case historyImport(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .historyImport(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(375566091)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .historyImport(let id):
|
||||
return ("historyImport", [("id", id as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_historyImport(_ reader: BufferReader) -> HistoryImport? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.HistoryImport.historyImport(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,91 @@
|
|||
public extension Api.messages {
|
||||
enum HighScores: TypeConstructorDescription {
|
||||
case highScores(scores: [Api.HighScore], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .highScores(let scores, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1707344487)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(scores.count))
|
||||
for item in scores {
|
||||
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 .highScores(let scores, let users):
|
||||
return ("highScores", [("scores", scores as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_highScores(_ reader: BufferReader) -> HighScores? {
|
||||
var _1: [Api.HighScore]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.HighScore.self)
|
||||
}
|
||||
var _2: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.HighScores.highScores(scores: _1!, users: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum HistoryImport: TypeConstructorDescription {
|
||||
case historyImport(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .historyImport(let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(375566091)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .historyImport(let id):
|
||||
return ("historyImport", [("id", id as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_historyImport(_ reader: BufferReader) -> HistoryImport? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.HistoryImport.historyImport(id: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum HistoryImportParsed: TypeConstructorDescription {
|
||||
case historyImportParsed(flags: Int32, title: String?)
|
||||
|
|
@ -1452,85 +1540,3 @@ public extension Api.messages {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SponsoredMessages: TypeConstructorDescription {
|
||||
case sponsoredMessages(flags: Int32, postsBetween: Int32?, messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User])
|
||||
case sponsoredMessagesEmpty
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-907141753)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(postsBetween!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .sponsoredMessagesEmpty:
|
||||
if boxed {
|
||||
buffer.appendInt32(406407439)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users):
|
||||
return ("sponsoredMessages", [("flags", flags as Any), ("postsBetween", postsBetween as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .sponsoredMessagesEmpty:
|
||||
return ("sponsoredMessagesEmpty", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sponsoredMessages(_ reader: BufferReader) -> SponsoredMessages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
|
||||
var _3: [Api.SponsoredMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SponsoredMessage.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.messages.SponsoredMessages.sponsoredMessages(flags: _1!, postsBetween: _2, messages: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sponsoredMessagesEmpty(_ reader: BufferReader) -> SponsoredMessages? {
|
||||
return Api.messages.SponsoredMessages.sponsoredMessagesEmpty
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,85 @@
|
|||
public extension Api.messages {
|
||||
enum SponsoredMessages: TypeConstructorDescription {
|
||||
case sponsoredMessages(flags: Int32, postsBetween: Int32?, messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User])
|
||||
case sponsoredMessagesEmpty
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-907141753)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(postsBetween!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .sponsoredMessagesEmpty:
|
||||
if boxed {
|
||||
buffer.appendInt32(406407439)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sponsoredMessages(let flags, let postsBetween, let messages, let chats, let users):
|
||||
return ("sponsoredMessages", [("flags", flags as Any), ("postsBetween", postsBetween as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
case .sponsoredMessagesEmpty:
|
||||
return ("sponsoredMessagesEmpty", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sponsoredMessages(_ reader: BufferReader) -> SponsoredMessages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt32() }
|
||||
var _3: [Api.SponsoredMessage]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SponsoredMessage.self)
|
||||
}
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.messages.SponsoredMessages.sponsoredMessages(flags: _1!, postsBetween: _2, messages: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sponsoredMessagesEmpty(_ reader: BufferReader) -> SponsoredMessages? {
|
||||
return Api.messages.SponsoredMessages.sponsoredMessagesEmpty
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum StickerSet: TypeConstructorDescription {
|
||||
case stickerSet(set: Api.StickerSet, packs: [Api.StickerPack], keywords: [Api.StickerKeyword], documents: [Api.Document])
|
||||
|
|
@ -679,6 +761,7 @@ public extension Api.payments {
|
|||
public extension Api.payments {
|
||||
enum PaymentForm: TypeConstructorDescription {
|
||||
case paymentForm(flags: Int32, formId: Int64, botId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, providerId: Int64, url: String, nativeProvider: String?, nativeParams: Api.DataJSON?, additionalMethods: [Api.PaymentFormMethod]?, savedInfo: Api.PaymentRequestedInfo?, savedCredentials: [Api.PaymentSavedCredentials]?, users: [Api.User])
|
||||
case paymentFormStarGift(formId: Int64, invoice: Api.Invoice)
|
||||
case paymentFormStars(flags: Int32, formId: Int64, botId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
|
|
@ -715,6 +798,13 @@ public extension Api.payments {
|
|||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .paymentFormStarGift(let formId, let invoice):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1272590367)
|
||||
}
|
||||
serializeInt64(formId, buffer: buffer, boxed: false)
|
||||
invoice.serialize(buffer, true)
|
||||
break
|
||||
case .paymentFormStars(let flags, let formId, let botId, let title, let description, let photo, let invoice, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(2079764828)
|
||||
|
|
@ -739,6 +829,8 @@ public extension Api.payments {
|
|||
switch self {
|
||||
case .paymentForm(let flags, let formId, let botId, let title, let description, let photo, let invoice, let providerId, let url, let nativeProvider, let nativeParams, let additionalMethods, let savedInfo, let savedCredentials, let users):
|
||||
return ("paymentForm", [("flags", flags as Any), ("formId", formId as Any), ("botId", botId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("providerId", providerId as Any), ("url", url as Any), ("nativeProvider", nativeProvider as Any), ("nativeParams", nativeParams as Any), ("additionalMethods", additionalMethods as Any), ("savedInfo", savedInfo as Any), ("savedCredentials", savedCredentials as Any), ("users", users as Any)])
|
||||
case .paymentFormStarGift(let formId, let invoice):
|
||||
return ("paymentFormStarGift", [("formId", formId as Any), ("invoice", invoice as Any)])
|
||||
case .paymentFormStars(let flags, let formId, let botId, let title, let description, let photo, let invoice, let users):
|
||||
return ("paymentFormStars", [("flags", flags as Any), ("formId", formId as Any), ("botId", botId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("users", users as Any)])
|
||||
}
|
||||
|
|
@ -811,6 +903,22 @@ public extension Api.payments {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_paymentFormStarGift(_ reader: BufferReader) -> PaymentForm? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: Api.Invoice?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.PaymentForm.paymentFormStarGift(formId: _1!, invoice: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_paymentFormStars(_ reader: BufferReader) -> PaymentForm? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
|
|
@ -1128,6 +1236,64 @@ public extension Api.payments {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarGifts: TypeConstructorDescription {
|
||||
case starGifts(hash: Int32, gifts: [Api.StarGift])
|
||||
case starGiftsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starGifts(let hash, let gifts):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1877571094)
|
||||
}
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(gifts.count))
|
||||
for item in gifts {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .starGiftsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1551326360)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starGifts(let hash, let gifts):
|
||||
return ("starGifts", [("hash", hash as Any), ("gifts", gifts as Any)])
|
||||
case .starGiftsNotModified:
|
||||
return ("starGiftsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starGifts(_ reader: BufferReader) -> StarGifts? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.StarGift]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarGift.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.StarGifts.starGifts(hash: _1!, gifts: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_starGiftsNotModified(_ reader: BufferReader) -> StarGifts? {
|
||||
return Api.payments.StarGifts.starGiftsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsRevenueAdsAccountUrl: TypeConstructorDescription {
|
||||
case starsRevenueAdsAccountUrl(url: String)
|
||||
|
|
@ -1341,311 +1507,61 @@ public extension Api.payments {
|
|||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum ValidatedRequestedInfo: TypeConstructorDescription {
|
||||
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
|
||||
enum UserStarGifts: TypeConstructorDescription {
|
||||
case userStarGifts(flags: Int32, count: Int32, gifts: [Api.UserStarGift], nextOffset: String?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-784000893)
|
||||
buffer.appendInt32(1801827607)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(id!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(shippingOptions!.count))
|
||||
for item in shippingOptions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
|
||||
return ("validatedRequestedInfo", [("flags", flags as Any), ("id", id as Any), ("shippingOptions", shippingOptions as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_validatedRequestedInfo(_ reader: BufferReader) -> ValidatedRequestedInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
|
||||
var _3: [Api.ShippingOption]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ShippingOption.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.payments.ValidatedRequestedInfo.validatedRequestedInfo(flags: _1!, id: _2, shippingOptions: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum ExportedGroupCallInvite: TypeConstructorDescription {
|
||||
case exportedGroupCallInvite(link: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .exportedGroupCallInvite(let link):
|
||||
if boxed {
|
||||
buffer.appendInt32(541839704)
|
||||
}
|
||||
serializeString(link, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .exportedGroupCallInvite(let link):
|
||||
return ("exportedGroupCallInvite", [("link", link as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_exportedGroupCallInvite(_ reader: BufferReader) -> ExportedGroupCallInvite? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.phone.ExportedGroupCallInvite.exportedGroupCallInvite(link: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCall: TypeConstructorDescription {
|
||||
case groupCall(call: Api.GroupCall, participants: [Api.GroupCallParticipant], participantsNextOffset: String, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCall(let call, let participants, let participantsNextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1636664659)
|
||||
}
|
||||
call.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(participants.count))
|
||||
for item in participants {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeString(participantsNextOffset, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .groupCall(let call, let participants, let participantsNextOffset, let chats, let users):
|
||||
return ("groupCall", [("call", call as Any), ("participants", participants as Any), ("participantsNextOffset", participantsNextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCall(_ reader: BufferReader) -> GroupCall? {
|
||||
var _1: Api.GroupCall?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.GroupCall
|
||||
}
|
||||
var _2: [Api.GroupCallParticipant]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
|
||||
}
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = 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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.phone.GroupCall.groupCall(call: _1!, participants: _2!, participantsNextOffset: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCallStreamChannels: TypeConstructorDescription {
|
||||
case groupCallStreamChannels(channels: [Api.GroupCallStreamChannel])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCallStreamChannels(let channels):
|
||||
if boxed {
|
||||
buffer.appendInt32(-790330702)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(channels.count))
|
||||
for item in channels {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupCallStreamChannels(let channels):
|
||||
return ("groupCallStreamChannels", [("channels", channels as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCallStreamChannels(_ reader: BufferReader) -> GroupCallStreamChannels? {
|
||||
var _1: [Api.GroupCallStreamChannel]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallStreamChannel.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.phone.GroupCallStreamChannels.groupCallStreamChannels(channels: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCallStreamRtmpUrl: TypeConstructorDescription {
|
||||
case groupCallStreamRtmpUrl(url: String, key: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCallStreamRtmpUrl(let url, let key):
|
||||
if boxed {
|
||||
buffer.appendInt32(767505458)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(key, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupCallStreamRtmpUrl(let url, let key):
|
||||
return ("groupCallStreamRtmpUrl", [("url", url as Any), ("key", key as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCallStreamRtmpUrl(_ reader: BufferReader) -> GroupCallStreamRtmpUrl? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.phone.GroupCallStreamRtmpUrl.groupCallStreamRtmpUrl(url: _1!, key: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupParticipants: TypeConstructorDescription {
|
||||
case groupParticipants(count: Int32, participants: [Api.GroupCallParticipant], nextOffset: String, chats: [Api.Chat], users: [Api.User], version: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupParticipants(let count, let participants, let nextOffset, let chats, let users, let version):
|
||||
if boxed {
|
||||
buffer.appendInt32(-193506890)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(participants.count))
|
||||
for item in participants {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeString(nextOffset, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
buffer.appendInt32(Int32(gifts.count))
|
||||
for item in gifts {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupParticipants(let count, let participants, let nextOffset, let chats, let users, let version):
|
||||
return ("groupParticipants", [("count", count as Any), ("participants", participants as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any), ("version", version as Any)])
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
return ("userStarGifts", [("flags", flags as Any), ("count", count as Any), ("gifts", gifts as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupParticipants(_ reader: BufferReader) -> GroupParticipants? {
|
||||
public static func parse_userStarGifts(_ reader: BufferReader) -> UserStarGifts? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.GroupCallParticipant]?
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.UserStarGift]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
|
||||
}
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.UserStarGift.self)
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Int32?
|
||||
_6 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.phone.GroupParticipants.groupParticipants(count: _1!, participants: _2!, nextOffset: _3!, chats: _4!, users: _5!, version: _6!)
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.payments.UserStarGifts.userStarGifts(flags: _1!, count: _2!, gifts: _3!, nextOffset: _4, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1,3 +1,317 @@
|
|||
public extension Api.payments {
|
||||
enum ValidatedRequestedInfo: TypeConstructorDescription {
|
||||
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
|
||||
if boxed {
|
||||
buffer.appendInt32(-784000893)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(id!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(shippingOptions!.count))
|
||||
for item in shippingOptions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
|
||||
return ("validatedRequestedInfo", [("flags", flags as Any), ("id", id as Any), ("shippingOptions", shippingOptions as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_validatedRequestedInfo(_ reader: BufferReader) -> ValidatedRequestedInfo? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
|
||||
var _3: [Api.ShippingOption]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ShippingOption.self)
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.payments.ValidatedRequestedInfo.validatedRequestedInfo(flags: _1!, id: _2, shippingOptions: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum ExportedGroupCallInvite: TypeConstructorDescription {
|
||||
case exportedGroupCallInvite(link: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .exportedGroupCallInvite(let link):
|
||||
if boxed {
|
||||
buffer.appendInt32(541839704)
|
||||
}
|
||||
serializeString(link, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .exportedGroupCallInvite(let link):
|
||||
return ("exportedGroupCallInvite", [("link", link as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_exportedGroupCallInvite(_ reader: BufferReader) -> ExportedGroupCallInvite? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.phone.ExportedGroupCallInvite.exportedGroupCallInvite(link: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCall: TypeConstructorDescription {
|
||||
case groupCall(call: Api.GroupCall, participants: [Api.GroupCallParticipant], participantsNextOffset: String, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCall(let call, let participants, let participantsNextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1636664659)
|
||||
}
|
||||
call.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(participants.count))
|
||||
for item in participants {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeString(participantsNextOffset, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .groupCall(let call, let participants, let participantsNextOffset, let chats, let users):
|
||||
return ("groupCall", [("call", call as Any), ("participants", participants as Any), ("participantsNextOffset", participantsNextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCall(_ reader: BufferReader) -> GroupCall? {
|
||||
var _1: Api.GroupCall?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.GroupCall
|
||||
}
|
||||
var _2: [Api.GroupCallParticipant]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
|
||||
}
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = 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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.phone.GroupCall.groupCall(call: _1!, participants: _2!, participantsNextOffset: _3!, chats: _4!, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCallStreamChannels: TypeConstructorDescription {
|
||||
case groupCallStreamChannels(channels: [Api.GroupCallStreamChannel])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCallStreamChannels(let channels):
|
||||
if boxed {
|
||||
buffer.appendInt32(-790330702)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(channels.count))
|
||||
for item in channels {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupCallStreamChannels(let channels):
|
||||
return ("groupCallStreamChannels", [("channels", channels as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCallStreamChannels(_ reader: BufferReader) -> GroupCallStreamChannels? {
|
||||
var _1: [Api.GroupCallStreamChannel]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallStreamChannel.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.phone.GroupCallStreamChannels.groupCallStreamChannels(channels: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupCallStreamRtmpUrl: TypeConstructorDescription {
|
||||
case groupCallStreamRtmpUrl(url: String, key: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupCallStreamRtmpUrl(let url, let key):
|
||||
if boxed {
|
||||
buffer.appendInt32(767505458)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(key, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupCallStreamRtmpUrl(let url, let key):
|
||||
return ("groupCallStreamRtmpUrl", [("url", url as Any), ("key", key as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupCallStreamRtmpUrl(_ reader: BufferReader) -> GroupCallStreamRtmpUrl? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.phone.GroupCallStreamRtmpUrl.groupCallStreamRtmpUrl(url: _1!, key: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum GroupParticipants: TypeConstructorDescription {
|
||||
case groupParticipants(count: Int32, participants: [Api.GroupCallParticipant], nextOffset: String, chats: [Api.Chat], users: [Api.User], version: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .groupParticipants(let count, let participants, let nextOffset, let chats, let users, let version):
|
||||
if boxed {
|
||||
buffer.appendInt32(-193506890)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(participants.count))
|
||||
for item in participants {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeString(nextOffset, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
serializeInt32(version, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .groupParticipants(let count, let participants, let nextOffset, let chats, let users, let version):
|
||||
return ("groupParticipants", [("count", count as Any), ("participants", participants as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any), ("version", version as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_groupParticipants(_ reader: BufferReader) -> GroupParticipants? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.GroupCallParticipant]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
|
||||
}
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _6: Int32?
|
||||
_6 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.phone.GroupParticipants.groupParticipants(count: _1!, participants: _2!, nextOffset: _3!, chats: _4!, users: _5!, version: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.phone {
|
||||
enum JoinAsPeers: TypeConstructorDescription {
|
||||
case joinAsPeers(peers: [Api.Peer], chats: [Api.Chat], users: [Api.User])
|
||||
|
|
@ -1352,187 +1666,3 @@ public extension Api.storage {
|
|||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum AllStories: TypeConstructorDescription {
|
||||
case allStories(flags: Int32, count: Int32, state: String, peerStories: [Api.PeerStories], chats: [Api.Chat], users: [Api.User], stealthMode: Api.StoriesStealthMode)
|
||||
case allStoriesNotModified(flags: Int32, state: String, stealthMode: Api.StoriesStealthMode)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
|
||||
if boxed {
|
||||
buffer.appendInt32(1862033025)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeString(state, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(peerStories.count))
|
||||
for item in peerStories {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
stealthMode.serialize(buffer, true)
|
||||
break
|
||||
case .allStoriesNotModified(let flags, let state, let stealthMode):
|
||||
if boxed {
|
||||
buffer.appendInt32(291044926)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(state, buffer: buffer, boxed: false)
|
||||
stealthMode.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
|
||||
return ("allStories", [("flags", flags as Any), ("count", count as Any), ("state", state as Any), ("peerStories", peerStories as Any), ("chats", chats as Any), ("users", users as Any), ("stealthMode", stealthMode as Any)])
|
||||
case .allStoriesNotModified(let flags, let state, let stealthMode):
|
||||
return ("allStoriesNotModified", [("flags", flags as Any), ("state", state as Any), ("stealthMode", stealthMode as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_allStories(_ reader: BufferReader) -> AllStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.PeerStories]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PeerStories.self)
|
||||
}
|
||||
var _5: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _6: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _7: Api.StoriesStealthMode?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
|
||||
}
|
||||
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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.stories.AllStories.allStories(flags: _1!, count: _2!, state: _3!, peerStories: _4!, chats: _5!, users: _6!, stealthMode: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_allStoriesNotModified(_ reader: BufferReader) -> AllStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.StoriesStealthMode?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.stories.AllStories.allStoriesNotModified(flags: _1!, state: _2!, stealthMode: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum FoundStories: TypeConstructorDescription {
|
||||
case foundStories(flags: Int32, count: Int32, stories: [Api.FoundStory], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .foundStories(let flags, let count, let stories, let nextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-488736969)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(stories.count))
|
||||
for item in stories {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .foundStories(let flags, let count, let stories, let nextOffset, let chats, let users):
|
||||
return ("foundStories", [("flags", flags as Any), ("count", count as Any), ("stories", stories as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_foundStories(_ reader: BufferReader) -> FoundStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.FoundStory]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.FoundStory.self)
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _6: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.stories.FoundStories.foundStories(flags: _1!, count: _2!, stories: _3!, nextOffset: _4, chats: _5!, users: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,187 @@
|
|||
public extension Api.stories {
|
||||
enum AllStories: TypeConstructorDescription {
|
||||
case allStories(flags: Int32, count: Int32, state: String, peerStories: [Api.PeerStories], chats: [Api.Chat], users: [Api.User], stealthMode: Api.StoriesStealthMode)
|
||||
case allStoriesNotModified(flags: Int32, state: String, stealthMode: Api.StoriesStealthMode)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
|
||||
if boxed {
|
||||
buffer.appendInt32(1862033025)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeString(state, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(peerStories.count))
|
||||
for item in peerStories {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
stealthMode.serialize(buffer, true)
|
||||
break
|
||||
case .allStoriesNotModified(let flags, let state, let stealthMode):
|
||||
if boxed {
|
||||
buffer.appendInt32(291044926)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(state, buffer: buffer, boxed: false)
|
||||
stealthMode.serialize(buffer, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
|
||||
return ("allStories", [("flags", flags as Any), ("count", count as Any), ("state", state as Any), ("peerStories", peerStories as Any), ("chats", chats as Any), ("users", users as Any), ("stealthMode", stealthMode as Any)])
|
||||
case .allStoriesNotModified(let flags, let state, let stealthMode):
|
||||
return ("allStoriesNotModified", [("flags", flags as Any), ("state", state as Any), ("stealthMode", stealthMode as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_allStories(_ reader: BufferReader) -> AllStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: [Api.PeerStories]?
|
||||
if let _ = reader.readInt32() {
|
||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PeerStories.self)
|
||||
}
|
||||
var _5: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _6: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
var _7: Api.StoriesStealthMode?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
|
||||
}
|
||||
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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.stories.AllStories.allStories(flags: _1!, count: _2!, state: _3!, peerStories: _4!, chats: _5!, users: _6!, stealthMode: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_allStoriesNotModified(_ reader: BufferReader) -> AllStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Api.StoriesStealthMode?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.stories.AllStories.allStoriesNotModified(flags: _1!, state: _2!, stealthMode: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum FoundStories: TypeConstructorDescription {
|
||||
case foundStories(flags: Int32, count: Int32, stories: [Api.FoundStory], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .foundStories(let flags, let count, let stories, let nextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-488736969)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(stories.count))
|
||||
for item in stories {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
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 .foundStories(let flags, let count, let stories, let nextOffset, let chats, let users):
|
||||
return ("foundStories", [("flags", flags as Any), ("count", count as Any), ("stories", stories as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_foundStories(_ reader: BufferReader) -> FoundStories? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.FoundStory]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.FoundStory.self)
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _6: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.stories.FoundStories.foundStories(flags: _1!, count: _2!, stories: _3!, nextOffset: _4, chats: _5!, users: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.stories {
|
||||
enum PeerStories: TypeConstructorDescription {
|
||||
case peerStories(stories: Api.PeerStories, chats: [Api.Chat], users: [Api.User])
|
||||
|
|
|
|||
|
|
@ -8838,6 +8838,22 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func convertStarGift(userId: Api.InputUser, msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(69328935)
|
||||
userId.serialize(buffer, true)
|
||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.convertStarGift", parameters: [("userId", String(describing: userId)), ("msgId", String(describing: msgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Bool?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func exportInvoice(invoiceMedia: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.ExportedInvoice>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -8964,6 +8980,21 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func getStarGifts(hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarGifts>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1000983152)
|
||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.getStarGifts", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarGifts? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.payments.StarGifts?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.payments.StarGifts
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func getStarsGiftOptions(flags: Int32, userId: Api.InputUser?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.StarsGiftOption]>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -9129,6 +9160,23 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func getUserStarGifts(userId: Api.InputUser, offset: String, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.UserStarGifts>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1584580577)
|
||||
userId.serialize(buffer, true)
|
||||
serializeString(offset, buffer: buffer, boxed: false)
|
||||
serializeInt32(limit, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.getUserStarGifts", parameters: [("userId", String(describing: userId)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.UserStarGifts? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.payments.UserStarGifts?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.payments.UserStarGifts
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func launchPrepaidGiveaway(peer: Api.InputPeer, giveawayId: Int64, purpose: Api.InputStorePaymentPurpose) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -9162,6 +9210,23 @@ public extension Api.functions.payments {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func saveStarGift(flags: Int32, userId: Api.InputUser, msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-2018709362)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
userId.serialize(buffer, true)
|
||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "payments.saveStarGift", parameters: [("flags", String(describing: flags)), ("userId", String(describing: userId)), ("msgId", String(describing: msgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Bool?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func sendPaymentForm(flags: Int32, formId: Int64, invoice: Api.InputInvoice, requestedInfoId: String?, shippingOptionId: String?, credentials: Api.InputPaymentCredentials, tipAmount: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentResult>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -9184,13 +9249,12 @@ public extension Api.functions.payments {
|
|||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func sendStarsForm(flags: Int32, formId: Int64, invoice: Api.InputInvoice) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentResult>) {
|
||||
static func sendStarsForm(formId: Int64, invoice: Api.InputInvoice) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.PaymentResult>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(45839133)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(2040056084)
|
||||
serializeInt64(formId, buffer: buffer, boxed: false)
|
||||
invoice.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "payments.sendStarsForm", parameters: [("flags", String(describing: flags)), ("formId", String(describing: formId)), ("invoice", String(describing: invoice))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.PaymentResult? in
|
||||
return (FunctionDescription(name: "payments.sendStarsForm", parameters: [("formId", String(describing: formId)), ("invoice", String(describing: invoice))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.PaymentResult? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.payments.PaymentResult?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
|
|||
|
|
@ -227,7 +227,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:
|
||||
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:
|
||||
break
|
||||
case let .messageActionChannelMigrateFrom(_, chatId):
|
||||
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))
|
||||
|
|
|
|||
|
|
@ -150,6 +150,21 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
|||
return TelegramMediaAction(action: .paymentRefunded(peerId: peer.peerId, currency: currency, totalAmount: totalAmount, payload: payload?.makeData(), transactionId: transactionId))
|
||||
case let .messageActionPrizeStars(flags, stars, transactionId, boostPeer, giveawayMsgId):
|
||||
return TelegramMediaAction(action: .prizeStars(amount: stars, isUnclaimed: (flags & (1 << 2)) != 0, boostPeerId: boostPeer.peerId, transactionId: transactionId, giveawayMessageId: MessageId(peerId: boostPeer.peerId, namespace: Namespaces.Message.Cloud, id: giveawayMsgId)))
|
||||
case let .messageActionStarGift(flags, apiGift, message, convertStars):
|
||||
let text: String?
|
||||
let entities: [MessageTextEntity]?
|
||||
switch message {
|
||||
case let .textWithEntities(textValue, entitiesValue):
|
||||
text = textValue
|
||||
entities = messageTextEntitiesFromApiEntities(entitiesValue)
|
||||
default:
|
||||
text = nil
|
||||
entities = nil
|
||||
}
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramMediaAction(action: .starGift(gift: gift, convertStars: convertStars, text: text, entities: entities, nameHidden: (flags & (1 << 0)) != 0, savedToProfile: (flags & (1 << 2)) != 0, converted: (flags & (1 << 3)) != 0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ final class AccountTaskManager {
|
|||
tasks.add(managedDisabledChannelStatusIconEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconTopicEmoji, forceActualized: true).start())
|
||||
tasks.add(managedPeerColorUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
tasks.add(managedStarGiftsUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
|
||||
self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
|
||||
|
|
|
|||
|
|
@ -1472,7 +1472,7 @@ public final class AccountViewTracker {
|
|||
if i < slice.count {
|
||||
let value = result[i]
|
||||
transaction.updatePeerCachedData(peerIds: Set([slice[i].0]), update: { _, cachedData in
|
||||
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, themeEmoticon: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, premiumGiftOptions: [], voiceMessagesAvailable: true, wallpaper: nil, flags: [], businessHours: nil, businessLocation: nil, greetingMessage: nil, awayMessage: nil, connectedBot: nil, businessIntro: .unknown, birthday: nil, personalChannel: .unknown, botPreview: nil)
|
||||
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, themeEmoticon: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, premiumGiftOptions: [], voiceMessagesAvailable: true, wallpaper: nil, flags: [], businessHours: nil, businessLocation: nil, greetingMessage: nil, awayMessage: nil, connectedBot: nil, businessIntro: .unknown, birthday: nil, personalChannel: .unknown, botPreview: nil, starGiftsCount: nil)
|
||||
var flags = cachedData.flags
|
||||
if case .boolTrue = value {
|
||||
flags.insert(.premiumRequired)
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 188
|
||||
return 189
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
|
|
|||
|
|
@ -744,6 +744,7 @@ public final class CachedUserData: CachedPeerData {
|
|||
public let birthday: TelegramBirthday?
|
||||
public let personalChannel: CachedTelegramPersonalChannel
|
||||
public let botPreview: BotPreview?
|
||||
public let starGiftsCount: Int32?
|
||||
|
||||
public let peerIds: Set<PeerId>
|
||||
public let messageIds: Set<MessageId>
|
||||
|
|
@ -782,9 +783,10 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.birthday = nil
|
||||
self.personalChannel = .unknown
|
||||
self.botPreview = nil
|
||||
self.starGiftsCount = nil
|
||||
}
|
||||
|
||||
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, premiumGiftOptions: [CachedPremiumGiftOption], voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?) {
|
||||
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, premiumGiftOptions: [CachedPremiumGiftOption], voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?, greetingMessage: TelegramBusinessGreetingMessage?, awayMessage: TelegramBusinessAwayMessage?, connectedBot: TelegramAccountConnectedBot?, businessIntro: CachedTelegramBusinessIntro, birthday: TelegramBirthday?, personalChannel: CachedTelegramPersonalChannel, botPreview: BotPreview?, starGiftsCount: Int32?) {
|
||||
self.about = about
|
||||
self.botInfo = botInfo
|
||||
self.editableBotInfo = editableBotInfo
|
||||
|
|
@ -815,6 +817,7 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.birthday = birthday
|
||||
self.personalChannel = personalChannel
|
||||
self.botPreview = botPreview
|
||||
self.starGiftsCount = starGiftsCount
|
||||
|
||||
self.peerIds = Set<PeerId>()
|
||||
|
||||
|
|
@ -880,6 +883,8 @@ public final class CachedUserData: CachedPeerData {
|
|||
self.personalChannel = decoder.decodeCodable(CachedTelegramPersonalChannel.self, forKey: "pchan") ?? .unknown
|
||||
|
||||
self.botPreview = decoder.decodeCodable(BotPreview.self, forKey: "botPreview")
|
||||
|
||||
self.starGiftsCount = decoder.decodeOptionalInt32ForKey("starGiftsCount")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -985,6 +990,12 @@ public final class CachedUserData: CachedPeerData {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "botPreview")
|
||||
}
|
||||
|
||||
if let starGiftsCount = self.starGiftsCount {
|
||||
encoder.encodeInt32(starGiftsCount, forKey: "starGiftsCount")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "starGiftsCount")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(to: CachedPeerData) -> Bool {
|
||||
|
|
@ -1025,128 +1036,135 @@ public final class CachedUserData: CachedPeerData {
|
|||
if other.botPreview != self.botPreview {
|
||||
return false
|
||||
}
|
||||
if other.starGiftsCount != self.starGiftsCount {
|
||||
return false
|
||||
}
|
||||
|
||||
return other.about == self.about && other.botInfo == self.botInfo && other.editableBotInfo == self.editableBotInfo && self.peerStatusSettings == other.peerStatusSettings && self.isBlocked == other.isBlocked && self.commonGroupCount == other.commonGroupCount && self.voiceCallsAvailable == other.voiceCallsAvailable && self.videoCallsAvailable == other.videoCallsAvailable && self.callsPrivate == other.callsPrivate && self.hasScheduledMessages == other.hasScheduledMessages && self.autoremoveTimeout == other.autoremoveTimeout && self.themeEmoticon == other.themeEmoticon && self.photo == other.photo && self.personalPhoto == other.personalPhoto && self.fallbackPhoto == other.fallbackPhoto && self.premiumGiftOptions == other.premiumGiftOptions && self.voiceMessagesAvailable == other.voiceMessagesAvailable && self.flags == other.flags && self.wallpaper == other.wallpaper
|
||||
}
|
||||
|
||||
public func withUpdatedAbout(_ about: String?) -> CachedUserData {
|
||||
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBotInfo(_ botInfo: BotInfo?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedEditableBotInfo(_ editableBotInfo: EditableBotInfo?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedIsBlocked(_ isBlocked: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedCommonGroupCount(_ commonGroupCount: Int32) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedVoiceCallsAvailable(_ voiceCallsAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedVideoCallsAvailable(_ videoCallsAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedCallsPrivate(_ callsPrivate: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedCanPinMessages(_ canPinMessages: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedThemeEmoticon(_ themeEmoticon: String?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPhoto(_ photo: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPersonalPhoto(_ personalPhoto: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedFallbackPhoto(_ fallbackPhoto: CachedPeerProfilePhoto) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPremiumGiftOptions(_ premiumGiftOptions: [CachedPremiumGiftOption]) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedFlags(_ flags: CachedUserFlags) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessHours(_ businessHours: TelegramBusinessHours?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessLocation(_ businessLocation: TelegramBusinessLocation?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedGreetingMessage(_ greetingMessage: TelegramBusinessGreetingMessage?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedAwayMessage(_ awayMessage: TelegramBusinessAwayMessage?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedConnectedBot(_ connectedBot: TelegramAccountConnectedBot?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBusinessIntro(_ businessIntro: TelegramBusinessIntro?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: .known(businessIntro), birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: .known(businessIntro), birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBirthday(_ birthday: TelegramBirthday?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: birthday, personalChannel: self.personalChannel, botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedPersonalChannel(_ personalChannel: TelegramPersonalChannel?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: .known(personalChannel), botPreview: self.botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: .known(personalChannel), botPreview: self.botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedBotPreview(_ botPreview: BotPreview?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: botPreview)
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: botPreview, starGiftsCount: self.starGiftsCount)
|
||||
}
|
||||
|
||||
public func withUpdatedStarGiftsCount(_ starGiftsCount: Int32?) -> CachedUserData {
|
||||
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation, greetingMessage: self.greetingMessage, awayMessage: self.awayMessage, connectedBot: self.connectedBot, businessIntro: self.businessIntro, birthday: self.birthday, personalChannel: self.personalChannel, botPreview: self.botPreview, starGiftsCount: starGiftsCount)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ private enum PreferencesKeyValues: Int32 {
|
|||
case timezoneList = 38
|
||||
case botBiometricsState = 39
|
||||
case businessLinks = 40
|
||||
case starGifts = 41
|
||||
}
|
||||
|
||||
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
||||
|
|
@ -524,6 +525,12 @@ public struct PreferencesKeys {
|
|||
key.setInt32(0, value: PreferencesKeyValues.businessLinks.rawValue)
|
||||
return key
|
||||
}
|
||||
|
||||
public static func starGifts() -> ValueBoxKey {
|
||||
let key = ValueBoxKey(length: 4)
|
||||
key.setInt32(0, value: PreferencesKeyValues.starGifts.rawValue)
|
||||
return key
|
||||
}
|
||||
}
|
||||
|
||||
private enum SharedDataKeyValues: Int32 {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
case paymentRefunded(peerId: PeerId, currency: String, totalAmount: Int64, payload: Data?, transactionId: String)
|
||||
case giftStars(currency: String, amount: Int64, count: Int64, cryptoCurrency: String?, cryptoAmount: Int64?, transactionId: String?)
|
||||
case prizeStars(amount: Int64, isUnclaimed: Bool, boostPeerId: PeerId?, transactionId: String?, giveawayMessageId: MessageId?)
|
||||
case starGift(gift: StarGift, convertStars: Int64, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, converted: Bool)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
|
|
@ -250,6 +251,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
giveawayMessageId = MessageId(peerId: boostPeerId, namespace: Namespaces.Message.Cloud, id: giveawayMsgId)
|
||||
}
|
||||
self = .prizeStars(amount: decoder.decodeInt64ForKey("amount", orElse: 0), isUnclaimed: decoder.decodeBoolForKey("unclaimed", orElse: false), boostPeerId: boostPeerId, transactionId: decoder.decodeOptionalStringForKey("transactionId"), giveawayMessageId: giveawayMessageId)
|
||||
case 44:
|
||||
self = .starGift(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, convertStars: decoder.decodeInt64ForKey("convertStars", orElse: 0), text: decoder.decodeOptionalStringForKey("text"), entities: decoder.decodeOptionalObjectArrayWithDecoderForKey("entities"), nameHidden: decoder.decodeBoolForKey("nameHidden", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), converted: decoder.decodeBoolForKey("converted", orElse: false))
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
|
|
@ -525,6 +528,20 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||
} else {
|
||||
encoder.encodeNil(forKey: "giveawayMsgId")
|
||||
}
|
||||
case let .starGift(gift, convertStars, text, entities, nameHidden, savedToProfile, converted):
|
||||
encoder.encodeInt32(44, forKey: "_rawValue")
|
||||
encoder.encodeObject(gift, forKey: "gift")
|
||||
encoder.encodeInt64(convertStars, forKey: "convertStars")
|
||||
if let text, let entities {
|
||||
encoder.encodeString(text, forKey: "text")
|
||||
encoder.encodeObjectArray(entities, forKey: "entities")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "text")
|
||||
encoder.encodeNil(forKey: "entities")
|
||||
}
|
||||
encoder.encodeBool(nameHidden, forKey: "nameHidden")
|
||||
encoder.encodeBool(savedToProfile, forKey: "savedToProfile")
|
||||
encoder.encodeBool(converted, forKey: "converted")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public enum BotPaymentInvoiceSource {
|
|||
case starsGift(peerId: EnginePeer.Id, count: Int64, currency: String, amount: Int64)
|
||||
case starsChatSubscription(hash: String)
|
||||
case starsGiveaway(stars: Int64, boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32, currency: String, amount: Int64, users: Int32)
|
||||
case starGift(hideName: Bool, peerId: EnginePeer.Id, giftId: Int64, text: String?, entities: [MessageTextEntity]?)
|
||||
}
|
||||
|
||||
public struct BotPaymentInvoiceFields: OptionSet {
|
||||
|
|
@ -130,7 +131,7 @@ public struct BotPaymentForm : Equatable {
|
|||
public let canSaveCredentials: Bool
|
||||
public let passwordMissing: Bool
|
||||
public let invoice: BotPaymentInvoice
|
||||
public let paymentBotId: PeerId
|
||||
public let paymentBotId: PeerId?
|
||||
public let providerId: PeerId?
|
||||
public let url: String?
|
||||
public let nativeProvider: BotPaymentNativeProvider?
|
||||
|
|
@ -138,7 +139,7 @@ public struct BotPaymentForm : Equatable {
|
|||
public let savedCredentials: [BotPaymentSavedCredentials]
|
||||
public let additionalPaymentMethods: [BotPaymentMethod]
|
||||
|
||||
public init(id: Int64, canSaveCredentials: Bool, passwordMissing: Bool, invoice: BotPaymentInvoice, paymentBotId: PeerId, providerId: PeerId?, url: String?, nativeProvider: BotPaymentNativeProvider?, savedInfo: BotPaymentRequestedInfo?, savedCredentials: [BotPaymentSavedCredentials], additionalPaymentMethods: [BotPaymentMethod]) {
|
||||
public init(id: Int64, canSaveCredentials: Bool, passwordMissing: Bool, invoice: BotPaymentInvoice, paymentBotId: PeerId?, providerId: PeerId?, url: String?, nativeProvider: BotPaymentNativeProvider?, savedInfo: BotPaymentRequestedInfo?, savedCredentials: [BotPaymentSavedCredentials], additionalPaymentMethods: [BotPaymentMethod]) {
|
||||
self.id = id
|
||||
self.canSaveCredentials = canSaveCredentials
|
||||
self.passwordMissing = passwordMissing
|
||||
|
|
@ -345,6 +346,20 @@ func _internal_parseInputInvoice(transaction: Transaction, source: BotPaymentInv
|
|||
flags |= (1 << 4)
|
||||
}
|
||||
return .inputInvoiceStars(purpose: .inputStorePaymentStarsGiveaway(flags: flags, stars: stars, boostPeer: apiBoostPeer, additionalPeers: additionalPeers, countriesIso2: countries, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate, currency: currency, amount: amount, users: users))
|
||||
case let .starGift(hideName, peerId, giftId, text, entities):
|
||||
guard let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) else {
|
||||
return nil
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
if hideName {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
var message: Api.TextWithEntities?
|
||||
if let text, !text.isEmpty {
|
||||
flags |= (1 << 1)
|
||||
message = .textWithEntities(text: text, entities: entities.flatMap { apiEntitiesFromMessageTextEntities($0, associatedPeers: SimpleDictionary()) } ?? [])
|
||||
}
|
||||
return .inputInvoiceStarGift(flags: flags, userId: inputUser, giftId: giftId, message: message)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,6 +397,9 @@ func _internal_fetchBotPaymentInvoice(postbox: Postbox, network: Network, source
|
|||
case let .paymentFormStars(_, _, _, title, description, photo, invoice, _):
|
||||
let parsedInvoice = BotPaymentInvoice(apiInvoice: invoice)
|
||||
return TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: parsedInvoice.prices.reduce(0, { $0 + $1.amount }), startParam: "", extendedMedia: nil, flags: [], version: TelegramMediaInvoice.lastVersion)
|
||||
case let .paymentFormStarGift(_, invoice):
|
||||
let parsedInvoice = BotPaymentInvoice(apiInvoice: invoice)
|
||||
return TelegramMediaInvoice(title: "", description: "", photo: nil, receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: parsedInvoice.prices.reduce(0, { $0 + $1.amount }), startParam: "", extendedMedia: nil, flags: [], version: TelegramMediaInvoice.lastVersion)
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> BotPaymentFormRequestError in }
|
||||
|
|
@ -452,6 +470,10 @@ func _internal_fetchBotPaymentForm(accountPeerId: PeerId, postbox: Postbox, netw
|
|||
|
||||
let parsedInvoice = BotPaymentInvoice(apiInvoice: invoice)
|
||||
return BotPaymentForm(id: id, canSaveCredentials: false, passwordMissing: false, invoice: parsedInvoice, paymentBotId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)), providerId: nil, url: nil, nativeProvider: nil, savedInfo: nil, savedCredentials: [], additionalPaymentMethods: [])
|
||||
|
||||
case let .paymentFormStarGift(id, invoice):
|
||||
let parsedInvoice = BotPaymentInvoice(apiInvoice: invoice)
|
||||
return BotPaymentForm(id: id, canSaveCredentials: false, passwordMissing: false, invoice: parsedInvoice, paymentBotId: nil, providerId: nil, url: nil, nativeProvider: nil, savedInfo: nil, savedCredentials: [], additionalPaymentMethods: [])
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> BotPaymentFormRequestError in }
|
||||
|
|
@ -660,7 +682,7 @@ func _internal_sendBotPaymentForm(account: Account, formId: Int64, source: BotPa
|
|||
receiptMessageId = id
|
||||
}
|
||||
}
|
||||
case .giftCode, .stars, .starsGift, .starsChatSubscription:
|
||||
case .giftCode, .stars, .starsGift, .starsChatSubscription, .starGift:
|
||||
receiptMessageId = nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,462 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import MtProtoKit
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
|
||||
public final class StarGiftsList: Codable, Equatable {
|
||||
public let items: [StarGift]
|
||||
public let hashValue: Int32
|
||||
|
||||
public init(items: [StarGift], hashValue: Int32) {
|
||||
self.items = items
|
||||
self.hashValue = hashValue
|
||||
}
|
||||
|
||||
public static func ==(lhs: StarGiftsList, rhs: StarGiftsList) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
if lhs.hashValue != rhs.hashValue {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public struct StarGift: Equatable, Codable, PostboxCoding {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case file
|
||||
case price
|
||||
case convertStars
|
||||
case availability
|
||||
}
|
||||
|
||||
public struct Availability: Equatable, Codable, PostboxCoding {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case remains
|
||||
case total
|
||||
}
|
||||
|
||||
public let remains: Int32
|
||||
public let total: Int32
|
||||
|
||||
init(remains: Int32, total: Int32) {
|
||||
self.remains = remains
|
||||
self.total = total
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.remains = decoder.decodeInt32ForKey(CodingKeys.remains.rawValue, orElse: 0)
|
||||
self.total = decoder.decodeInt32ForKey(CodingKeys.total.rawValue, orElse: 0)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt32(self.remains, forKey: CodingKeys.remains.rawValue)
|
||||
encoder.encodeInt32(self.total, forKey: CodingKeys.total.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
public enum DecodingError: Error {
|
||||
case generic
|
||||
}
|
||||
|
||||
public let id: Int64
|
||||
public let file: TelegramMediaFile
|
||||
public let price: Int64
|
||||
public let convertStars: Int64
|
||||
public let availability: Availability?
|
||||
|
||||
public init(id: Int64, file: TelegramMediaFile, price: Int64, convertStars: Int64, availability: Availability?) {
|
||||
self.id = id
|
||||
self.file = file
|
||||
self.price = price
|
||||
self.convertStars = convertStars
|
||||
self.availability = availability
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.id = try container.decode(Int64.self, forKey: .id)
|
||||
|
||||
if let fileData = try container.decodeIfPresent(Data.self, forKey: .file), let file = PostboxDecoder(buffer: MemoryBuffer(data: fileData)).decodeRootObject() as? TelegramMediaFile {
|
||||
self.file = file
|
||||
} else {
|
||||
throw DecodingError.generic
|
||||
}
|
||||
|
||||
self.price = try container.decode(Int64.self, forKey: .price)
|
||||
self.convertStars = try container.decodeIfPresent(Int64.self, forKey: .convertStars) ?? 0
|
||||
self.availability = try container.decodeIfPresent(Availability.self, forKey: .availability)
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.id = decoder.decodeInt64ForKey(CodingKeys.id.rawValue, orElse: 0)
|
||||
self.file = decoder.decodeObjectForKey(CodingKeys.file.rawValue) as! TelegramMediaFile
|
||||
self.price = decoder.decodeInt64ForKey(CodingKeys.price.rawValue, orElse: 0)
|
||||
self.convertStars = decoder.decodeInt64ForKey(CodingKeys.convertStars.rawValue, orElse: 0)
|
||||
self.availability = decoder.decodeObjectForKey(CodingKeys.availability.rawValue, decoder: { StarGift.Availability(decoder: $0) }) as? StarGift.Availability
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(self.id, forKey: .id)
|
||||
|
||||
let encoder = PostboxEncoder()
|
||||
encoder.encodeRootObject(self.file)
|
||||
let fileData = encoder.makeData()
|
||||
try container.encode(fileData, forKey: .file)
|
||||
|
||||
try container.encode(self.price, forKey: .price)
|
||||
try container.encode(self.convertStars, forKey: .convertStars)
|
||||
try container.encodeIfPresent(self.availability, forKey: .availability)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeInt64(self.id, forKey: CodingKeys.id.rawValue)
|
||||
encoder.encodeObject(self.file, forKey: CodingKeys.file.rawValue)
|
||||
encoder.encodeInt64(self.price, forKey: CodingKeys.price.rawValue)
|
||||
encoder.encodeInt64(self.convertStars, forKey: CodingKeys.convertStars.rawValue)
|
||||
if let availability = self.availability {
|
||||
encoder.encodeObject(availability, forKey: CodingKeys.availability.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.availability.rawValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension StarGift {
|
||||
init?(apiStarGift: Api.StarGift) {
|
||||
switch apiStarGift {
|
||||
case let .starGift(_, id, sticker, stars, availabilityRemains, availabilityTotal, convertStars):
|
||||
var availability: Availability?
|
||||
if let availabilityRemains, let availabilityTotal {
|
||||
availability = Availability(remains: availabilityRemains, total: availabilityTotal)
|
||||
}
|
||||
guard let file = telegramMediaFileFromApiDocument(sticker, altDocuments: nil) else {
|
||||
return nil
|
||||
}
|
||||
self.init(id: id, file: file, price: stars, convertStars: convertStars, availability: availability)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_cachedStarGifts(postbox: Postbox) -> Signal<StarGiftsList?, NoError> {
|
||||
let viewKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.starGifts()]))
|
||||
return postbox.combinedView(keys: [viewKey])
|
||||
|> map { views -> StarGiftsList? in
|
||||
guard let view = views.views[viewKey] as? PreferencesView else {
|
||||
return nil
|
||||
}
|
||||
guard let value = view.values[PreferencesKeys.starGifts()]?.get(StarGiftsList.self) else {
|
||||
return nil
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||
let updateSignal = _internal_cachedStarGifts(postbox: postbox)
|
||||
|> take(1)
|
||||
|> mapToSignal { list -> Signal<Never, NoError> in
|
||||
return network.request(Api.functions.payments.getStarGifts(hash: 0))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.payments.StarGifts?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
guard let result else {
|
||||
return .complete()
|
||||
}
|
||||
|
||||
return postbox.transaction { transaction in
|
||||
switch result {
|
||||
case let .starGifts(hash, gifts):
|
||||
let starGiftsLists = StarGiftsList(items: gifts.compactMap { StarGift(apiStarGift: $0) }, hashValue: hash)
|
||||
transaction.setPreferencesEntry(key: PreferencesKeys.starGifts(), value: PreferencesEntry(starGiftsLists))
|
||||
case .starGiftsNotModified:
|
||||
break
|
||||
}
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
return updateSignal
|
||||
}
|
||||
|
||||
func managedStarGiftsUpdates(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||
let poll = _internal_keepCachedStarGiftsUpdated(postbox: postbox, network: network)
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(2.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
||||
|
||||
func _internal_convertStarGift(account: Account, messageId: EngineMessage.Id) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||
return transaction.getPeer(messageId.peerId).flatMap(apiInputUser)
|
||||
}
|
||||
|> mapToSignal { inputUser -> Signal<Never, NoError> in
|
||||
guard let inputUser else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.payments.convertStarGift(userId: inputUser, msgId: messageId.id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_updateStarGiftAddedToProfile(account: Account, messageId: EngineMessage.Id, added: Bool) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||
return transaction.getPeer(messageId.peerId).flatMap(apiInputUser)
|
||||
}
|
||||
|> mapToSignal { inputUser -> Signal<Never, NoError> in
|
||||
guard let inputUser else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
if !added {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
return account.network.request(Api.functions.payments.saveStarGift(flags: flags, userId: inputUser, msgId: messageId.id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Bool?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProfileGiftsContextImpl {
|
||||
private let queue: Queue
|
||||
private let account: Account
|
||||
private let peerId: PeerId
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
private let actionDisposable = MetaDisposable()
|
||||
|
||||
private var gifts: [ProfileGiftsContext.State.StarGift] = []
|
||||
private var count: Int32?
|
||||
private var dataState: ProfileGiftsContext.State.DataState = .ready(canLoadMore: true, nextOffset: nil)
|
||||
|
||||
private let stateValue = Promise<ProfileGiftsContext.State>()
|
||||
var state: Signal<ProfileGiftsContext.State, NoError> {
|
||||
return self.stateValue.get()
|
||||
}
|
||||
|
||||
init(queue: Queue, account: Account, peerId: EnginePeer.Id) {
|
||||
self.queue = queue
|
||||
self.account = account
|
||||
self.peerId = peerId
|
||||
|
||||
self.loadMore()
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable.dispose()
|
||||
self.actionDisposable.dispose()
|
||||
}
|
||||
|
||||
func loadMore() {
|
||||
if case let .ready(true, nextOffset) = self.dataState {
|
||||
self.dataState = .loading
|
||||
self.pushState()
|
||||
|
||||
let peerId = self.peerId
|
||||
let accountPeerId = self.account.peerId
|
||||
let network = self.account.network
|
||||
let postbox = self.account.postbox
|
||||
let signal: Signal<([ProfileGiftsContext.State.StarGift], Int32, String?), NoError> = self.account.postbox.transaction { transaction -> Api.InputUser? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputUser)
|
||||
}
|
||||
|> mapToSignal { inputUser -> Signal<([ProfileGiftsContext.State.StarGift], Int32, String?), NoError> in
|
||||
guard let inputUser else {
|
||||
return .single(([], 0, nil))
|
||||
}
|
||||
return network.request(Api.functions.payments.getUserStarGifts(userId: inputUser, offset: nextOffset ?? "", limit: 32))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.payments.UserStarGifts?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<([ProfileGiftsContext.State.StarGift], Int32, String?), NoError> in
|
||||
guard let result else {
|
||||
return .single(([], 0, nil))
|
||||
}
|
||||
return postbox.transaction { transaction -> ([ProfileGiftsContext.State.StarGift], Int32, String?) in
|
||||
switch result {
|
||||
case let .userStarGifts(_, count, apiGifts, nextOffset, users):
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [], users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
|
||||
let gifts = apiGifts.compactMap { ProfileGiftsContext.State.StarGift(apiUserStarGift: $0, transaction: transaction) }
|
||||
return (gifts, count, nextOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.disposable.set((signal
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] (gifts, count, nextOffset) in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
for gift in gifts {
|
||||
strongSelf.gifts.append(gift)
|
||||
}
|
||||
|
||||
let updatedCount = max(Int32(strongSelf.gifts.count), count)
|
||||
strongSelf.count = updatedCount
|
||||
strongSelf.dataState = .ready(canLoadMore: count != 0 && updatedCount > strongSelf.gifts.count && nextOffset != nil, nextOffset: nextOffset)
|
||||
strongSelf.pushState()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
func updateStarGiftAddedToProfile(messageId: EngineMessage.Id, added: Bool) {
|
||||
self.actionDisposable.set(
|
||||
_internal_updateStarGiftAddedToProfile(account: self.account, messageId: messageId, added: added).startStrict()
|
||||
)
|
||||
if let index = self.gifts.firstIndex(where: { $0.messageId == messageId }) {
|
||||
self.gifts[index] = self.gifts[index].withSavedToProfile(added)
|
||||
}
|
||||
self.pushState()
|
||||
}
|
||||
|
||||
func convertStarGift(messageId: EngineMessage.Id) {
|
||||
self.actionDisposable.set(
|
||||
_internal_convertStarGift(account: self.account, messageId: messageId).startStrict()
|
||||
)
|
||||
if let count = self.count {
|
||||
self.count = max(0, count - 1)
|
||||
}
|
||||
self.gifts.removeAll(where: { $0.messageId == messageId })
|
||||
self.pushState()
|
||||
}
|
||||
|
||||
private func pushState() {
|
||||
self.stateValue.set(.single(ProfileGiftsContext.State(gifts: self.gifts, count: self.count, dataState: self.dataState)))
|
||||
}
|
||||
}
|
||||
|
||||
public final class ProfileGiftsContext {
|
||||
public struct State: Equatable {
|
||||
public struct StarGift: Equatable {
|
||||
public let gift: TelegramCore.StarGift
|
||||
public let fromPeer: EnginePeer?
|
||||
public let date: Int32
|
||||
public let text: String?
|
||||
public let entities: [MessageTextEntity]?
|
||||
public let messageId: EngineMessage.Id?
|
||||
public let nameHidden: Bool
|
||||
public let savedToProfile: Bool
|
||||
public let convertStars: Int64?
|
||||
|
||||
public func withSavedToProfile(_ savedToProfile: Bool) -> StarGift {
|
||||
return StarGift(
|
||||
gift: self.gift,
|
||||
fromPeer: self.fromPeer,
|
||||
date: self.date,
|
||||
text: self.text,
|
||||
entities: self.entities,
|
||||
messageId: self.messageId,
|
||||
nameHidden: self.nameHidden,
|
||||
savedToProfile: savedToProfile,
|
||||
convertStars: self.convertStars
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public enum DataState: Equatable {
|
||||
case loading
|
||||
case ready(canLoadMore: Bool, nextOffset: String?)
|
||||
}
|
||||
|
||||
public var gifts: [ProfileGiftsContext.State.StarGift]
|
||||
public var count: Int32?
|
||||
public var dataState: ProfileGiftsContext.State.DataState
|
||||
}
|
||||
|
||||
private let queue: Queue = .mainQueue()
|
||||
private let impl: QueueLocalObject<ProfileGiftsContextImpl>
|
||||
|
||||
public var state: Signal<ProfileGiftsContext.State, NoError> {
|
||||
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: EnginePeer.Id) {
|
||||
let queue = self.queue
|
||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||
return ProfileGiftsContextImpl(queue: queue, account: account, peerId: peerId)
|
||||
})
|
||||
}
|
||||
|
||||
public func loadMore() {
|
||||
self.impl.with { impl in
|
||||
impl.loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
public func updateStarGiftAddedToProfile(messageId: EngineMessage.Id, added: Bool) {
|
||||
self.impl.with { impl in
|
||||
impl.updateStarGiftAddedToProfile(messageId: messageId, added: added)
|
||||
}
|
||||
}
|
||||
|
||||
public func convertStarGift(messageId: EngineMessage.Id) {
|
||||
self.impl.with { impl in
|
||||
impl.convertStarGift(messageId: messageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ProfileGiftsContext.State.StarGift {
|
||||
init?(apiUserStarGift: Api.UserStarGift, transaction: Transaction) {
|
||||
switch apiUserStarGift {
|
||||
case let .userStarGift(flags, fromId, date, apiGift, message, msgId, convertStars):
|
||||
guard let gift = StarGift(apiStarGift: apiGift) else {
|
||||
return nil
|
||||
}
|
||||
self.gift = gift
|
||||
if let fromPeerId = fromId.flatMap({ EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value($0)) }) {
|
||||
self.fromPeer = transaction.getPeer(fromPeerId).flatMap(EnginePeer.init)
|
||||
} else {
|
||||
self.fromPeer = nil
|
||||
}
|
||||
self.date = date
|
||||
|
||||
if let message {
|
||||
switch message {
|
||||
case let .textWithEntities(text, entities):
|
||||
self.text = text
|
||||
self.entities = messageTextEntitiesFromApiEntities(entities)
|
||||
}
|
||||
} else {
|
||||
self.text = nil
|
||||
self.entities = nil
|
||||
}
|
||||
if let fromPeer = self.fromPeer, let msgId {
|
||||
self.messageId = EngineMessage.Id(peerId: fromPeer.id, namespace: Namespaces.Message.Cloud, id: msgId)
|
||||
} else {
|
||||
self.messageId = nil
|
||||
}
|
||||
self.nameHidden = (flags & (1 << 0)) != 0
|
||||
self.savedToProfile = (flags & (1 << 5)) == 0
|
||||
self.convertStars = convertStars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1229,10 +1229,7 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
|||
guard let invoice = invoice else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
let flags: Int32 = 0
|
||||
|
||||
return account.network.request(Api.functions.payments.sendStarsForm(flags: flags, formId: formId, invoice: invoice))
|
||||
return account.network.request(Api.functions.payments.sendStarsForm(formId: formId, invoice: invoice))
|
||||
|> map { result -> SendBotPaymentResult in
|
||||
switch result {
|
||||
case let .paymentResult(updates):
|
||||
|
|
@ -1288,6 +1285,8 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
|||
receiptMessageId = nil
|
||||
case .starsChatSubscription:
|
||||
receiptMessageId = nil
|
||||
case .starGift:
|
||||
receiptMessageId = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,5 +101,24 @@ public extension TelegramEngine {
|
|||
public func fulfillStarsSubscription(peerId: EnginePeer.Id, subscriptionId: String) -> Signal<Never, FulfillStarsSubsciptionError> {
|
||||
return _internal_fulfillStarsSubscription(account: self.account, peerId: peerId, subscriptionId: subscriptionId)
|
||||
}
|
||||
|
||||
public func cachedStarGifts() -> Signal<[StarGift]?, NoError> {
|
||||
return _internal_cachedStarGifts(postbox: self.account.postbox)
|
||||
|> map { starGiftsList in
|
||||
return starGiftsList?.items
|
||||
}
|
||||
}
|
||||
|
||||
public func keepStarGiftsUpdated() -> Signal<Never, NoError> {
|
||||
return _internal_keepCachedStarGiftsUpdated(postbox: self.account.postbox, network: self.account.network)
|
||||
}
|
||||
|
||||
public func convertStarGift(messageId: EngineMessage.Id) -> Signal<Never, NoError> {
|
||||
return _internal_convertStarGift(account: self.account, messageId: messageId)
|
||||
}
|
||||
|
||||
public func updateStarGiftAddedToProfile(messageId: EngineMessage.Id, added: Bool) -> Signal<Never, NoError> {
|
||||
return _internal_updateStarGiftAddedToProfile(account: self.account, messageId: messageId, added: added)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
}
|
||||
|
||||
switch fullUser {
|
||||
case let .userFull(_, _, _, _, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .userFull(_, _, _, _, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: userFullNotifySettings)])
|
||||
}
|
||||
|
|
@ -270,7 +270,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
previous = CachedUserData()
|
||||
}
|
||||
switch fullUser {
|
||||
case let .userFull(userFullFlags, userFullFlags2, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage):
|
||||
case let .userFull(userFullFlags, userFullFlags2, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage, starGiftsCount):
|
||||
let _ = stories
|
||||
let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:))
|
||||
let isBlocked = (userFullFlags & (1 << 0)) != 0
|
||||
|
|
@ -414,6 +414,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
.withUpdatedBirthday(mappedBirthday)
|
||||
.withUpdatedPersonalChannel(personalChannel)
|
||||
.withUpdatedBotPreview(botPreview)
|
||||
.withUpdatedStarGiftsCount(starGiftsCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,7 +286,6 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
|||
reactionActiveMediaPlaceholder: UIColor(rgb: 0xffffff, alpha: 0.2)
|
||||
)
|
||||
),
|
||||
linkHighlightColor: accentColor?.withAlphaComponent(0.3),
|
||||
accentTextColor: accentColor,
|
||||
accentControlColor: accentColor,
|
||||
accentControlDisabledColor: accentColor?.withAlphaComponent(0.7),
|
||||
|
|
@ -331,7 +330,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
|||
primaryTextColor: outgoingPrimaryTextColor,
|
||||
secondaryTextColor: outgoingSecondaryTextColor,
|
||||
linkTextColor: outgoingLinkTextColor,
|
||||
linkHighlightColor: day ? nil : accentColor?.withAlphaComponent(0.3),
|
||||
linkHighlightColor: day ? nil : outgoingLinkTextColor?.withAlphaComponent(0.3),
|
||||
scamColor: outgoingScamColor,
|
||||
accentTextColor: outgoingAccentTextColor,
|
||||
accentControlColor: outgoingControlColor,
|
||||
|
|
|
|||
|
|
@ -1051,6 +1051,27 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
attributedString = mutableString
|
||||
case .prizeStars:
|
||||
attributedString = NSAttributedString(string: strings.Notification_StarsPrize, font: titleFont, textColor: primaryTextColor)
|
||||
case let .starGift(gift, _, nameHidden, limitNumber, limitTotal, text, entities):
|
||||
let _ = nameHidden
|
||||
let _ = limitNumber
|
||||
let _ = limitTotal
|
||||
let _ = text
|
||||
let _ = entities
|
||||
|
||||
let starsPrice = "\(gift.price) Stars"
|
||||
var authorName = compactAuthorName
|
||||
var peerIds: [(Int, EnginePeer.Id?)] = [(0, message.author?.id)]
|
||||
if message.id.peerId.namespace == Namespaces.Peer.CloudUser && message.id.peerId.id._internalGetInt64Value() == 777000 {
|
||||
authorName = strings.Notification_StarsGift_UnknownUser
|
||||
peerIds = []
|
||||
}
|
||||
if message.author?.id == accountPeerId {
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_SentYou(starsPrice)._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
} else {
|
||||
var attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributes[1] = boldAttributes
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Sent(authorName, starsPrice)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
case .unknown:
|
||||
attributedString = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -459,6 +459,8 @@ swift_library(
|
|||
"//submodules/TelegramUI/Components/MinimizedContainer",
|
||||
"//submodules/TelegramUI/Components/SpaceWarpView",
|
||||
"//submodules/TelegramUI/Components/MiniAppListScreen",
|
||||
"//submodules/TelegramUI/Components/Stars/StarsIntroScreen",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftOptionsScreen",
|
||||
] + select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
||||
"//build-system:ios_sim_arm64": [],
|
||||
|
|
|
|||
|
|
@ -205,6 +205,8 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||
result.append((message, ChatMessageGiftBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
} else if case .giftStars = action.action {
|
||||
result.append((message, ChatMessageGiftBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
} else if case .starGift = action.action {
|
||||
result.append((message, ChatMessageGiftBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
skipText = true
|
||||
} else if case .suggestedProfilePhoto = action.action {
|
||||
result.append((message, ChatMessageProfilePhotoSuggestionContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
|
|
|
|||
|
|
@ -31,13 +31,16 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
private let backgroundMaskNode: ASImageNode
|
||||
private var linkHighlightingNode: LinkHighlightingNode?
|
||||
|
||||
private let mediaBackgroundMaskNode: ASImageNode
|
||||
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
|
||||
private let mediaBackgroundNode: NavigationBackgroundNode
|
||||
private let titleNode: TextNode
|
||||
private let subtitleNode: TextNode
|
||||
private let placeholderNode: StickerShimmerEffectNode
|
||||
private let animationNode: AnimatedStickerNode
|
||||
|
||||
private let ribbonBackgroundNode: ASImageNode
|
||||
private let ribbonTextNode: TextNode
|
||||
|
||||
private var shimmerEffectNode: ShimmerEffectForegroundNode?
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
private let buttonStarsNode: PremiumStarsNode
|
||||
|
|
@ -69,7 +72,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
}
|
||||
|
||||
private var animationDisposable: Disposable?
|
||||
private var fetchDisposable: Disposable?
|
||||
private var setupTimestamp: Double?
|
||||
|
||||
required public init() {
|
||||
|
|
@ -79,9 +82,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
|
||||
self.backgroundMaskNode = ASImageNode()
|
||||
|
||||
self.mediaBackgroundNode = NavigationBackgroundNode(color: .clear)
|
||||
self.mediaBackgroundNode.clipsToBounds = true
|
||||
self.mediaBackgroundNode.cornerRadius = 24.0
|
||||
self.mediaBackgroundMaskNode = ASImageNode()
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
|
|
@ -107,19 +108,30 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
self.buttonTitleNode.isUserInteractionEnabled = false
|
||||
self.buttonTitleNode.displaysAsynchronously = false
|
||||
|
||||
self.ribbonBackgroundNode = ASImageNode()
|
||||
self.ribbonBackgroundNode.displaysAsynchronously = false
|
||||
|
||||
self.ribbonTextNode = TextNode()
|
||||
self.ribbonTextNode.isUserInteractionEnabled = false
|
||||
self.ribbonTextNode.displaysAsynchronously = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.labelNode)
|
||||
|
||||
self.addSubnode(self.mediaBackgroundNode)
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.subtitleNode)
|
||||
self.addSubnode(self.subtitleNode)
|
||||
self.addSubnode(self.placeholderNode)
|
||||
self.addSubnode(self.animationNode)
|
||||
|
||||
self.addSubnode(self.buttonNode)
|
||||
self.buttonNode.addSubnode(self.buttonStarsNode)
|
||||
self.addSubnode(self.buttonTitleNode)
|
||||
|
||||
self.addSubnode(self.ribbonBackgroundNode)
|
||||
self.addSubnode(self.ribbonTextNode)
|
||||
|
||||
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
|
|
@ -144,7 +156,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
|
||||
deinit {
|
||||
self.animationDisposable?.dispose()
|
||||
self.fetchDisposable?.dispose()
|
||||
self.currentProgressDisposable?.dispose()
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +238,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
|
||||
let makeButtonTitleLayout = TextNode.asyncLayout(self.buttonTitleNode)
|
||||
|
||||
let makeRibbonTextLayout = TextNode.asyncLayout(self.ribbonTextNode)
|
||||
|
||||
let cachedMaskBackgroundImage = self.cachedMaskBackgroundImage
|
||||
|
||||
return { item, layoutConstants, _, _, _, _ in
|
||||
|
|
@ -243,9 +256,11 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
|
||||
var months: Int32 = 3
|
||||
var animationName: String = ""
|
||||
var animationFile: TelegramMediaFile?
|
||||
var title = item.presentationData.strings.Notification_PremiumGift_Title
|
||||
var text = ""
|
||||
var buttonTitle = item.presentationData.strings.Notification_PremiumGift_View
|
||||
var ribbonTitle = ""
|
||||
var hasServiceMessage = true
|
||||
var textSpacing: CGFloat = 0.0
|
||||
for media in item.message.media {
|
||||
|
|
@ -314,6 +329,39 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
buttonTitle = item.presentationData.strings.Notification_PremiumPrize_View
|
||||
hasServiceMessage = false
|
||||
}
|
||||
case let .starGift(gift, convertStars, giftText, entities, nameHidden, savedToProfile, converted):
|
||||
let _ = nameHidden
|
||||
//TODO:localize
|
||||
let authorName = item.message.author.flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
||||
title = "Gift from \(authorName)"
|
||||
if let giftText, !giftText.isEmpty {
|
||||
text = giftText
|
||||
let _ = entities
|
||||
} else {
|
||||
if incoming {
|
||||
if converted {
|
||||
text = "You converted this gift to \(convertStars) Stars."
|
||||
} else if savedToProfile {
|
||||
text = "You are displaying this gift on your page. You can also convert it to \(convertStars) Stars."
|
||||
} else {
|
||||
text = "Display this gift on your page or convert it to \(convertStars) Stars."
|
||||
}
|
||||
} else {
|
||||
var peerName = ""
|
||||
if let peer = item.message.peers[item.message.id.peerId] {
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
}
|
||||
if peerName.isEmpty {
|
||||
text = "Display this gift on your page or convert it to \(convertStars) Stars."
|
||||
} else {
|
||||
text = "\(peerName) can keep this gift on their page or convert it to \(convertStars) Stars."
|
||||
}
|
||||
}
|
||||
}
|
||||
animationFile = gift.file
|
||||
if let availability = gift.availability {
|
||||
ribbonTitle = "1 of \(availability.total)"
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
@ -347,6 +395,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: buttonTitle, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (ribbonTextLayout, ribbonTextApply) = makeRibbonTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: ribbonTitle, font: Font.semibold(11.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
giftSize.height = titleLayout.size.height + textSpacing + subtitleLayout.size.height + 212.0
|
||||
|
||||
|
|
@ -394,32 +444,67 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
return (backgroundSize.width, { boundingWidth in
|
||||
return (backgroundSize, { [weak self] animation, synchronousLoads, _ in
|
||||
if let strongSelf = self {
|
||||
let overlayColor = item.presentationData.theme.theme.overallDarkAppearance ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12)
|
||||
|
||||
let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 16.0 : 0.0), size: giftSize)
|
||||
let mediaBackgroundFrame = imageFrame.insetBy(dx: -2.0, dy: -2.0)
|
||||
|
||||
var iconSize = CGSize(width: 160.0, height: 160.0)
|
||||
var iconOffset: CGFloat = 0.0
|
||||
if let _ = animationFile {
|
||||
iconSize = CGSize(width: 120.0, height: 120.0)
|
||||
iconOffset = 32.0
|
||||
}
|
||||
let animationFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - iconSize.width) / 2.0), y: mediaBackgroundFrame.minY - 16.0 + iconOffset), size: iconSize)
|
||||
strongSelf.animationNode.frame = animationFrame
|
||||
|
||||
if strongSelf.item == nil {
|
||||
strongSelf.animationNode.started = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let current = CACurrentMediaTime()
|
||||
if let setupTimestamp = strongSelf.setupTimestamp, current - setupTimestamp > 0.3 {
|
||||
if !strongSelf.placeholderNode.alpha.isZero {
|
||||
strongSelf.animationNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
strongSelf.removePlaceholder(animated: true)
|
||||
}
|
||||
} else {
|
||||
strongSelf.removePlaceholder(animated: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.animationNode.autoplay = true
|
||||
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: 384, height: 384, playbackMode: .still(.end), mode: .direct(cachePathPrefix: nil))
|
||||
|
||||
if let file = animationFile {
|
||||
strongSelf.animationNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: file.resource), width: 384, height: 384, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
if strongSelf.fetchDisposable == nil {
|
||||
strongSelf.fetchDisposable = freeMediaFileResourceInteractiveFetched(postbox: item.context.account.postbox, userLocation: .other, fileReference: .message(message: MessageReference(item.message), media: file), resource: file.resource).start()
|
||||
}
|
||||
|
||||
if let immediateThumbnailData = file.immediateThumbnailData {
|
||||
let shimmeringColor = bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.stickerPlaceholderShimmerColor, wallpaper: item.presentationData.theme.wallpaper)
|
||||
strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: overlayColor, shimmeringColor: shimmeringColor, data: immediateThumbnailData, size: animationFrame.size, enableEffect: item.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||
}
|
||||
} else if animationName.hasPrefix("Gift") {
|
||||
strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: 384, height: 384, playbackMode: .still(.end), mode: .direct(cachePathPrefix: nil))
|
||||
}
|
||||
}
|
||||
strongSelf.item = item
|
||||
|
||||
|
||||
strongSelf.updateVisibility()
|
||||
|
||||
strongSelf.labelNode.isHidden = !hasServiceMessage
|
||||
|
||||
let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 16.0 : 0.0), size: giftSize)
|
||||
let mediaBackgroundFrame = imageFrame.insetBy(dx: -2.0, dy: -2.0)
|
||||
strongSelf.mediaBackgroundNode.frame = mediaBackgroundFrame
|
||||
|
||||
strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate)
|
||||
strongSelf.mediaBackgroundNode.update(size: mediaBackgroundFrame.size, transition: .immediate)
|
||||
strongSelf.buttonNode.backgroundColor = item.presentationData.theme.theme.overallDarkAppearance ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12)
|
||||
|
||||
let iconSize = CGSize(width: 160.0, height: 160.0)
|
||||
strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - iconSize.width) / 2.0), y: mediaBackgroundFrame.minY - 16.0), size: iconSize)
|
||||
strongSelf.buttonNode.backgroundColor = overlayColor
|
||||
|
||||
strongSelf.animationNode.updateLayout(size: iconSize)
|
||||
strongSelf.placeholderNode.frame = animationFrame
|
||||
|
||||
let _ = labelApply()
|
||||
let _ = titleApply()
|
||||
let _ = subtitleApply()
|
||||
let _ = buttonTitleApply()
|
||||
let _ = ribbonTextApply()
|
||||
|
||||
let labelFrame = CGRect(origin: CGPoint(x: 8.0, y: 2.0), size: labelLayout.size)
|
||||
strongSelf.labelNode.frame = labelFrame
|
||||
|
|
@ -436,23 +521,58 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
let buttonSize = CGSize(width: buttonTitleLayout.size.width + 38.0, height: 34.0)
|
||||
strongSelf.buttonNode.frame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - buttonSize.width) / 2.0), y: subtitleFrame.maxY + 10.0), size: buttonSize)
|
||||
strongSelf.buttonStarsNode.frame = CGRect(origin: .zero, size: buttonSize)
|
||||
|
||||
if item.controllerInteraction.presentationContext.backgroundNode?.hasExtraBubbleBackground() == true {
|
||||
if strongSelf.mediaBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||
strongSelf.mediaBackgroundNode.isHidden = true
|
||||
backgroundContent.clipsToBounds = true
|
||||
backgroundContent.allowsGroupOpacity = true
|
||||
backgroundContent.cornerRadius = 24.0
|
||||
|
||||
strongSelf.mediaBackgroundContent = backgroundContent
|
||||
strongSelf.insertSubnode(backgroundContent, at: 0)
|
||||
|
||||
if ribbonTextLayout.size.width > 0.0 {
|
||||
if strongSelf.ribbonBackgroundNode.image == nil {
|
||||
let ribbonImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/GiftRibbon"), color: overlayColor)
|
||||
strongSelf.ribbonBackgroundNode.image = ribbonImage
|
||||
}
|
||||
if let ribbonImage = strongSelf.ribbonBackgroundNode.image {
|
||||
let ribbonFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.maxX - ribbonImage.size.width + 2.0, y: mediaBackgroundFrame.minY - 2.0), size: ribbonImage.size)
|
||||
strongSelf.ribbonBackgroundNode.frame = ribbonFrame
|
||||
|
||||
strongSelf.ribbonTextNode.transform = CATransform3DMakeRotation(.pi / 4.0, 0.0, 0.0, 1.0)
|
||||
strongSelf.ribbonTextNode.bounds = CGRect(origin: .zero, size: ribbonTextLayout.size)
|
||||
strongSelf.ribbonTextNode.position = ribbonFrame.center.offsetBy(dx: 7.0, dy: -6.0)
|
||||
}
|
||||
}
|
||||
|
||||
if strongSelf.mediaBackgroundContent == nil, let backgroundContent = item.controllerInteraction.presentationContext.backgroundNode?.makeBubbleBackground(for: .free) {
|
||||
backgroundContent.clipsToBounds = true
|
||||
backgroundContent.cornerRadius = 24.0
|
||||
|
||||
strongSelf.mediaBackgroundContent?.frame = mediaBackgroundFrame
|
||||
} else {
|
||||
strongSelf.mediaBackgroundNode.isHidden = false
|
||||
strongSelf.mediaBackgroundContent?.removeFromSupernode()
|
||||
strongSelf.mediaBackgroundContent = nil
|
||||
strongSelf.mediaBackgroundContent = backgroundContent
|
||||
strongSelf.insertSubnode(backgroundContent, at: 0)
|
||||
}
|
||||
|
||||
if let backgroundContent = strongSelf.mediaBackgroundContent {
|
||||
if ribbonTextLayout.size.width > 0.0 {
|
||||
let backgroundMaskFrame = mediaBackgroundFrame.insetBy(dx: -2.0, dy: -2.0)
|
||||
backgroundContent.frame = backgroundMaskFrame
|
||||
backgroundContent.cornerRadius = 0.0
|
||||
|
||||
if strongSelf.mediaBackgroundMaskNode.image?.size != mediaBackgroundFrame.size {
|
||||
strongSelf.mediaBackgroundMaskNode.image = generateImage(backgroundMaskFrame.size, contextGenerator: { size, context in
|
||||
let bounds = CGRect(origin: .zero, size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: bounds.insetBy(dx: 2.0, dy: 2.0), cornerRadius: 24.0).cgPath)
|
||||
context.fillPath()
|
||||
|
||||
if let ribbonImage = UIImage(bundleImageName: "Chat/Message/GiftRibbon"), let cgImage = ribbonImage.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: CGPoint(x: bounds.width - ribbonImage.size.width, y: bounds.height - ribbonImage.size.height), size: ribbonImage.size), byTiling: false)
|
||||
}
|
||||
})
|
||||
}
|
||||
backgroundContent.view.mask = strongSelf.mediaBackgroundMaskNode.view
|
||||
strongSelf.mediaBackgroundMaskNode.frame = CGRect(origin: .zero, size: backgroundMaskFrame.size)
|
||||
} else {
|
||||
backgroundContent.frame = mediaBackgroundFrame
|
||||
backgroundContent.clipsToBounds = true
|
||||
backgroundContent.cornerRadius = 24.0
|
||||
backgroundContent.view.mask = nil
|
||||
}
|
||||
}
|
||||
|
||||
let baseBackgroundFrame = labelFrame.offsetBy(dx: 0.0, dy: -11.0)
|
||||
|
|
@ -602,7 +722,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
return ChatMessageBubbleContentTapAction(content: .ignore)
|
||||
} else if let backgroundNode = self.backgroundNode, backgroundNode.frame.contains(point) {
|
||||
return ChatMessageBubbleContentTapAction(content: .openMessage)
|
||||
} else if self.mediaBackgroundNode.frame.contains(point) {
|
||||
} else if self.mediaBackgroundContent?.frame.contains(point) == true {
|
||||
return ChatMessageBubbleContentTapAction(content: .openMessage)
|
||||
} else {
|
||||
return ChatMessageBubbleContentTapAction(content: .none)
|
||||
|
|
|
|||
|
|
@ -1209,8 +1209,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||
if let invoice {
|
||||
let inputData = Promise<BotCheckoutController.InputData?>()
|
||||
inputData.set(BotCheckoutController.InputData.fetch(context: strongSelf.context, source: .slug(slug))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<BotCheckoutController.InputData?, NoError> in
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<BotCheckoutController.InputData?, NoError> in
|
||||
return .single(nil)
|
||||
})
|
||||
strongSelf.controllerInteraction.presentController(BotCheckoutController(context: strongSelf.context, invoice: invoice, source: .slug(slug), inputData: inputData, completed: { currencyValue, receiptMessageId in
|
||||
|
|
|
|||
|
|
@ -144,6 +144,34 @@ public func animationCacheFetchFile(postbox: Postbox, userLocation: MediaResourc
|
|||
}
|
||||
}
|
||||
|
||||
public func animationCacheLoadLocalFile(name: String, type: AnimationCacheAnimationType, keyframeOnly: Bool, customColor: UIColor?) -> (AnimationCacheFetchOptions) -> Disposable {
|
||||
return { options in
|
||||
let source = AnimatedStickerNodeLocalFileSource(name: name)
|
||||
let dataDisposable = source.directDataPath(attemptSynchronously: false).start(next: { result in
|
||||
guard let result = result else {
|
||||
return
|
||||
}
|
||||
|
||||
switch type {
|
||||
case .video:
|
||||
cacheVideoAnimation(path: result, width: Int(options.size.width), height: Int(options.size.height), writer: options.writer, firstFrameOnly: options.firstFrameOnly, customColor: customColor)
|
||||
case .lottie:
|
||||
guard let data = try? Data(contentsOf: URL(fileURLWithPath: result)) else {
|
||||
options.writer.finish()
|
||||
return
|
||||
}
|
||||
cacheLottieAnimation(data: data, width: Int(options.size.width), height: Int(options.size.height), keyframeOnly: keyframeOnly, writer: options.writer, firstFrameOnly: options.firstFrameOnly, customColor: customColor)
|
||||
case .still:
|
||||
cacheStillSticker(path: result, width: Int(options.size.width), height: Int(options.size.height), writer: options.writer, customColor: customColor)
|
||||
}
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
dataDisposable.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, isDark: Bool, bounds: CGSize = CGSize(width: 40.0, height: 40.0), size: CGSize = CGSize(width: 40.0, height: 40.0)) -> UIImage? {
|
||||
return generateImage(bounds, rotatedContext: { contextSize, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: contextSize)
|
||||
|
|
@ -310,6 +338,8 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||
private var didProcessTintColor: Bool = false
|
||||
|
||||
public private(set) var file: TelegramMediaFile?
|
||||
private var localAnimationName: String?
|
||||
|
||||
private var infoDisposable: Disposable?
|
||||
private var disposable: Disposable?
|
||||
private var fetchDisposable: Disposable?
|
||||
|
|
@ -440,6 +470,8 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||
}
|
||||
case .ton:
|
||||
self.updateTon()
|
||||
case let .animation(name):
|
||||
self.updateLocalAnimation(name: name, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||
}
|
||||
} else if let file = file {
|
||||
self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||
|
|
@ -629,6 +661,42 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||
self.contents = tonImage?.cgImage
|
||||
}
|
||||
|
||||
private func updateLocalAnimation(name: String, attemptSynchronousLoad: Bool) {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
}
|
||||
|
||||
self.localAnimationName = name
|
||||
|
||||
if attemptSynchronousLoad {
|
||||
if !arguments.renderer.loadFirstFrameSynchronously(target: self, cache: arguments.cache, itemId: name, size: arguments.pixelSize) {
|
||||
|
||||
}
|
||||
|
||||
self.loadAnimation()
|
||||
} else {
|
||||
self.loadDisposable = arguments.renderer.loadFirstFrame(target: self, cache: arguments.cache, itemId: name, size: arguments.pixelSize, fetch: animationCacheLoadLocalFile(name: name, type: .lottie, keyframeOnly: true, customColor: nil), completion: { [weak self] result, isFinal in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.loadAnimation()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func loadLocalAnimation() {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let name = self.localAnimationName else {
|
||||
return
|
||||
}
|
||||
|
||||
let keyframeOnly = arguments.pixelSize.width >= 120.0
|
||||
self.disposable = arguments.renderer.add(target: self, cache: arguments.cache, itemId: name, unique: arguments.unique, size: arguments.pixelSize, fetch: animationCacheLoadLocalFile(name: name, type: .lottie, keyframeOnly: keyframeOnly, customColor: nil))
|
||||
}
|
||||
|
||||
private func updateFile(file: TelegramMediaFile, attemptSynchronousLoad: Bool) {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "GiftItemComponent",
|
||||
module_name = "GiftItemComponent",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/MultilineTextWithEntitiesComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/AvatarNode",
|
||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||
"//submodules/TelegramUI/Components/Stars/ItemShimmeringLoadingComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,612 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import AppBundle
|
||||
import AccountContext
|
||||
import MultilineTextComponent
|
||||
import MultilineTextWithEntitiesComponent
|
||||
import EmojiTextAttachmentView
|
||||
import TextFormat
|
||||
import ItemShimmeringLoadingComponent
|
||||
import AvatarNode
|
||||
|
||||
public final class GiftItemComponent: Component {
|
||||
public enum Subject: Equatable {
|
||||
case premium(Int32)
|
||||
case starGift(Int64, TelegramMediaFile)
|
||||
}
|
||||
|
||||
public struct Ribbon: Equatable {
|
||||
public enum Color {
|
||||
case red
|
||||
case blue
|
||||
|
||||
var colors: [UIColor] {
|
||||
switch self {
|
||||
case .red:
|
||||
return [
|
||||
UIColor(rgb: 0xed1c26),
|
||||
UIColor(rgb: 0xff5c55)
|
||||
|
||||
]
|
||||
case .blue:
|
||||
return [
|
||||
UIColor(rgb: 0x34a4fc),
|
||||
UIColor(rgb: 0x6fd3ff)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
public let text: String
|
||||
public let color: Color
|
||||
|
||||
public init(text: String, color: Color) {
|
||||
self.text = text
|
||||
self.color = color
|
||||
}
|
||||
}
|
||||
|
||||
public enum Peer: Equatable {
|
||||
case peer(EnginePeer)
|
||||
case anonymous
|
||||
}
|
||||
|
||||
let context: AccountContext
|
||||
let theme: PresentationTheme
|
||||
let peer: GiftItemComponent.Peer?
|
||||
let subject: GiftItemComponent.Subject
|
||||
let title: String?
|
||||
let subtitle: String?
|
||||
let price: String
|
||||
let ribbon: Ribbon?
|
||||
let isLoading: Bool
|
||||
let isHidden: Bool
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
theme: PresentationTheme,
|
||||
peer: GiftItemComponent.Peer?,
|
||||
subject: GiftItemComponent.Subject,
|
||||
title: String? = nil,
|
||||
subtitle: String? = nil,
|
||||
price: String,
|
||||
ribbon: Ribbon? = nil,
|
||||
isLoading: Bool = false,
|
||||
isHidden: Bool = false
|
||||
) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.peer = peer
|
||||
self.subject = subject
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.price = price
|
||||
self.ribbon = ribbon
|
||||
self.isLoading = isLoading
|
||||
self.isHidden = isHidden
|
||||
}
|
||||
|
||||
public static func ==(lhs: GiftItemComponent, rhs: GiftItemComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.subject != rhs.subject {
|
||||
return false
|
||||
}
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
if lhs.subtitle != rhs.subtitle {
|
||||
return false
|
||||
}
|
||||
if lhs.price != rhs.price {
|
||||
return false
|
||||
}
|
||||
if lhs.ribbon != rhs.ribbon {
|
||||
return false
|
||||
}
|
||||
if lhs.isLoading != rhs.isLoading {
|
||||
return false
|
||||
}
|
||||
if lhs.isHidden != rhs.isHidden {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: UIView {
|
||||
private var component: GiftItemComponent?
|
||||
private weak var componentState: EmptyComponentState?
|
||||
|
||||
private let backgroundLayer = SimpleLayer()
|
||||
private var loadingBackground: ComponentView<Empty>?
|
||||
|
||||
private var avatarNode: AvatarNode?
|
||||
private let title = ComponentView<Empty>()
|
||||
private let subtitle = ComponentView<Empty>()
|
||||
private let button = ComponentView<Empty>()
|
||||
private let ribbon = UIImageView()
|
||||
private let ribbonText = ComponentView<Empty>()
|
||||
|
||||
private var animationLayer: InlineStickerItemLayer?
|
||||
|
||||
private var hiddenIconBackground: UIVisualEffectView?
|
||||
private var hiddenIcon: UIImageView?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.layer.addSublayer(self.backgroundLayer)
|
||||
|
||||
self.backgroundLayer.cornerRadius = 10.0
|
||||
if #available(iOS 13.0, *) {
|
||||
self.backgroundLayer.cornerCurve = .circular
|
||||
}
|
||||
self.backgroundLayer.masksToBounds = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: GiftItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
let isFirstTime = self.component == nil
|
||||
|
||||
self.component = component
|
||||
self.componentState = state
|
||||
|
||||
let size = CGSize(width: availableSize.width, height: component.title != nil ? 178.0 : 154.0)
|
||||
|
||||
if component.isLoading {
|
||||
let loadingBackground: ComponentView<Empty>
|
||||
if let current = self.loadingBackground {
|
||||
loadingBackground = current
|
||||
} else {
|
||||
loadingBackground = ComponentView<Empty>()
|
||||
self.loadingBackground = loadingBackground
|
||||
}
|
||||
|
||||
let _ = loadingBackground.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
ItemShimmeringLoadingComponent(color: component.theme.list.itemAccentColor, cornerRadius: 10.0)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: size
|
||||
)
|
||||
if let loadingBackgroundView = loadingBackground.view {
|
||||
if loadingBackgroundView.layer.superlayer == nil {
|
||||
self.layer.insertSublayer(loadingBackgroundView.layer, above: self.backgroundLayer)
|
||||
}
|
||||
loadingBackgroundView.frame = CGRect(origin: .zero, size: size)
|
||||
}
|
||||
} else if let loadingBackground = self.loadingBackground {
|
||||
loadingBackground.view?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||
loadingBackground.view?.layer.removeFromSuperlayer()
|
||||
})
|
||||
self.loadingBackground = nil
|
||||
}
|
||||
|
||||
let emoji: ChatTextInputTextCustomEmojiAttribute?
|
||||
var file: TelegramMediaFile?
|
||||
var animationOffset: CGFloat = 0.0
|
||||
switch component.subject {
|
||||
case let .premium(months):
|
||||
emoji = ChatTextInputTextCustomEmojiAttribute(
|
||||
interactivelySelectedFromPackId: nil,
|
||||
fileId: 0,
|
||||
file: nil,
|
||||
custom: .animation(name: "Gift\(months)")
|
||||
)
|
||||
case let .starGift(_, fileValue):
|
||||
file = fileValue
|
||||
emoji = ChatTextInputTextCustomEmojiAttribute(
|
||||
interactivelySelectedFromPackId: nil,
|
||||
fileId: fileValue.fileId.id,
|
||||
file: fileValue
|
||||
)
|
||||
animationOffset = 16.0
|
||||
}
|
||||
|
||||
let iconSize = CGSize(width: 88.0, height: 88.0)
|
||||
if self.animationLayer == nil, let emoji {
|
||||
let animationLayer = InlineStickerItemLayer(
|
||||
context: .account(component.context),
|
||||
userLocation: .other,
|
||||
attemptSynchronousLoad: false,
|
||||
emoji: emoji,
|
||||
file: file,
|
||||
cache: component.context.animationCache,
|
||||
renderer: component.context.animationRenderer,
|
||||
unique: false,
|
||||
placeholderColor: component.theme.list.mediaPlaceholderColor,
|
||||
pointSize: CGSize(width: iconSize.width * 2.0, height: iconSize.height * 2.0),
|
||||
loopCount: 1
|
||||
)
|
||||
animationLayer.isVisibleForAnimations = true
|
||||
self.animationLayer = animationLayer
|
||||
self.layer.addSublayer(animationLayer)
|
||||
}
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - iconSize.width) / 2.0), y: animationOffset), size: iconSize)
|
||||
if let animationLayer = self.animationLayer {
|
||||
transition.setFrame(layer: animationLayer, frame: animationFrame)
|
||||
}
|
||||
|
||||
if let title = component.title {
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: title, font: Font.semibold(15.0), textColor: component.theme.list.itemPrimaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - titleSize.width) / 2.0), y: 94.0), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
}
|
||||
|
||||
if let subtitle = component.subtitle {
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: subtitle, font: Font.regular(13.0), textColor: component.theme.list.itemPrimaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - subtitleSize.width) / 2.0), y: 112.0), size: subtitleSize)
|
||||
if let subtitleView = self.subtitle.view {
|
||||
if subtitleView.superview == nil {
|
||||
self.addSubview(subtitleView)
|
||||
}
|
||||
transition.setFrame(view: subtitleView, frame: subtitleFrame)
|
||||
}
|
||||
}
|
||||
|
||||
let buttonSize = self.button.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
ButtonContentComponent(
|
||||
context: component.context,
|
||||
text: component.price,
|
||||
color: component.price.containsEmoji ? UIColor(rgb: 0xd3720a) : component.theme.list.itemAccentColor,
|
||||
isStars: component.price.containsEmoji)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - buttonSize.width) / 2.0), y: size.height - buttonSize.height - 10.0), size: buttonSize)
|
||||
if let buttonView = self.button.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
}
|
||||
transition.setFrame(view: buttonView, frame: buttonFrame)
|
||||
}
|
||||
|
||||
if let ribbon = component.ribbon {
|
||||
let ribbonTextSize = self.ribbonText.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: ribbon.text, font: Font.semibold(11.0), textColor: .white)),
|
||||
horizontalAlignment: .center
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let ribbonTextView = self.ribbonText.view {
|
||||
if ribbonTextView.superview == nil {
|
||||
self.addSubview(self.ribbon)
|
||||
self.addSubview(ribbonTextView)
|
||||
}
|
||||
ribbonTextView.bounds = CGRect(origin: .zero, size: ribbonTextSize)
|
||||
|
||||
if self.ribbon.image == nil {
|
||||
self.ribbon.image = generateGradientTintedImage(image: UIImage(bundleImageName: "Premium/GiftRibbon"), colors: ribbon.color.colors, direction: .diagonal)
|
||||
}
|
||||
if let ribbonImage = self.ribbon.image {
|
||||
self.ribbon.frame = CGRect(origin: CGPoint(x: size.width - ribbonImage.size.width + 2.0, y: -2.0), size: ribbonImage.size)
|
||||
}
|
||||
ribbonTextView.transform = CGAffineTransform(rotationAngle: .pi / 4.0)
|
||||
ribbonTextView.center = CGPoint(x: size.width - 20.0, y: 20.0)
|
||||
}
|
||||
} else {
|
||||
if self.ribbonText.view?.superview != nil {
|
||||
self.ribbon.removeFromSuperview()
|
||||
self.ribbonText.view?.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
if let peer = component.peer {
|
||||
let avatarNode: AvatarNode
|
||||
if let current = self.avatarNode {
|
||||
avatarNode = current
|
||||
} else {
|
||||
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 8.0))
|
||||
self.addSubview(avatarNode.view)
|
||||
self.avatarNode = avatarNode
|
||||
}
|
||||
|
||||
switch peer {
|
||||
case let .peer(peer):
|
||||
avatarNode.setPeer(context: component.context, theme: component.theme, peer: peer, displayDimensions: CGSize(width: 20.0, height: 20.0))
|
||||
case .anonymous:
|
||||
avatarNode.setPeer(context: component.context, theme: component.theme, peer: nil, overrideImage: .anonymousSavedMessagesIcon(isColored: true))
|
||||
}
|
||||
|
||||
avatarNode.frame = CGRect(origin: CGPoint(x: 2.0, y: 2.0), size: CGSize(width: 20.0, height: 20.0))
|
||||
}
|
||||
|
||||
self.backgroundLayer.backgroundColor = component.theme.list.itemBlocksBackgroundColor.cgColor
|
||||
transition.setFrame(layer: self.backgroundLayer, frame: CGRect(origin: .zero, size: size))
|
||||
|
||||
if component.isHidden {
|
||||
let hiddenIconBackground: UIVisualEffectView
|
||||
let hiddenIcon: UIImageView
|
||||
if let currentBackground = self.hiddenIconBackground, let currentIcon = self.hiddenIcon {
|
||||
hiddenIconBackground = currentBackground
|
||||
hiddenIcon = currentIcon
|
||||
} else {
|
||||
let blurEffect: UIBlurEffect
|
||||
if #available(iOS 13.0, *) {
|
||||
blurEffect = UIBlurEffect(style: .systemThinMaterialDark)
|
||||
} else {
|
||||
blurEffect = UIBlurEffect(style: .dark)
|
||||
}
|
||||
hiddenIconBackground = UIVisualEffectView(effect: blurEffect)
|
||||
hiddenIconBackground.clipsToBounds = true
|
||||
hiddenIconBackground.layer.cornerRadius = 15.0
|
||||
self.hiddenIconBackground = hiddenIconBackground
|
||||
|
||||
hiddenIcon = UIImageView(image: generateTintedImage(image: UIImage(bundleImageName: "Peer Info/HiddenIcon"), color: .white))
|
||||
self.hiddenIcon = hiddenIcon
|
||||
|
||||
self.addSubview(hiddenIconBackground)
|
||||
hiddenIconBackground.contentView.addSubview(hiddenIcon)
|
||||
|
||||
if !isFirstTime {
|
||||
hiddenIconBackground.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
|
||||
hiddenIconBackground.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
let iconSize = CGSize(width: 30.0, height: 30.0)
|
||||
hiddenIconBackground.frame = iconSize.centered(around: animationFrame.center)
|
||||
hiddenIcon.frame = CGRect(origin: .zero, size: iconSize)
|
||||
} else {
|
||||
if let hiddenIconBackground = self.hiddenIconBackground {
|
||||
self.hiddenIconBackground = nil
|
||||
self.hiddenIcon = nil
|
||||
|
||||
hiddenIconBackground.layer.animateAlpha(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||
hiddenIconBackground.removeFromSuperview()
|
||||
})
|
||||
hiddenIconBackground.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
private final class ButtonContentComponent: Component {
|
||||
let context: AccountContext
|
||||
let text: String
|
||||
let color: UIColor
|
||||
let isStars: Bool
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
text: String,
|
||||
color: UIColor,
|
||||
isStars: Bool = false
|
||||
) {
|
||||
self.context = context
|
||||
self.text = text
|
||||
self.color = color
|
||||
self.isStars = isStars
|
||||
}
|
||||
|
||||
public static func ==(lhs: ButtonContentComponent, rhs: ButtonContentComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
if lhs.color != rhs.color {
|
||||
return false
|
||||
}
|
||||
if lhs.isStars != rhs.isStars {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: UIView {
|
||||
private var component: ButtonContentComponent?
|
||||
private weak var componentState: EmptyComponentState?
|
||||
|
||||
private let backgroundLayer = SimpleLayer()
|
||||
private let title = ComponentView<Empty>()
|
||||
|
||||
private var starsLayer: StarsButtonEffectLayer?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.layer.addSublayer(self.backgroundLayer)
|
||||
self.backgroundLayer.masksToBounds = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(component: ButtonContentComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
self.componentState = state
|
||||
|
||||
let attributedText = NSMutableAttributedString(string: component.text, font: Font.semibold(11.0), textColor: component.color)
|
||||
let range = (attributedText.string as NSString).range(of: "⭐️")
|
||||
if range.location != NSNotFound {
|
||||
attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: range)
|
||||
attributedText.addAttribute(.font, value: Font.semibold(15.0), range: range)
|
||||
attributedText.addAttribute(.baselineOffset, value: 2.0, range: NSRange(location: range.upperBound, length: attributedText.length - range.upperBound))
|
||||
}
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
MultilineTextWithEntitiesComponent(
|
||||
context: component.context,
|
||||
animationCache: component.context.animationCache,
|
||||
animationRenderer: component.context.animationRenderer,
|
||||
placeholderColor: .white,
|
||||
text: .plain(attributedText)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
|
||||
let padding: CGFloat = 9.0
|
||||
let size = CGSize(width: titleSize.width + padding * 2.0, height: 30.0)
|
||||
|
||||
if component.isStars {
|
||||
let starsLayer: StarsButtonEffectLayer
|
||||
if let current = self.starsLayer {
|
||||
starsLayer = current
|
||||
} else {
|
||||
starsLayer = StarsButtonEffectLayer()
|
||||
self.layer.addSublayer(starsLayer)
|
||||
self.starsLayer = starsLayer
|
||||
}
|
||||
starsLayer.frame = CGRect(origin: .zero, size: size)
|
||||
starsLayer.update(size: size)
|
||||
} else {
|
||||
self.starsLayer?.removeFromSuperlayer()
|
||||
self.starsLayer = nil
|
||||
}
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - titleSize.width) / 2.0), y: floorToScreenPixels((size.height - titleSize.height) / 2.0)), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
self.addSubview(titleView)
|
||||
}
|
||||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
|
||||
let backgroundColor: UIColor
|
||||
if component.color.rgb == 0xd3720a {
|
||||
backgroundColor = UIColor(rgb: 0xffc83d, alpha: 0.2)
|
||||
} else {
|
||||
backgroundColor = component.color.withAlphaComponent(0.1)
|
||||
}
|
||||
|
||||
self.backgroundLayer.backgroundColor = backgroundColor.cgColor
|
||||
transition.setFrame(layer: self.backgroundLayer, frame: CGRect(origin: .zero, size: size))
|
||||
self.backgroundLayer.cornerRadius = size.height / 2.0
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
private final class StarsButtonEffectLayer: SimpleLayer {
|
||||
let emitterLayer = CAEmitterLayer()
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
self.addSublayer(self.emitterLayer)
|
||||
}
|
||||
|
||||
override init(layer: Any) {
|
||||
super.init(layer: layer)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
let color = UIColor(rgb: 0xffbe27)
|
||||
|
||||
let emitter = CAEmitterCell()
|
||||
emitter.name = "emitter"
|
||||
emitter.contents = UIImage(bundleImageName: "Premium/Stars/Particle")?.cgImage
|
||||
emitter.birthRate = 25.0
|
||||
emitter.lifetime = 2.0
|
||||
emitter.velocity = 12.0
|
||||
emitter.velocityRange = 3
|
||||
emitter.scale = 0.1
|
||||
emitter.scaleRange = 0.08
|
||||
emitter.alphaRange = 0.1
|
||||
emitter.emissionRange = .pi * 2.0
|
||||
emitter.setValue(3.0, forKey: "mass")
|
||||
emitter.setValue(2.0, forKey: "massRange")
|
||||
|
||||
let staticColors: [Any] = [
|
||||
color.withAlphaComponent(0.0).cgColor,
|
||||
color.cgColor,
|
||||
color.cgColor,
|
||||
color.withAlphaComponent(0.0).cgColor
|
||||
]
|
||||
let staticColorBehavior = CAEmitterCell.createEmitterBehavior(type: "colorOverLife")
|
||||
staticColorBehavior.setValue(staticColors, forKey: "colors")
|
||||
emitter.setValue([staticColorBehavior], forKey: "emitterBehaviors")
|
||||
|
||||
self.emitterLayer.emitterCells = [emitter]
|
||||
}
|
||||
|
||||
func update(size: CGSize) {
|
||||
if self.emitterLayer.emitterCells == nil {
|
||||
self.setup()
|
||||
}
|
||||
self.emitterLayer.emitterShape = .circle
|
||||
self.emitterLayer.emitterSize = CGSize(width: size.width * 0.7, height: size.height * 0.7)
|
||||
self.emitterLayer.emitterMode = .surface
|
||||
self.emitterLayer.frame = CGRect(origin: .zero, size: size)
|
||||
self.emitterLayer.emitterPosition = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "GiftOptionsScreen",
|
||||
module_name = "GiftOptionsScreen",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/ItemListUI",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/Components/SheetComponent",
|
||||
"//submodules/UndoUI",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/ScrollComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||
"//submodules/Components/BlurredBackgroundComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftItemComponent",
|
||||
"//submodules/ConfettiEffect",
|
||||
"//submodules/InAppPurchaseManager",
|
||||
"//submodules/TelegramUI/Components/TabSelectorComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftSetupScreen",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
File diff suppressed because it is too large
Load diff
45
submodules/TelegramUI/Components/Gifts/GiftSetupScreen/BUILD
Normal file
45
submodules/TelegramUI/Components/Gifts/GiftSetupScreen/BUILD
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "GiftSetupScreen",
|
||||
module_name = "GiftSetupScreen",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/ListMultilineTextFieldItemComponent",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/WallpaperBackgroundNode",
|
||||
"//submodules/ChatPresentationInterfaceState",
|
||||
"//submodules/TelegramUI/Components/TextFieldComponent",
|
||||
"//submodules/TelegramUI/Components/ListItemComponentAdaptor",
|
||||
"//submodules/BotPaymentsUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import Postbox
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import WallpaperBackgroundNode
|
||||
import ListItemComponentAdaptor
|
||||
|
||||
final class ChatGiftPreviewItem: ListViewItem, ItemListItem, ListItemComponentAdaptor.ItemGenerator {
|
||||
let context: AccountContext
|
||||
let theme: PresentationTheme
|
||||
let componentTheme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let sectionId: ItemListSectionId
|
||||
let fontSize: PresentationFontSize
|
||||
let chatBubbleCorners: PresentationChatBubbleCorners
|
||||
let wallpaper: TelegramWallpaper
|
||||
let dateTimeFormat: PresentationDateTimeFormat
|
||||
let nameDisplayOrder: PresentationPersonNameOrder
|
||||
|
||||
let accountPeer: EnginePeer?
|
||||
let gift: StarGift
|
||||
let text: String
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
theme: PresentationTheme,
|
||||
componentTheme: PresentationTheme,
|
||||
strings: PresentationStrings,
|
||||
sectionId: ItemListSectionId,
|
||||
fontSize: PresentationFontSize,
|
||||
chatBubbleCorners: PresentationChatBubbleCorners,
|
||||
wallpaper: TelegramWallpaper,
|
||||
dateTimeFormat: PresentationDateTimeFormat,
|
||||
nameDisplayOrder: PresentationPersonNameOrder,
|
||||
accountPeer: EnginePeer?,
|
||||
gift: StarGift,
|
||||
text: String
|
||||
) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.componentTheme = componentTheme
|
||||
self.strings = strings
|
||||
self.sectionId = sectionId
|
||||
self.fontSize = fontSize
|
||||
self.chatBubbleCorners = chatBubbleCorners
|
||||
self.wallpaper = wallpaper
|
||||
self.dateTimeFormat = dateTimeFormat
|
||||
self.nameDisplayOrder = nameDisplayOrder
|
||||
self.accountPeer = accountPeer
|
||||
self.gift = gift
|
||||
self.text = text
|
||||
}
|
||||
|
||||
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
async {
|
||||
let node = ChatGiftPreviewItemNode()
|
||||
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
|
||||
node.contentSize = layout.contentSize
|
||||
node.insets = layout.insets
|
||||
|
||||
Queue.mainQueue().async {
|
||||
completion(node, {
|
||||
return (nil, { _ in apply() })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
if let nodeValue = node() as? ChatGiftPreviewItemNode {
|
||||
let makeLayout = nodeValue.asyncLayout()
|
||||
|
||||
async {
|
||||
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||
Queue.mainQueue().async {
|
||||
completion(layout, { _ in
|
||||
apply()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func item() -> ListViewItem {
|
||||
return self
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChatGiftPreviewItem, rhs: ChatGiftPreviewItem) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
if lhs.componentTheme !== rhs.componentTheme {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.fontSize != rhs.fontSize {
|
||||
return false
|
||||
}
|
||||
if lhs.chatBubbleCorners != rhs.chatBubbleCorners {
|
||||
return false
|
||||
}
|
||||
if lhs.wallpaper != rhs.wallpaper {
|
||||
return false
|
||||
}
|
||||
if lhs.dateTimeFormat != rhs.dateTimeFormat {
|
||||
return false
|
||||
}
|
||||
if lhs.nameDisplayOrder != rhs.nameDisplayOrder {
|
||||
return false
|
||||
}
|
||||
if lhs.accountPeer != rhs.accountPeer {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
final class ChatGiftPreviewItemNode: ListViewItemNode {
|
||||
private var backgroundNode: WallpaperBackgroundNode?
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
private let containerNode: ASDisplayNode
|
||||
private var messageNodes: [ListViewItemNode]?
|
||||
private var itemHeaderNodes: [ListViewItemNode.HeaderId: ListViewItemHeaderNode] = [:]
|
||||
|
||||
private var item: ChatGiftPreviewItem?
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
private var initialBubbleHeight: CGFloat?
|
||||
|
||||
init() {
|
||||
self.topStripeNode = ASDisplayNode()
|
||||
self.topStripeNode.isLayerBacked = true
|
||||
|
||||
self.bottomStripeNode = ASDisplayNode()
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.maskNode = ASImageNode()
|
||||
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0)
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.isUserInteractionEnabled = false
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable.dispose()
|
||||
}
|
||||
|
||||
func asyncLayout() -> (_ item: ChatGiftPreviewItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||
let currentNodes = self.messageNodes
|
||||
|
||||
var currentBackgroundNode = self.backgroundNode
|
||||
|
||||
return { item, params, neighbors in
|
||||
if currentBackgroundNode == nil {
|
||||
currentBackgroundNode = createWallpaperBackgroundNode(context: item.context, forChatDisplay: false)
|
||||
currentBackgroundNode?.update(wallpaper: item.wallpaper, animated: false)
|
||||
currentBackgroundNode?.updateBubbleTheme(bubbleTheme: item.componentTheme, bubbleCorners: item.chatBubbleCorners)
|
||||
}
|
||||
|
||||
var insets: UIEdgeInsets
|
||||
let separatorHeight = UIScreenPixel
|
||||
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1))
|
||||
|
||||
var items: [ListViewItem] = []
|
||||
for _ in 0 ..< 1 {
|
||||
let authorPeerId = item.context.account.peerId
|
||||
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
let messages = SimpleDictionary<MessageId, Message>()
|
||||
|
||||
peers[authorPeerId] = item.accountPeer?._asPeer()
|
||||
|
||||
let media: [Media] = [
|
||||
TelegramMediaAction(action: .starGift(gift: item.gift, convertStars: item.gift.convertStars, text: item.text, entities: [], nameHidden: false, savedToProfile: false, converted: false))
|
||||
]
|
||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: peers[authorPeerId], text: "", attributes: [], media: media, peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, accountPeer: nil, isCentered: false, isPreview: true, isStandalone: false))
|
||||
}
|
||||
|
||||
var nodes: [ListViewItemNode] = []
|
||||
if let messageNodes = currentNodes {
|
||||
nodes = messageNodes
|
||||
for i in 0 ..< items.count {
|
||||
let itemNode = messageNodes[i]
|
||||
items[i].updateNode(async: { $0() }, node: {
|
||||
return itemNode
|
||||
}, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None, completion: { (layout, apply) in
|
||||
let nodeFrame = CGRect(origin: itemNode.frame.origin, size: CGSize(width: layout.size.width, height: layout.size.height))
|
||||
|
||||
itemNode.contentSize = layout.contentSize
|
||||
itemNode.insets = layout.insets
|
||||
itemNode.frame = nodeFrame
|
||||
itemNode.isUserInteractionEnabled = false
|
||||
|
||||
Queue.mainQueue().after(0.01) {
|
||||
apply(ListViewItemApply(isOnScreen: true))
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
var messageNodes: [ListViewItemNode] = []
|
||||
for i in 0 ..< items.count {
|
||||
var itemNode: ListViewItemNode?
|
||||
items[i].nodeConfiguredForParams(async: { $0() }, params: params, synchronousLoads: false, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], completion: { node, apply in
|
||||
itemNode = node
|
||||
apply().1(ListViewItemApply(isOnScreen: true))
|
||||
})
|
||||
itemNode!.isUserInteractionEnabled = false
|
||||
messageNodes.append(itemNode!)
|
||||
|
||||
self.initialBubbleHeight = itemNode?.frame.height
|
||||
}
|
||||
nodes = messageNodes
|
||||
}
|
||||
|
||||
var contentSize = CGSize(width: params.width, height: 4.0 + 4.0)
|
||||
contentSize.height = 346.0
|
||||
insets = itemListNeighborsGroupedInsets(neighbors, params)
|
||||
if params.width <= 320.0 {
|
||||
insets.top = 0.0
|
||||
}
|
||||
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: .zero)
|
||||
let layoutSize = layout.size
|
||||
|
||||
return (layout, { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.item = item
|
||||
|
||||
if let currentBackgroundNode {
|
||||
currentBackgroundNode.update(wallpaper: item.wallpaper, animated: false)
|
||||
currentBackgroundNode.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners)
|
||||
}
|
||||
|
||||
strongSelf.containerNode.frame = CGRect(origin: CGPoint(), size: contentSize)
|
||||
|
||||
strongSelf.messageNodes = nodes
|
||||
//var topOffset: CGFloat = 4.0
|
||||
for node in nodes {
|
||||
if node.supernode == nil {
|
||||
strongSelf.containerNode.addSubnode(node)
|
||||
}
|
||||
let bubbleHeight: CGFloat
|
||||
if let initialBubbleHeight = strongSelf.initialBubbleHeight {
|
||||
bubbleHeight = max(node.frame.height, initialBubbleHeight)
|
||||
} else {
|
||||
bubbleHeight = node.frame.height
|
||||
}
|
||||
node.updateFrame(CGRect(origin: CGPoint(x: 0.0, y: floor((contentSize.height - bubbleHeight) / 2.0)), size: node.frame.size), within: layoutSize)
|
||||
//topOffset += node.frame.size.height
|
||||
}
|
||||
|
||||
if let currentBackgroundNode = currentBackgroundNode, strongSelf.backgroundNode !== currentBackgroundNode {
|
||||
strongSelf.backgroundNode = currentBackgroundNode
|
||||
strongSelf.insertSubnode(currentBackgroundNode, at: 0)
|
||||
}
|
||||
|
||||
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
|
||||
|
||||
if strongSelf.topStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.topStripeNode, at: 1)
|
||||
}
|
||||
if strongSelf.bottomStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
|
||||
}
|
||||
if strongSelf.maskNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.maskNode, at: 3)
|
||||
}
|
||||
|
||||
if params.isStandalone {
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
strongSelf.bottomStripeNode.isHidden = true
|
||||
strongSelf.maskNode.isHidden = true
|
||||
} else {
|
||||
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||
|
||||
var hasTopCorners = false
|
||||
var hasBottomCorners = false
|
||||
|
||||
switch neighbors.top {
|
||||
case .sameSection(false):
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
default:
|
||||
hasTopCorners = true
|
||||
strongSelf.topStripeNode.isHidden = hasCorners
|
||||
}
|
||||
let bottomStripeInset: CGFloat
|
||||
let bottomStripeOffset: CGFloat
|
||||
switch neighbors.bottom {
|
||||
case .sameSection(false):
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = -separatorHeight
|
||||
strongSelf.bottomStripeNode.isHidden = false
|
||||
default:
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = 0.0
|
||||
hasBottomCorners = true
|
||||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.componentTheme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
|
||||
let displayMode: WallpaperDisplayMode
|
||||
if abs(params.availableHeight - params.width) < 100.0, params.availableHeight > 700.0 {
|
||||
displayMode = .halfAspectFill
|
||||
} else {
|
||||
if backgroundFrame.width > backgroundFrame.height * 4.0 {
|
||||
if params.availableHeight < 700.0 {
|
||||
displayMode = .halfAspectFill
|
||||
} else {
|
||||
displayMode = .aspectFill
|
||||
}
|
||||
} else {
|
||||
displayMode = .aspectFill
|
||||
}
|
||||
}
|
||||
|
||||
if let backgroundNode = strongSelf.backgroundNode {
|
||||
backgroundNode.frame = backgroundFrame
|
||||
backgroundNode.updateLayout(size: backgroundNode.bounds.size, displayMode: displayMode, transition: .immediate)
|
||||
}
|
||||
strongSelf.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override func animateInsertion(_ currentTimestamp: Double, duration: Double, options: ListViewItemAnimationOptions) {
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||
}
|
||||
|
||||
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,647 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import ComponentFlow
|
||||
import ViewControllerComponent
|
||||
import MultilineTextComponent
|
||||
import BalancedTextComponent
|
||||
import ListSectionComponent
|
||||
import ListActionItemComponent
|
||||
import ListMultilineTextFieldItemComponent
|
||||
import ListItemComponentAdaptor
|
||||
import BundleIconComponent
|
||||
import LottieComponent
|
||||
import TextFieldComponent
|
||||
import ButtonComponent
|
||||
import BotPaymentsUI
|
||||
|
||||
final class GiftSetupScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let peerId: EnginePeer.Id
|
||||
let gift: StarGift
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
peerId: EnginePeer.Id,
|
||||
gift: StarGift
|
||||
) {
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
self.gift = gift
|
||||
}
|
||||
|
||||
static func ==(lhs: GiftSetupScreenComponent, rhs: GiftSetupScreenComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.peerId != rhs.peerId {
|
||||
return false
|
||||
}
|
||||
if lhs.gift != rhs.gift {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private final class ScrollView: UIScrollView {
|
||||
override func touchesShouldCancel(in view: UIView) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
final class View: UIView, UIScrollViewDelegate {
|
||||
private let topOverscrollLayer = SimpleLayer()
|
||||
private let scrollView: ScrollView
|
||||
|
||||
private let navigationTitle = ComponentView<Empty>()
|
||||
private let introContent = ComponentView<Empty>()
|
||||
private let introSection = ComponentView<Empty>()
|
||||
private let hideSection = ComponentView<Empty>()
|
||||
private let button = ComponentView<Empty>()
|
||||
|
||||
private var ignoreScrolling: Bool = false
|
||||
private var isUpdating: Bool = false
|
||||
|
||||
private var component: GiftSetupScreenComponent?
|
||||
private(set) weak var state: EmptyComponentState?
|
||||
private var environment: EnvironmentType?
|
||||
|
||||
private let introPlaceholderTag = NSObject()
|
||||
private let textInputState = ListMultilineTextFieldItemComponent.ExternalState()
|
||||
private let textInputTag = NSObject()
|
||||
private var resetText: String?
|
||||
|
||||
private var hideName = false
|
||||
|
||||
private var previousHadInputHeight: Bool = false
|
||||
private var recenterOnTag: NSObject?
|
||||
|
||||
private var peerMap: [EnginePeer.Id: EnginePeer] = [:]
|
||||
|
||||
private var starImage: (UIImage, PresentationTheme)?
|
||||
|
||||
private var optionsDisposable: Disposable?
|
||||
private(set) var options: [StarsTopUpOption] = [] {
|
||||
didSet {
|
||||
self.optionsPromise.set(self.options)
|
||||
}
|
||||
}
|
||||
private let optionsPromise = ValuePromise<[StarsTopUpOption]?>(nil)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.scrollView = ScrollView()
|
||||
self.scrollView.showsVerticalScrollIndicator = true
|
||||
self.scrollView.showsHorizontalScrollIndicator = false
|
||||
self.scrollView.scrollsToTop = false
|
||||
self.scrollView.delaysContentTouches = false
|
||||
self.scrollView.canCancelContentTouches = true
|
||||
self.scrollView.contentInsetAdjustmentBehavior = .never
|
||||
if #available(iOS 13.0, *) {
|
||||
self.scrollView.automaticallyAdjustsScrollIndicatorInsets = false
|
||||
}
|
||||
self.scrollView.alwaysBounceVertical = true
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.scrollView.delegate = self
|
||||
self.addSubview(self.scrollView)
|
||||
|
||||
self.scrollView.layer.addSublayer(self.topOverscrollLayer)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
func scrollToTop() {
|
||||
self.scrollView.setContentOffset(CGPoint(), animated: true)
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if !self.ignoreScrolling {
|
||||
self.updateScrolling(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
private var scrolledUp = true
|
||||
private func updateScrolling(transition: ComponentTransition) {
|
||||
let navigationRevealOffsetY: CGFloat = 0.0
|
||||
|
||||
let navigationAlphaDistance: CGFloat = 16.0
|
||||
let navigationAlpha: CGFloat = max(0.0, min(1.0, (self.scrollView.contentOffset.y - navigationRevealOffsetY) / navigationAlphaDistance))
|
||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||
transition.setAlpha(layer: navigationBar.backgroundNode.layer, alpha: navigationAlpha)
|
||||
transition.setAlpha(layer: navigationBar.stripeNode.layer, alpha: navigationAlpha)
|
||||
}
|
||||
|
||||
var scrolledUp = false
|
||||
if navigationAlpha < 0.5 {
|
||||
scrolledUp = true
|
||||
} else if navigationAlpha > 0.5 {
|
||||
scrolledUp = false
|
||||
}
|
||||
|
||||
if self.scrolledUp != scrolledUp {
|
||||
self.scrolledUp = scrolledUp
|
||||
if !self.isUpdating {
|
||||
self.state?.updated()
|
||||
}
|
||||
}
|
||||
|
||||
if let navigationTitleView = self.navigationTitle.view {
|
||||
transition.setAlpha(view: navigationTitleView, alpha: 1.0)
|
||||
}
|
||||
}
|
||||
|
||||
func proceed() {
|
||||
guard let component = self.component, let starsContext = component.context.starsContext, let starsState = starsContext.currentState else {
|
||||
return
|
||||
}
|
||||
|
||||
let proceed = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let source: BotPaymentInvoiceSource = .starGift(hideName: self.hideName, peerId: component.peerId, giftId: component.gift.id, text: self.textInputState.text.string, entities: [])
|
||||
let inputData = BotCheckoutController.InputData.fetch(context: component.context, source: source)
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<BotCheckoutController.InputData?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
let _ = (inputData
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] inputData in
|
||||
guard let inputData else {
|
||||
return
|
||||
}
|
||||
let _ = (component.context.engine.payments.sendStarsPaymentForm(formId: inputData.form.id, source: source)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
guard let self, let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
|
||||
var controllers = navigationController.viewControllers
|
||||
controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) }
|
||||
var foundController = false
|
||||
for controller in controllers.reversed() {
|
||||
if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation {
|
||||
chatController.hintPlayNextOutgoingGift()
|
||||
foundController = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundController {
|
||||
let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
||||
chatController.hintPlayNextOutgoingGift()
|
||||
controllers.append(chatController)
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if starsState.balance < component.gift.price {
|
||||
let _ = (self.optionsPromise.get()
|
||||
|> filter { $0 != nil }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] options in
|
||||
guard let self, let component = self.component, let controller = self.environment?.controller() else {
|
||||
return
|
||||
}
|
||||
let purchaseController = component.context.sharedContext.makeStarsPurchaseScreen(
|
||||
context: component.context,
|
||||
starsContext: starsContext,
|
||||
options: options ?? [],
|
||||
purpose: .starGift(peerId: component.peerId, requiredStars: component.gift.price),
|
||||
completion: { [weak starsContext] stars in
|
||||
starsContext?.add(balance: stars)
|
||||
Queue.mainQueue().after(0.1) {
|
||||
proceed()
|
||||
}
|
||||
}
|
||||
)
|
||||
controller.push(purchaseController)
|
||||
})
|
||||
} else {
|
||||
proceed()
|
||||
}
|
||||
}
|
||||
|
||||
func update(component: GiftSetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
self.isUpdating = true
|
||||
defer {
|
||||
self.isUpdating = false
|
||||
}
|
||||
|
||||
if self.component == nil {
|
||||
let _ = (component.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: component.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: component.context.account.peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, accountPeer in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let peer {
|
||||
self.peerMap[peer.id] = peer
|
||||
}
|
||||
if let accountPeer {
|
||||
self.peerMap[accountPeer.id] = accountPeer
|
||||
}
|
||||
|
||||
self.state?.updated()
|
||||
})
|
||||
}
|
||||
|
||||
let environment = environment[EnvironmentType.self].value
|
||||
let themeUpdated = self.environment?.theme !== environment.theme
|
||||
self.environment = environment
|
||||
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let alphaTransition: ComponentTransition
|
||||
if !transition.animation.isImmediate {
|
||||
alphaTransition = .easeInOut(duration: 0.25)
|
||||
} else {
|
||||
alphaTransition = .immediate
|
||||
}
|
||||
|
||||
if themeUpdated {
|
||||
self.backgroundColor = environment.theme.list.blocksBackgroundColor
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let _ = alphaTransition
|
||||
let _ = presentationData
|
||||
|
||||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Send a Gift", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 100.0)
|
||||
)
|
||||
let navigationTitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - navigationTitleSize.width) / 2.0), y: environment.statusBarHeight + floor((environment.navigationHeight - environment.statusBarHeight - navigationTitleSize.height) / 2.0)), size: navigationTitleSize)
|
||||
if let navigationTitleView = self.navigationTitle.view {
|
||||
if navigationTitleView.superview == nil {
|
||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||
navigationBar.view.addSubview(navigationTitleView)
|
||||
}
|
||||
}
|
||||
transition.setFrame(view: navigationTitleView, frame: navigationTitleFrame)
|
||||
}
|
||||
|
||||
let bottomContentInset: CGFloat = 24.0
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let sectionSpacing: CGFloat = 24.0
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
|
||||
contentHeight += environment.navigationHeight
|
||||
contentHeight += 26.0
|
||||
|
||||
self.recenterOnTag = nil
|
||||
if let hint = transition.userData(TextFieldComponent.AnimationHint.self), let targetView = hint.view {
|
||||
if let textView = self.introSection.findTaggedView(tag: self.textInputTag) {
|
||||
if targetView.isDescendant(of: textView) {
|
||||
self.recenterOnTag = self.textInputTag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var introSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
introSectionItems.append(AnyComponentWithIdentity(id: introSectionItems.count, component: AnyComponent(Rectangle(color: .clear, height: 346.0, tag: self.introPlaceholderTag))))
|
||||
introSectionItems.append(AnyComponentWithIdentity(id: introSectionItems.count, component: AnyComponent(ListMultilineTextFieldItemComponent(
|
||||
externalState: self.textInputState,
|
||||
context: component.context,
|
||||
theme: environment.theme,
|
||||
strings: environment.strings,
|
||||
initialText: "",
|
||||
resetText: self.resetText.flatMap {
|
||||
return ListMultilineTextFieldItemComponent.ResetText(value: $0)
|
||||
},
|
||||
placeholder: environment.strings.Business_Intro_IntroTextPlaceholder,
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
returnKeyType: .done,
|
||||
characterLimit: 70,
|
||||
displayCharacterLimit: true,
|
||||
emptyLineHandling: .notAllowed,
|
||||
updated: { _ in
|
||||
},
|
||||
returnKeyAction: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let titleView = self.introSection.findTaggedView(tag: self.textInputTag) as? ListMultilineTextFieldItemComponent.View {
|
||||
titleView.endEditing(true)
|
||||
}
|
||||
},
|
||||
textUpdateTransition: .spring(duration: 0.4),
|
||||
tag: self.textInputTag
|
||||
))))
|
||||
self.resetText = nil
|
||||
|
||||
let introSectionSize = self.introSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "CUSTOMIZE YOUR GIFT",
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
footer: nil,
|
||||
items: introSectionItems
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
|
||||
)
|
||||
let introSectionFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: introSectionSize)
|
||||
if let introSectionView = self.introSection.view {
|
||||
if introSectionView.superview == nil {
|
||||
self.scrollView.addSubview(introSectionView)
|
||||
self.introSection.parentState = state
|
||||
}
|
||||
transition.setFrame(view: introSectionView, frame: introSectionFrame)
|
||||
}
|
||||
contentHeight += introSectionSize.height
|
||||
contentHeight += sectionSpacing
|
||||
|
||||
// let titleText: String
|
||||
// if self.titleInputState.text.string.isEmpty {
|
||||
// titleText = environment.strings.Conversation_EmptyPlaceholder
|
||||
// } else {
|
||||
// let rawTitle = self.titleInputState.text.string
|
||||
// titleText = rawTitle.count <= maxTitleLength ? rawTitle : String(rawTitle[rawTitle.startIndex ..< rawTitle.index(rawTitle.startIndex, offsetBy: maxTitleLength)])
|
||||
// }
|
||||
|
||||
// let textText: String
|
||||
// if self.textInputState.text.string.isEmpty {
|
||||
// textText = environment.strings.Conversation_GreetingText
|
||||
// } else {
|
||||
// let rawText = self.textInputState.text.string
|
||||
// textText = rawText.count <= maxTextLength ? rawText : String(rawText[rawText.startIndex ..< rawText.index(rawText.startIndex, offsetBy: maxTextLength)])
|
||||
// }
|
||||
|
||||
let listItemParams = ListViewItemLayoutParams(width: availableSize.width - sideInset * 2.0, leftInset: 0.0, rightInset: 0.0, availableHeight: 10000.0, isStandalone: true)
|
||||
let introContentSize = self.introContent.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(
|
||||
ListItemComponentAdaptor(
|
||||
itemGenerator: ChatGiftPreviewItem(
|
||||
context: component.context,
|
||||
theme: environment.theme,
|
||||
componentTheme: environment.theme,
|
||||
strings: environment.strings,
|
||||
sectionId: 0,
|
||||
fontSize: presentationData.chatFontSize,
|
||||
chatBubbleCorners: presentationData.chatBubbleCorners,
|
||||
wallpaper: presentationData.chatWallpaper,
|
||||
dateTimeFormat: environment.dateTimeFormat,
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||
accountPeer: self.peerMap[component.context.account.peerId],
|
||||
gift: component.gift,
|
||||
text: self.textInputState.text.string
|
||||
),
|
||||
params: listItemParams
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
|
||||
)
|
||||
if let introContentView = self.introContent.view {
|
||||
if introContentView.superview == nil {
|
||||
if let placeholderView = self.introSection.findTaggedView(tag: self.introPlaceholderTag) {
|
||||
placeholderView.addSubview(introContentView)
|
||||
}
|
||||
}
|
||||
transition.setFrame(view: introContentView, frame: CGRect(origin: CGPoint(), size: introContentSize))
|
||||
}
|
||||
|
||||
if self.recenterOnTag == nil && self.previousHadInputHeight != (environment.inputHeight > 0.0) {
|
||||
if self.textInputState.isEditing {
|
||||
self.recenterOnTag = self.textInputTag
|
||||
}
|
||||
}
|
||||
self.previousHadInputHeight = environment.inputHeight > 0.0
|
||||
|
||||
let peerName = self.peerMap[component.peerId]?.compactDisplayTitle ?? ""
|
||||
let hideSectionSize = self.hideSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: nil,
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Hide my name and message from visitors to \(peerName)'s profile. \(peerName) will still see your name and message.",
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
items: [
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Hide My Name",
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 1
|
||||
))),
|
||||
], alignment: .left, spacing: 2.0)),
|
||||
accessory: .toggle(ListActionItemComponent.Toggle(style: .regular, isOn: self.hideName, action: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.hideName = !self.hideName
|
||||
self.state?.updated(transition: .spring(duration: 0.4))
|
||||
})),
|
||||
action: nil
|
||||
)))
|
||||
]
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
|
||||
)
|
||||
let hideSectionFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: hideSectionSize)
|
||||
if let hideSectionView = self.hideSection.view {
|
||||
if hideSectionView.superview == nil {
|
||||
self.scrollView.addSubview(hideSectionView)
|
||||
}
|
||||
transition.setFrame(view: hideSectionView, frame: hideSectionFrame)
|
||||
}
|
||||
contentHeight += hideSectionSize.height
|
||||
|
||||
contentHeight += bottomContentInset
|
||||
|
||||
let inputHeight: CGFloat = environment.inputHeight
|
||||
let combinedBottomInset = max(inputHeight, environment.safeInsets.bottom)
|
||||
contentHeight += combinedBottomInset
|
||||
|
||||
|
||||
if self.starImage == nil || self.starImage?.1 !== environment.theme {
|
||||
self.starImage = (generateTintedImage(image: UIImage(bundleImageName: "Item List/PremiumIcon"), color: environment.theme.list.itemCheckColors.foregroundColor)!, environment.theme)
|
||||
}
|
||||
let amountString = presentationStringsFormattedNumber(Int32(component.gift.price), presentationData.dateTimeFormat.groupingSeparator)
|
||||
let buttonAttributedString = NSMutableAttributedString(string: "Send a Gift for # \(amountString)", font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
|
||||
if let range = buttonAttributedString.string.range(of: "#"), let starImage = self.starImage?.0 {
|
||||
buttonAttributedString.addAttribute(.attachment, value: starImage, range: NSRange(range, in: buttonAttributedString.string))
|
||||
buttonAttributedString.addAttribute(.foregroundColor, value: environment.theme.list.itemCheckColors.foregroundColor, range: NSRange(range, in: buttonAttributedString.string))
|
||||
buttonAttributedString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: buttonAttributedString.string))
|
||||
}
|
||||
|
||||
let buttonSize = self.button.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
color: environment.theme.list.itemCheckColors.fillColor,
|
||||
foreground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9),
|
||||
cornerRadius: 10.0
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(buttonAttributedString)))
|
||||
),
|
||||
isEnabled: true,
|
||||
displaysProgress: false,
|
||||
action: { [weak self] in
|
||||
self?.proceed()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50)
|
||||
)
|
||||
if let buttonView = self.button.view {
|
||||
if buttonView.superview == nil {
|
||||
self.addSubview(buttonView)
|
||||
}
|
||||
buttonView.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - buttonSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - buttonSize.height), size: buttonSize)
|
||||
}
|
||||
|
||||
let previousBounds = self.scrollView.bounds
|
||||
|
||||
self.ignoreScrolling = true
|
||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
||||
self.scrollView.frame = CGRect(origin: CGPoint(), size: availableSize)
|
||||
}
|
||||
if self.scrollView.contentSize != contentSize {
|
||||
self.scrollView.contentSize = contentSize
|
||||
}
|
||||
let scrollInsets = UIEdgeInsets(top: environment.navigationHeight, left: 0.0, bottom: 0.0, right: 0.0)
|
||||
if self.scrollView.scrollIndicatorInsets != scrollInsets {
|
||||
self.scrollView.scrollIndicatorInsets = scrollInsets
|
||||
}
|
||||
|
||||
if !previousBounds.isEmpty, !transition.animation.isImmediate {
|
||||
let bounds = self.scrollView.bounds
|
||||
if bounds.maxY != previousBounds.maxY {
|
||||
let offsetY = previousBounds.maxY - bounds.maxY
|
||||
transition.animateBoundsOrigin(view: self.scrollView, from: CGPoint(x: 0.0, y: offsetY), to: CGPoint(), additive: true)
|
||||
}
|
||||
}
|
||||
|
||||
if let recenterOnTag = self.recenterOnTag {
|
||||
self.recenterOnTag = nil
|
||||
|
||||
if let targetView = self.introSection.findTaggedView(tag: recenterOnTag) {
|
||||
let caretRect = targetView.convert(targetView.bounds, to: self.scrollView)
|
||||
var scrollViewBounds = self.scrollView.bounds
|
||||
let minButtonDistance: CGFloat = 16.0
|
||||
if -scrollViewBounds.minY + caretRect.maxY > availableSize.height - combinedBottomInset - minButtonDistance {
|
||||
scrollViewBounds.origin.y = -(availableSize.height - combinedBottomInset - minButtonDistance - caretRect.maxY)
|
||||
if scrollViewBounds.origin.y < 0.0 {
|
||||
scrollViewBounds.origin.y = 0.0
|
||||
}
|
||||
}
|
||||
if self.scrollView.bounds != scrollViewBounds {
|
||||
transition.setBounds(view: self.scrollView, bounds: scrollViewBounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.topOverscrollLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: -3000.0), size: CGSize(width: availableSize.width, height: 3000.0))
|
||||
self.ignoreScrolling = false
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
||||
func makeView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
public final class GiftSetupScreen: ViewControllerComponentContainer {
|
||||
private let context: AccountContext
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
peerId: EnginePeer.Id,
|
||||
gift: StarGift
|
||||
) {
|
||||
self.context = context
|
||||
|
||||
super.init(context: context, component: GiftSetupScreenComponent(
|
||||
context: context,
|
||||
peerId: peerId,
|
||||
gift: gift
|
||||
), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil)
|
||||
|
||||
self.title = ""
|
||||
//self.navigationItem.backBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||
|
||||
self.scrollToTop = { [weak self] in
|
||||
guard let self, let componentView = self.node.hostView.componentView as? GiftSetupScreenComponent.View else {
|
||||
return
|
||||
}
|
||||
componentView.scrollToTop()
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
@objc private func cancelPressed() {
|
||||
self.dismiss()
|
||||
}
|
||||
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
45
submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD
Normal file
45
submodules/TelegramUI/Components/Gifts/GiftViewScreen/BUILD
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "GiftViewScreen",
|
||||
module_name = "GiftViewScreen",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/MultilineTextWithEntitiesComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/Components/SheetComponent",
|
||||
"//submodules/Components/SolidRoundedButtonComponent",
|
||||
"//submodules/TelegramUI/Components/Stars/StarsAvatarComponent",
|
||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
|
||||
"//submodules/UndoUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,7 @@ public enum PeerInfoPaneKey: Int32 {
|
|||
case gifs
|
||||
case groupsInCommon
|
||||
case recommended
|
||||
case gifts
|
||||
}
|
||||
|
||||
public struct PeerInfoStatusData: Equatable {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ final class PeerInfoRecommendedChannelsPaneNode: ASDisplayNode, PeerInfoPaneNode
|
|||
private let listNode: ListView
|
||||
private var currentEntries: [RecommendedChannelsListEntry] = []
|
||||
private var currentState: (RecommendedChannels?, Bool)?
|
||||
private var canLoadMore: Bool = false
|
||||
private var enqueuedTransactions: [RecommendedChannelsListTransaction] = []
|
||||
|
||||
private var unlockBackground: UIImageView?
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ final class PeerInfoScreenData {
|
|||
let starsRevenueStatsState: StarsRevenueStats?
|
||||
let starsRevenueStatsContext: StarsRevenueStatsContext?
|
||||
let revenueStatsState: RevenueStats?
|
||||
let profileGiftsContext: ProfileGiftsContext?
|
||||
|
||||
let _isContact: Bool
|
||||
var forceIsContact: Bool = false
|
||||
|
|
@ -428,7 +429,8 @@ final class PeerInfoScreenData {
|
|||
starsState: StarsContext.State?,
|
||||
starsRevenueStatsState: StarsRevenueStats?,
|
||||
starsRevenueStatsContext: StarsRevenueStatsContext?,
|
||||
revenueStatsState: RevenueStats?
|
||||
revenueStatsState: RevenueStats?,
|
||||
profileGiftsContext: ProfileGiftsContext?
|
||||
) {
|
||||
self.peer = peer
|
||||
self.chatPeer = chatPeer
|
||||
|
|
@ -463,6 +465,7 @@ final class PeerInfoScreenData {
|
|||
self.starsRevenueStatsState = starsRevenueStatsState
|
||||
self.starsRevenueStatsContext = starsRevenueStatsContext
|
||||
self.revenueStatsState = revenueStatsState
|
||||
self.profileGiftsContext = profileGiftsContext
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -955,7 +958,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||
starsState: starsState,
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1000,7 +1004,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
starsState: nil,
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
))
|
||||
case let .user(userPeerId, secretChatId, kind):
|
||||
let groupsInCommon: GroupsInCommonContext?
|
||||
|
|
@ -1012,6 +1017,13 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
groupsInCommon = nil
|
||||
}
|
||||
|
||||
let profileGiftsContext: ProfileGiftsContext?
|
||||
if case .user = kind {
|
||||
profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: userPeerId)
|
||||
} else {
|
||||
profileGiftsContext = nil
|
||||
}
|
||||
|
||||
enum StatusInputData: Equatable {
|
||||
case none
|
||||
case presence(TelegramUserPresence)
|
||||
|
|
@ -1246,7 +1258,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
return (starsRevenueStatsContext, state.stats)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return combineLatest(
|
||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, isMyProfile: isMyProfile, chatLocationContextHolder: chatLocationContextHolder),
|
||||
|
|
@ -1272,11 +1284,22 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
if let hasStoryArchive, hasStoryArchive {
|
||||
availablePanes?.insert(.storyArchive, at: 1)
|
||||
}
|
||||
if availablePanes != nil, profileGiftsContext != nil, let cachedData = peerView.cachedData as? CachedUserData {
|
||||
if let starGiftsCount = cachedData.starGiftsCount, starGiftsCount > 0 {
|
||||
availablePanes?.insert(.gifts, at: hasStoryArchive == true ? 2 : 1)
|
||||
}
|
||||
}
|
||||
} else if let hasStories {
|
||||
if hasStories, peerView.peers[peerView.peerId] is TelegramUser, peerView.peerId != context.account.peerId {
|
||||
availablePanes?.insert(.stories, at: 0)
|
||||
}
|
||||
|
||||
if availablePanes != nil, profileGiftsContext != nil, let cachedData = peerView.cachedData as? CachedUserData {
|
||||
if let starGiftsCount = cachedData.starGiftsCount, starGiftsCount > 0 {
|
||||
availablePanes?.insert(.gifts, at: hasStories ? 1 : 0)
|
||||
}
|
||||
}
|
||||
|
||||
if availablePanes != nil, groupsInCommon != nil, let cachedData = peerView.cachedData as? CachedUserData {
|
||||
if cachedData.commonGroupCount != 0 {
|
||||
availablePanes?.append(.groupsInCommon)
|
||||
|
|
@ -1370,7 +1393,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
starsState: nil,
|
||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||
revenueStatsState: nil
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: profileGiftsContext
|
||||
)
|
||||
}
|
||||
case .channel:
|
||||
|
|
@ -1579,7 +1603,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
starsState: nil,
|
||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||
revenueStatsState: revenueContextAndState.1
|
||||
revenueStatsState: revenueContextAndState.1,
|
||||
profileGiftsContext: nil
|
||||
)
|
||||
}
|
||||
case let .group(groupId):
|
||||
|
|
@ -1879,7 +1904,8 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||
starsState: nil,
|
||||
starsRevenueStatsState: nil,
|
||||
starsRevenueStatsContext: nil,
|
||||
revenueStatsState: nil
|
||||
revenueStatsState: nil,
|
||||
profileGiftsContext: nil
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,6 +407,8 @@ private final class PeerInfoPendingPane {
|
|||
var captureProtected = data.peer?.isCopyProtectionEnabled ?? false
|
||||
let paneNode: PeerInfoPaneNode
|
||||
switch key {
|
||||
case .gifts:
|
||||
paneNode = PeerInfoGiftsPaneNode(context: context, peerId: peerId, chatControllerInteraction: chatControllerInteraction, openPeerContextAction: openPeerContextAction, profileGifts: data.profileGiftsContext!)
|
||||
case .stories, .storyArchive, .botPreview:
|
||||
var canManage = false
|
||||
if let peer = data.peer {
|
||||
|
|
@ -1149,6 +1151,9 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
|||
title = presentationData.strings.DialogList_TabTitle
|
||||
case .savedMessages:
|
||||
title = presentationData.strings.PeerInfo_SavedMessagesTabTitle
|
||||
case .gifts:
|
||||
//TODO:localize
|
||||
title = "Gifts"
|
||||
}
|
||||
return PeerInfoPaneSpecifier(key: key, title: title)
|
||||
}, selectedPane: self.currentPaneKey, disableSwitching: disableTabSwitching, transitionFraction: self.transitionFraction, transition: transition)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ swift_library(
|
|||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/TelegramUI/Components/TabSelectorComponent",
|
||||
"//submodules/TelegramUI/Components/Settings/LanguageSelectionScreen",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftItemComponent",
|
||||
"//submodules/TelegramUI/Components/Gifts/GiftViewScreen",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,391 @@
|
|||
import AsyncDisplayKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import ContextUI
|
||||
import PhotoResources
|
||||
import TelegramUIPreferences
|
||||
import ItemListPeerItem
|
||||
import ItemListPeerActionItem
|
||||
import MergeLists
|
||||
import ItemListUI
|
||||
import ChatControllerInteraction
|
||||
import MultilineTextComponent
|
||||
import BalancedTextComponent
|
||||
import Markdown
|
||||
import PeerInfoPaneNode
|
||||
import GiftItemComponent
|
||||
import PlainButtonComponent
|
||||
import GiftViewScreen
|
||||
import SolidRoundedButtonNode
|
||||
|
||||
public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDelegate {
|
||||
private let context: AccountContext
|
||||
private let peerId: PeerId
|
||||
private let profileGifts: ProfileGiftsContext
|
||||
|
||||
private var dataDisposable: Disposable?
|
||||
|
||||
private let chatControllerInteraction: ChatControllerInteraction
|
||||
private let openPeerContextAction: (Bool, Peer, ASDisplayNode, ContextGesture?) -> Void
|
||||
|
||||
public weak var parentController: ViewController?
|
||||
|
||||
private let backgroundNode: ASDisplayNode
|
||||
private let scrollNode: ASScrollNode
|
||||
|
||||
private var unlockBackground: UIImageView?
|
||||
private var unlockText: ComponentView<Empty>?
|
||||
private var unlockButton: SolidRoundedButtonNode?
|
||||
|
||||
private var currentParams: (size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, isScrollingLockedAtTop: Bool, presentationData: PresentationData)?
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
private let presentationDataPromise = Promise<PresentationData>()
|
||||
|
||||
private let ready = Promise<Bool>()
|
||||
private var didSetReady: Bool = false
|
||||
public var isReady: Signal<Bool, NoError> {
|
||||
return self.ready.get()
|
||||
}
|
||||
|
||||
private let statusPromise = Promise<PeerInfoStatusData?>(nil)
|
||||
public var status: Signal<PeerInfoStatusData?, NoError> {
|
||||
self.statusPromise.get()
|
||||
}
|
||||
|
||||
public var tabBarOffsetUpdated: ((ContainedViewLayoutTransition) -> Void)?
|
||||
public var tabBarOffset: CGFloat {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
private var starsProducts: [ProfileGiftsContext.State.StarGift]?
|
||||
|
||||
private var starsItems: [AnyHashable: ComponentView<Empty>] = [:]
|
||||
|
||||
public init(context: AccountContext, peerId: PeerId, chatControllerInteraction: ChatControllerInteraction, openPeerContextAction: @escaping (Bool, Peer, ASDisplayNode, ContextGesture?) -> Void, profileGifts: ProfileGiftsContext) {
|
||||
self.context = context
|
||||
self.peerId = peerId
|
||||
self.chatControllerInteraction = chatControllerInteraction
|
||||
self.openPeerContextAction = openPeerContextAction
|
||||
self.profileGifts = profileGifts
|
||||
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.scrollNode = ASScrollNode()
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.addSubnode(self.scrollNode)
|
||||
|
||||
self.dataDisposable = (profileGifts.state
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] state in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.statusPromise.set(.single(PeerInfoStatusData(text: presentationData.strings.SharedMedia_GiftCount(state.count ?? 0), isActivity: true, key: .gifts)))
|
||||
self.starsProducts = state.gifts
|
||||
|
||||
if !self.didSetReady {
|
||||
self.didSetReady = true
|
||||
self.ready.set(.single(true))
|
||||
}
|
||||
|
||||
self.updateScrolling()
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.dataDisposable?.dispose()
|
||||
}
|
||||
|
||||
public override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.scrollNode.view.delegate = self
|
||||
}
|
||||
|
||||
public func ensureMessageIsVisible(id: MessageId) {
|
||||
}
|
||||
|
||||
public func scrollToTop() -> Bool {
|
||||
self.scrollNode.view.setContentOffset(.zero, animated: true)
|
||||
return true
|
||||
}
|
||||
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
self.updateScrolling()
|
||||
}
|
||||
|
||||
func updateScrolling() {
|
||||
if let starsProducts = self.starsProducts, let params = self.currentParams {
|
||||
let optionSpacing: CGFloat = 10.0
|
||||
let sideInset = params.sideInset + 16.0
|
||||
|
||||
let itemsInRow = min(starsProducts.count, 3)
|
||||
let optionWidth = (params.size.width - sideInset * 2.0 - optionSpacing * CGFloat(itemsInRow - 1)) / CGFloat(itemsInRow)
|
||||
|
||||
let starsOptionSize = CGSize(width: optionWidth, height: 154.0)
|
||||
|
||||
let visibleBounds = self.scrollNode.bounds.insetBy(dx: 0.0, dy: -10.0)
|
||||
|
||||
var validIds: [AnyHashable] = []
|
||||
var itemFrame = CGRect(origin: CGPoint(x: sideInset, y: 60.0), size: starsOptionSize)
|
||||
for product in starsProducts {
|
||||
let itemId = AnyHashable(product.date)
|
||||
validIds.append(itemId)
|
||||
|
||||
let itemTransition = ComponentTransition.immediate
|
||||
let visibleItem: ComponentView<Empty>
|
||||
if let current = self.starsItems[itemId] {
|
||||
visibleItem = current
|
||||
} else {
|
||||
visibleItem = ComponentView()
|
||||
self.starsItems[itemId] = visibleItem
|
||||
}
|
||||
|
||||
var isVisible = false
|
||||
if visibleBounds.intersects(itemFrame) {
|
||||
isVisible = true
|
||||
}
|
||||
|
||||
if isVisible {
|
||||
let ribbonText: String?
|
||||
if let availability = product.gift.availability {
|
||||
//TODO:localize
|
||||
ribbonText = "1 of \(compactNumericCountString(Int(availability.total)))"
|
||||
} else {
|
||||
ribbonText = nil
|
||||
}
|
||||
let _ = visibleItem.update(
|
||||
transition: itemTransition,
|
||||
component: AnyComponent(
|
||||
PlainButtonComponent(
|
||||
content: AnyComponent(
|
||||
GiftItemComponent(
|
||||
context: self.context,
|
||||
theme: params.presentationData.theme,
|
||||
peer: product.fromPeer.flatMap { .peer($0) } ?? .anonymous,
|
||||
subject: .starGift(product.gift.id, product.gift.file),
|
||||
price: "⭐️ \(product.gift.price)",
|
||||
ribbon: ribbonText.flatMap { GiftItemComponent.Ribbon(text: $0, color: .blue) },
|
||||
isHidden: !product.savedToProfile
|
||||
)
|
||||
),
|
||||
effectAlignment: .center,
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let controller = GiftViewScreen(
|
||||
context: self.context,
|
||||
subject: .profileGift(self.peerId, product),
|
||||
updateSavedToProfile: { [weak self] added in
|
||||
guard let self, let messageId = product.messageId else {
|
||||
return
|
||||
}
|
||||
self.profileGifts.updateStarGiftAddedToProfile(messageId: messageId, added: added)
|
||||
},
|
||||
convertToStars: { [weak self] in
|
||||
guard let self, let messageId = product.messageId else {
|
||||
return
|
||||
}
|
||||
self.profileGifts.convertStarGift(messageId: messageId)
|
||||
}
|
||||
)
|
||||
self.parentController?.push(controller)
|
||||
|
||||
},
|
||||
animateAlpha: false
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: starsOptionSize
|
||||
)
|
||||
if let itemView = visibleItem.view {
|
||||
if itemView.superview == nil {
|
||||
self.scrollNode.view.addSubview(itemView)
|
||||
}
|
||||
itemTransition.setFrame(view: itemView, frame: itemFrame)
|
||||
}
|
||||
}
|
||||
itemFrame.origin.x += itemFrame.width + optionSpacing
|
||||
if itemFrame.maxX > params.size.width {
|
||||
itemFrame.origin.x = sideInset
|
||||
itemFrame.origin.y += starsOptionSize.height + optionSpacing
|
||||
}
|
||||
}
|
||||
|
||||
var contentHeight = ceil(CGFloat(starsProducts.count) / 3.0) * starsOptionSize.height + 60.0 + 16.0
|
||||
|
||||
if self.peerId == self.context.account.peerId {
|
||||
let transition = ComponentTransition.immediate
|
||||
|
||||
let size = params.size
|
||||
let sideInset = params.sideInset
|
||||
let bottomInset = params.bottomInset
|
||||
let presentationData = params.presentationData
|
||||
|
||||
let themeUpdated = self.theme !== presentationData.theme
|
||||
self.theme = presentationData.theme
|
||||
|
||||
let unlockText: ComponentView<Empty>
|
||||
let unlockBackground: UIImageView
|
||||
let unlockButton: SolidRoundedButtonNode
|
||||
if let current = self.unlockText {
|
||||
unlockText = current
|
||||
} else {
|
||||
unlockText = ComponentView<Empty>()
|
||||
self.unlockText = unlockText
|
||||
}
|
||||
|
||||
if let current = self.unlockBackground {
|
||||
unlockBackground = current
|
||||
} else {
|
||||
unlockBackground = UIImageView()
|
||||
unlockBackground.contentMode = .scaleToFill
|
||||
self.view.addSubview(unlockBackground)
|
||||
self.unlockBackground = unlockBackground
|
||||
}
|
||||
|
||||
if let current = self.unlockButton {
|
||||
unlockButton = current
|
||||
} else {
|
||||
unlockButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: presentationData.theme), height: 50.0, cornerRadius: 10.0)
|
||||
self.view.addSubview(unlockButton.view)
|
||||
self.unlockButton = unlockButton
|
||||
|
||||
//TODO:localize
|
||||
unlockButton.title = "Send Gifts to Friends"
|
||||
|
||||
unlockButton.pressed = { [weak self] in
|
||||
self?.buttonPressed()
|
||||
}
|
||||
}
|
||||
|
||||
if themeUpdated {
|
||||
let topColor = presentationData.theme.list.plainBackgroundColor.withAlphaComponent(0.0)
|
||||
let bottomColor = presentationData.theme.list.plainBackgroundColor
|
||||
unlockBackground.image = generateGradientImage(size: CGSize(width: 1.0, height: 170.0), colors: [topColor, bottomColor, bottomColor], locations: [0.0, 0.3, 1.0])
|
||||
unlockButton.updateTheme(SolidRoundedButtonTheme(theme: presentationData.theme))
|
||||
}
|
||||
|
||||
let textFont = Font.regular(13.0)
|
||||
let boldTextFont = Font.semibold(13.0)
|
||||
let textColor = presentationData.theme.list.itemSecondaryTextColor
|
||||
let linkColor = presentationData.theme.list.itemAccentColor
|
||||
let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: boldTextFont, textColor: linkColor), linkAttribute: { _ in
|
||||
return nil
|
||||
})
|
||||
|
||||
let scrollOffset: CGFloat = min(0.0, self.scrollNode.view.contentOffset.y + bottomInset + 80.0)
|
||||
|
||||
transition.setFrame(view: unlockBackground, frame: CGRect(x: 0.0, y: size.height - bottomInset - 170.0 + scrollOffset, width: size.width, height: bottomInset + 170.0))
|
||||
|
||||
let buttonSideInset = sideInset + 16.0
|
||||
let buttonSize = CGSize(width: size.width - buttonSideInset * 2.0, height: 50.0)
|
||||
transition.setFrame(view: unlockButton.view, frame: CGRect(origin: CGPoint(x: buttonSideInset, y: size.height - bottomInset - buttonSize.height - 26.0), size: buttonSize))
|
||||
let _ = unlockButton.updateLayout(width: buttonSize.width, transition: .immediate)
|
||||
|
||||
let unlockSize = unlockText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
BalancedTextComponent(
|
||||
text: .markdown(text: "These gifts were sent to you by other users. Tap on a gift to exchange it for Stars or change its privacy settings.", attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: size.width - 32.0, height: 200.0)
|
||||
)
|
||||
if let view = unlockText.view {
|
||||
if view.superview == nil {
|
||||
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.buttonPressed)))
|
||||
self.scrollNode.view.addSubview(view)
|
||||
}
|
||||
transition.setFrame(view: view, frame: CGRect(origin: CGPoint(x: floor((size.width - unlockSize.width) / 2.0), y: contentHeight), size: unlockSize))
|
||||
}
|
||||
contentHeight += unlockSize.height
|
||||
}
|
||||
contentHeight += params.bottomInset
|
||||
|
||||
let contentSize = CGSize(width: params.size.width, height: contentHeight)
|
||||
if self.scrollNode.view.contentSize != contentSize {
|
||||
self.scrollNode.view.contentSize = contentSize
|
||||
}
|
||||
}
|
||||
|
||||
let bottomOffset = max(0.0, self.scrollNode.view.contentSize.height - self.scrollNode.view.contentOffset.y - self.scrollNode.view.frame.height)
|
||||
if bottomOffset < 100.0 {
|
||||
self.profileGifts.loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
let _ = (self.context.account.stateManager.contactBirthdays
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] birthdays in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings(birthdays), completion: nil)
|
||||
controller.navigationPresentation = .modal
|
||||
self.chatControllerInteraction.navigationController()?.pushViewController(controller)
|
||||
})
|
||||
}
|
||||
|
||||
public func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) {
|
||||
self.currentParams = (size, sideInset, bottomInset, isScrollingLockedAtTop, presentationData)
|
||||
self.presentationDataPromise.set(.single(presentationData))
|
||||
|
||||
self.backgroundNode.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 48.0), size: size))
|
||||
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
if isScrollingLockedAtTop {
|
||||
self.scrollNode.view.contentOffset = .zero
|
||||
}
|
||||
self.scrollNode.view.isScrollEnabled = !isScrollingLockedAtTop
|
||||
|
||||
self.updateScrolling()
|
||||
}
|
||||
|
||||
public func findLoadedMessage(id: MessageId) -> Message? {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func updateHiddenMedia() {
|
||||
}
|
||||
|
||||
public func transferVelocity(_ velocity: CGFloat) {
|
||||
if velocity > 0.0 {
|
||||
// self.scrollNode.transferVelocity(velocity)
|
||||
}
|
||||
}
|
||||
|
||||
public func cancelPreviewGestures() {
|
||||
}
|
||||
|
||||
public func transitionNodeForGallery(messageId: MessageId, media: Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func addToTransitionSurface(view: UIView) {
|
||||
}
|
||||
|
||||
public func updateSelectedMessages(animated: Bool) {
|
||||
}
|
||||
}
|
||||
|
||||
private struct StarsGiftProduct: Equatable {
|
||||
let emoji: String
|
||||
let price: Int64
|
||||
let isLimited: Bool
|
||||
}
|
||||
|
|
@ -871,7 +871,10 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding, ListShimme
|
|||
}
|
||||
|
||||
let message = item.message
|
||||
let hasSpoiler = message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) && !self.revealedSpoilerMessageIds.contains(message.id)
|
||||
var hasSpoiler = message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) && !self.revealedSpoilerMessageIds.contains(message.id)
|
||||
if message.isSensitiveContent(platform: "ios") {
|
||||
hasSpoiler = true
|
||||
}
|
||||
layer.updateHasSpoiler(hasSpoiler: hasSpoiler)
|
||||
|
||||
var selectedMedia: Media?
|
||||
|
|
@ -1273,7 +1276,11 @@ public final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode,
|
|||
}
|
||||
strongSelf.chatControllerInteraction.toggleMessagesSelection([item.message.id], toggledValue)
|
||||
} else {
|
||||
let _ = strongSelf.chatControllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
|
||||
if item.message.isSensitiveContent(platform: "ios") {
|
||||
// strongSelf.context.currentContentSettings.with { $0 }.ignoreContentRestrictionReasons
|
||||
} else {
|
||||
let _ = strongSelf.chatControllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ItemShimmeringLoadingComponent",
|
||||
module_name = "ItemShimmeringLoadingComponent",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/Components/HierarchyTrackingLayer",
|
||||
"//submodules/TelegramUI/Components/TextLoadingEffect",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
@ -6,17 +6,25 @@ import HierarchyTrackingLayer
|
|||
import ComponentFlow
|
||||
import TextLoadingEffect
|
||||
|
||||
final class ItemLoadingComponent: Component {
|
||||
public final class ItemShimmeringLoadingComponent: Component {
|
||||
private let color: UIColor
|
||||
private let cornerRadius: CGFloat
|
||||
|
||||
public init(color: UIColor) {
|
||||
public init(
|
||||
color: UIColor,
|
||||
cornerRadius: CGFloat = 10.0
|
||||
) {
|
||||
self.color = color
|
||||
self.cornerRadius = cornerRadius
|
||||
}
|
||||
|
||||
public static func ==(lhs: ItemLoadingComponent, rhs: ItemLoadingComponent) -> Bool {
|
||||
public static func ==(lhs: ItemShimmeringLoadingComponent, rhs: ItemShimmeringLoadingComponent) -> Bool {
|
||||
if !lhs.color.isEqual(rhs.color) {
|
||||
return false
|
||||
}
|
||||
if lhs.cornerRadius != rhs.cornerRadius {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -28,16 +36,14 @@ final class ItemLoadingComponent: Component {
|
|||
private let borderMaskGradientView = UIImageView()
|
||||
private let borderMaskFillView = UIImageView()
|
||||
|
||||
private var component: ItemLoadingComponent?
|
||||
private var component: ItemShimmeringLoadingComponent?
|
||||
|
||||
override public init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.loadingView)
|
||||
self.addSubview(self.borderView)
|
||||
|
||||
self.borderView.image = generateFilledRoundedRectImage(size: CGSize(width: 24.0, height: 24.0), cornerRadius: 10.0, color: nil, strokeColor: .white, strokeWidth: 1.0 + UIScreenPixel, backgroundColor: nil)?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 10).withRenderingMode(.alwaysTemplate)
|
||||
|
||||
|
||||
self.borderMaskView.backgroundColor = .clear
|
||||
self.borderMaskFillView.backgroundColor = .white
|
||||
|
||||
|
|
@ -63,14 +69,23 @@ final class ItemLoadingComponent: Component {
|
|||
})
|
||||
}
|
||||
|
||||
func update(component: ItemLoadingComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
func update(component: ItemShimmeringLoadingComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
let isFirstTime = self.component == nil
|
||||
let previousCornerRadius = self.component?.cornerRadius
|
||||
|
||||
self.component = component
|
||||
|
||||
if previousCornerRadius != component.cornerRadius {
|
||||
self.borderView.image = generateFilledRoundedRectImage(size: CGSize(width: 24.0, height: 24.0), cornerRadius: component.cornerRadius, color: nil, strokeColor: .white, strokeWidth: 1.0 + UIScreenPixel, backgroundColor: nil)?.stretchableImage(withLeftCapWidth: Int(component.cornerRadius), topCapHeight: Int(component.cornerRadius)).withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
|
||||
self.borderView.tintColor = component.color
|
||||
|
||||
self.loadingView.update(color: component.color, rect: CGRect(origin: .zero, size: availableSize))
|
||||
self.loadingView.frame = CGRect(origin: .zero, size: availableSize)
|
||||
self.loadingView.layer.cornerRadius = component.cornerRadius
|
||||
self.loadingView.clipsToBounds = true
|
||||
|
||||
transition.setFrame(view: self.borderView, frame: CGRect(origin: .zero, size: availableSize))
|
||||
self.borderMaskView.frame = self.borderView.bounds
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "StarsIntroScreen",
|
||||
module_name = "StarsIntroScreen",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/Components/MultilineTextComponent",
|
||||
"//submodules/Components/BalancedTextComponent",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/ItemListUI",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/Components/SheetComponent",
|
||||
"//submodules/UndoUI",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/TelegramUI/Components/ListSectionComponent",
|
||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||
"//submodules/TelegramUI/Components/ScrollComponent",
|
||||
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||
"//submodules/TelegramUI/Components/ButtonComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/Components/SolidRoundedButtonComponent",
|
||||
"//submodules/Components/BlurredBackgroundComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import Markdown
|
||||
import TextFormat
|
||||
import TelegramPresentationData
|
||||
import ViewControllerComponent
|
||||
import ScrollComponent
|
||||
import BundleIconComponent
|
||||
import BalancedTextComponent
|
||||
import MultilineTextComponent
|
||||
import SolidRoundedButtonComponent
|
||||
import AccountContext
|
||||
import ScrollComponent
|
||||
import BlurredBackgroundComponent
|
||||
import PremiumStarComponent
|
||||
|
||||
private final class ScrollContent: CombinedComponent {
|
||||
typealias EnvironmentType = (ViewControllerComponentContainer.Environment, ScrollChildEnvironment)
|
||||
|
||||
let context: AccountContext
|
||||
let openExamples: () -> Void
|
||||
let dismiss: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
openExamples: @escaping () -> Void,
|
||||
dismiss: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.openExamples = openExamples
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
static func ==(lhs: ScrollContent, rhs: ScrollContent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
let star = Child(PremiumStarComponent.self)
|
||||
|
||||
let title = Child(BalancedTextComponent.self)
|
||||
let text = Child(BalancedTextComponent.self)
|
||||
let list = Child(List<Empty>.self)
|
||||
|
||||
return { context in
|
||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||
let component = context.component
|
||||
|
||||
let theme = environment.theme
|
||||
//let strings = environment.strings
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let textSideInset: CGFloat = 30.0 + environment.safeInsets.left
|
||||
|
||||
let titleFont = Font.semibold(20.0)
|
||||
let textFont = Font.regular(15.0)
|
||||
|
||||
let textColor = theme.actionSheet.primaryTextColor
|
||||
let secondaryTextColor = theme.actionSheet.secondaryTextColor
|
||||
let linkColor = theme.actionSheet.controlAccentColor
|
||||
|
||||
let spacing: CGFloat = 16.0
|
||||
var contentSize = CGSize(width: context.availableSize.width, height: 152.0)
|
||||
|
||||
let star = star.update(
|
||||
component: PremiumStarComponent(
|
||||
theme: environment.theme,
|
||||
isIntro: true,
|
||||
isVisible: true,
|
||||
hasIdleAnimations: true,
|
||||
colors: [
|
||||
UIColor(rgb: 0xe57d02),
|
||||
UIColor(rgb: 0xf09903),
|
||||
UIColor(rgb: 0xf9b004),
|
||||
UIColor(rgb: 0xfdd219)
|
||||
],
|
||||
particleColor: UIColor(rgb: 0xf9b004),
|
||||
backgroundColor: environment.theme.list.plainBackgroundColor
|
||||
),
|
||||
availableSize: CGSize(width: min(414.0, context.availableSize.width), height: 220.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(star
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: environment.navigationHeight + 24.0))
|
||||
)
|
||||
|
||||
let title = title.update(
|
||||
component: BalancedTextComponent(
|
||||
text: .plain(NSAttributedString(string: "What are Stars?", font: titleFont, textColor: textColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.1
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(title
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + title.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += title.size.height
|
||||
contentSize.height += spacing - 8.0
|
||||
|
||||
let text = text.update(
|
||||
component: BalancedTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Buy packages of Stars on Telegram that let you do following:", font: textFont, textColor: secondaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(text
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + text.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += text.size.height
|
||||
contentSize.height += spacing
|
||||
|
||||
var items: [AnyComponentWithIdentity<Empty>] = []
|
||||
items.append(
|
||||
AnyComponentWithIdentity(
|
||||
id: "gift",
|
||||
component: AnyComponent(ParagraphComponent(
|
||||
title: "Send Gifts to Friends",
|
||||
titleColor: textColor,
|
||||
text: "Give your friends gifts that can be kept on their profiles or converted to Stars.",
|
||||
textColor: secondaryTextColor,
|
||||
accentColor: linkColor,
|
||||
iconName: "Premium/StarsPerk/Gift",
|
||||
iconColor: linkColor
|
||||
))
|
||||
)
|
||||
)
|
||||
items.append(
|
||||
AnyComponentWithIdentity(
|
||||
id: "miniapp",
|
||||
component: AnyComponent(ParagraphComponent(
|
||||
title: "Use Stars in Miniapps",
|
||||
titleColor: textColor,
|
||||
text: "Buy additional content and services in Telegram miniapps. [See Examples >]()",
|
||||
textColor: secondaryTextColor,
|
||||
accentColor: linkColor,
|
||||
iconName: "Premium/StarsPerk/Miniapp",
|
||||
iconColor: linkColor,
|
||||
action: {
|
||||
component.openExamples()
|
||||
}
|
||||
))
|
||||
)
|
||||
)
|
||||
items.append(
|
||||
AnyComponentWithIdentity(
|
||||
id: "media",
|
||||
component: AnyComponent(ParagraphComponent(
|
||||
title: "Unlock Content in Channels",
|
||||
titleColor: textColor,
|
||||
text: "Get access to paid content and services in Telegram channels.",
|
||||
textColor: secondaryTextColor,
|
||||
accentColor: linkColor,
|
||||
iconName: "Premium/StarsPerk/Media",
|
||||
iconColor: linkColor
|
||||
))
|
||||
)
|
||||
)
|
||||
items.append(
|
||||
AnyComponentWithIdentity(
|
||||
id: "reaction",
|
||||
component: AnyComponent(ParagraphComponent(
|
||||
title: "Send Star Reactions",
|
||||
titleColor: textColor,
|
||||
text: "Support your favorite channels by sending Star reactions to their posts.",
|
||||
textColor: secondaryTextColor,
|
||||
accentColor: linkColor,
|
||||
iconName: "Premium/StarsPerk/Reaction",
|
||||
iconColor: linkColor
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
let list = list.update(
|
||||
component: List(items),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 10000.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(list
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + list.size.height / 2.0))
|
||||
)
|
||||
contentSize.height += list.size.height
|
||||
contentSize.height += spacing - 9.0
|
||||
|
||||
contentSize.height += 12.0 + 50.0
|
||||
if environment.safeInsets.bottom > 0 {
|
||||
contentSize.height += environment.safeInsets.bottom + 5.0
|
||||
} else {
|
||||
contentSize.height += 12.0
|
||||
}
|
||||
|
||||
return contentSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class ContainerComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let openExamples: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
openExamples: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.openExamples = openExamples
|
||||
}
|
||||
|
||||
static func ==(lhs: ContainerComponent, rhs: ContainerComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class State: ComponentState {
|
||||
var topContentOffset: CGFloat?
|
||||
var bottomContentOffset: CGFloat?
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State()
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
let background = Child(Rectangle.self)
|
||||
let scroll = Child(ScrollComponent<ViewControllerComponentContainer.Environment>.self)
|
||||
let bottomPanel = Child(BlurredBackgroundComponent.self)
|
||||
let bottomSeparator = Child(Rectangle.self)
|
||||
let actionButton = Child(SolidRoundedButtonComponent.self)
|
||||
let scrollExternalState = ScrollComponent<EnvironmentType>.ExternalState()
|
||||
|
||||
return { context in
|
||||
let environment = context.environment[EnvironmentType.self]
|
||||
let theme = environment.theme
|
||||
//let strings = environment.strings
|
||||
let state = context.state
|
||||
|
||||
let controller = environment.controller
|
||||
|
||||
let background = background.update(
|
||||
component: Rectangle(color: environment.theme.list.plainBackgroundColor),
|
||||
environment: {},
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(background
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
let scroll = scroll.update(
|
||||
component: ScrollComponent<EnvironmentType>(
|
||||
content: AnyComponent(ScrollContent(
|
||||
context: context.component.context,
|
||||
openExamples: context.component.openExamples,
|
||||
dismiss: {
|
||||
controller()?.dismiss()
|
||||
}
|
||||
)),
|
||||
externalState: scrollExternalState,
|
||||
contentInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 1.0, right: 0.0),
|
||||
contentOffsetUpdated: { [weak state] topContentOffset, bottomContentOffset in
|
||||
state?.topContentOffset = topContentOffset
|
||||
state?.bottomContentOffset = bottomContentOffset
|
||||
Queue.mainQueue().justDispatch {
|
||||
state?.updated(transition: .immediate)
|
||||
}
|
||||
},
|
||||
contentOffsetWillCommit: { targetContentOffset in
|
||||
}
|
||||
),
|
||||
environment: { environment },
|
||||
availableSize: context.availableSize,
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
context.add(scroll
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
)
|
||||
|
||||
let buttonHeight: CGFloat = 50.0
|
||||
let bottomPanelPadding: CGFloat = 12.0
|
||||
let bottomInset: CGFloat = environment.safeInsets.bottom > 0.0 ? environment.safeInsets.bottom + 5.0 : bottomPanelPadding
|
||||
let bottomPanelHeight = bottomPanelPadding + buttonHeight + bottomInset
|
||||
|
||||
let bottomPanelAlpha: CGFloat
|
||||
if scrollExternalState.contentHeight > context.availableSize.height {
|
||||
if let bottomContentOffset = state.bottomContentOffset {
|
||||
bottomPanelAlpha = min(16.0, bottomContentOffset) / 16.0
|
||||
} else {
|
||||
bottomPanelAlpha = 1.0
|
||||
}
|
||||
} else {
|
||||
bottomPanelAlpha = 0.0
|
||||
}
|
||||
|
||||
let bottomPanel = bottomPanel.update(
|
||||
component: BlurredBackgroundComponent(
|
||||
color: theme.rootController.tabBar.backgroundColor
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: bottomPanelHeight),
|
||||
transition: context.transition
|
||||
)
|
||||
let bottomSeparator = bottomSeparator.update(
|
||||
component: Rectangle(
|
||||
color: theme.rootController.tabBar.separatorColor
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: UIScreenPixel),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
context.add(bottomPanel
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height - bottomPanel.size.height / 2.0))
|
||||
.opacity(bottomPanelAlpha)
|
||||
)
|
||||
context.add(bottomSeparator
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height - bottomPanel.size.height))
|
||||
.opacity(bottomPanelAlpha)
|
||||
)
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let actionButton = actionButton.update(
|
||||
component: SolidRoundedButtonComponent(
|
||||
title: "Got It",
|
||||
theme: SolidRoundedButtonComponent.Theme(
|
||||
backgroundColor: theme.list.itemCheckColors.fillColor,
|
||||
backgroundColors: [],
|
||||
foregroundColor: theme.list.itemCheckColors.foregroundColor
|
||||
),
|
||||
font: .bold,
|
||||
fontSize: 17.0,
|
||||
height: buttonHeight,
|
||||
cornerRadius: 10.0,
|
||||
gloss: false,
|
||||
iconName: nil,
|
||||
animationName: nil,
|
||||
iconPosition: .left,
|
||||
action: {
|
||||
controller()?.dismiss()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
|
||||
transition: context.transition
|
||||
)
|
||||
context.add(actionButton
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height - bottomPanelHeight + bottomPanelPadding + actionButton.size.height / 2.0))
|
||||
)
|
||||
|
||||
return context.availableSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class StarsIntroScreen: ViewControllerComponentContainer {
|
||||
private let context: AccountContext
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
forceDark: Bool = false
|
||||
) {
|
||||
self.context = context
|
||||
|
||||
var openExamplesImpl: (() -> Void)?
|
||||
super.init(
|
||||
context: context,
|
||||
component: ContainerComponent(
|
||||
context: context,
|
||||
openExamples: {
|
||||
openExamplesImpl?()
|
||||
}
|
||||
),
|
||||
navigationBarAppearance: .none,
|
||||
statusBarStyle: .ignore,
|
||||
theme: forceDark ? .dark : .default
|
||||
)
|
||||
|
||||
self.navigationPresentation = .modal
|
||||
|
||||
openExamplesImpl = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let _ = (context.sharedContext.makeMiniAppListScreenInitialData(context: context)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] initialData in
|
||||
guard let self, let navigationController = self.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
navigationController.pushViewController(context.sharedContext.makeMiniAppListScreen(context: context, initialData: initialData))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
private final class ParagraphComponent: CombinedComponent {
|
||||
let title: String
|
||||
let titleColor: UIColor
|
||||
let text: String
|
||||
let textColor: UIColor
|
||||
let accentColor: UIColor
|
||||
let iconName: String
|
||||
let iconColor: UIColor
|
||||
let action: () -> Void
|
||||
|
||||
public init(
|
||||
title: String,
|
||||
titleColor: UIColor,
|
||||
text: String,
|
||||
textColor: UIColor,
|
||||
accentColor: UIColor,
|
||||
iconName: String,
|
||||
iconColor: UIColor,
|
||||
action: @escaping () -> Void = {}
|
||||
) {
|
||||
self.title = title
|
||||
self.titleColor = titleColor
|
||||
self.text = text
|
||||
self.textColor = textColor
|
||||
self.accentColor = accentColor
|
||||
self.iconName = iconName
|
||||
self.iconColor = iconColor
|
||||
self.action = action
|
||||
}
|
||||
|
||||
static func ==(lhs: ParagraphComponent, rhs: ParagraphComponent) -> Bool {
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
if lhs.titleColor != rhs.titleColor {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
if lhs.textColor != rhs.textColor {
|
||||
return false
|
||||
}
|
||||
if lhs.accentColor != rhs.accentColor {
|
||||
return false
|
||||
}
|
||||
if lhs.iconName != rhs.iconName {
|
||||
return false
|
||||
}
|
||||
if lhs.iconColor != rhs.iconColor {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
final class State: ComponentState {
|
||||
var cachedChevronImage: (UIImage, UIColor)?
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State()
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
let title = Child(MultilineTextComponent.self)
|
||||
let text = Child(MultilineTextComponent.self)
|
||||
let icon = Child(BundleIconComponent.self)
|
||||
|
||||
return { context in
|
||||
let component = context.component
|
||||
let state = context.state
|
||||
|
||||
let leftInset: CGFloat = 32.0
|
||||
let rightInset: CGFloat = 24.0
|
||||
let textSideInset: CGFloat = leftInset + 8.0
|
||||
let spacing: CGFloat = 5.0
|
||||
|
||||
let textTopInset: CGFloat = 9.0
|
||||
|
||||
let title = title.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: component.title,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: component.titleColor,
|
||||
paragraphAlignment: .natural
|
||||
)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 1
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude),
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
let textFont = Font.regular(15.0)
|
||||
let boldTextFont = Font.semibold(15.0)
|
||||
let textColor = component.textColor
|
||||
let accentColor = component.accentColor
|
||||
let markdownAttributes = MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: textFont, textColor: textColor),
|
||||
bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor),
|
||||
link: MarkdownAttributeSet(font: textFont, textColor: accentColor),
|
||||
linkAttribute: { contents in
|
||||
return (TelegramTextAttributes.URL, contents)
|
||||
}
|
||||
)
|
||||
|
||||
if state.cachedChevronImage == nil || state.cachedChevronImage?.1 != accentColor {
|
||||
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: accentColor)!, accentColor)
|
||||
}
|
||||
let textAttributedString = parseMarkdownIntoAttributedString(component.text, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString
|
||||
if let range = textAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
|
||||
textAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: textAttributedString.string))
|
||||
}
|
||||
|
||||
let text = text.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(textAttributedString),
|
||||
horizontalAlignment: .natural,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2,
|
||||
highlightAction: { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
||||
return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
tapAction: { _, _ in
|
||||
component.action()
|
||||
}
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width - leftInset - rightInset, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
let icon = icon.update(
|
||||
component: BundleIconComponent(
|
||||
name: component.iconName,
|
||||
tintColor: component.iconColor
|
||||
),
|
||||
availableSize: CGSize(width: context.availableSize.width, height: context.availableSize.height),
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
context.add(title
|
||||
.position(CGPoint(x: textSideInset + title.size.width / 2.0, y: textTopInset + title.size.height / 2.0))
|
||||
)
|
||||
|
||||
context.add(text
|
||||
.position(CGPoint(x: textSideInset + text.size.width / 2.0, y: textTopInset + title.size.height + spacing + text.size.height / 2.0))
|
||||
)
|
||||
|
||||
context.add(icon
|
||||
.position(CGPoint(x: 15.0, y: textTopInset + 18.0))
|
||||
)
|
||||
|
||||
return CGSize(width: context.availableSize.width, height: textTopInset + title.size.height + text.size.height + 20.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,9 @@ swift_library(
|
|||
"//submodules/Components/BlurredBackgroundComponent",
|
||||
"//submodules/Components/BundleIconComponent",
|
||||
"//submodules/ConfettiEffect",
|
||||
"//submodules/AnimatedStickerNode",
|
||||
"//submodules/TelegramAnimatedStickerNode",
|
||||
"//submodules/TelegramUI/Components/Stars/ItemShimmeringLoadingComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import TextFormat
|
|||
import PremiumStarComponent
|
||||
import BundleIconComponent
|
||||
import ConfettiEffect
|
||||
import ItemShimmeringLoadingComponent
|
||||
|
||||
private struct StarsProduct: Equatable {
|
||||
enum Option: Equatable {
|
||||
|
|
@ -236,6 +237,8 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||
textString = renew ? strings.Stars_Purchase_SubscriptionRenewInfo(component.peers.first?.value.compactDisplayTitle ?? "").string : strings.Stars_Purchase_SubscriptionInfo(component.peers.first?.value.compactDisplayTitle ?? "").string
|
||||
case .unlockMedia:
|
||||
textString = strings.Stars_Purchase_StarsNeededUnlockInfo
|
||||
case .starGift:
|
||||
textString = strings.Stars_Purchase_StarGiftInfo(component.peers.first?.value.compactDisplayTitle ?? "").string
|
||||
}
|
||||
|
||||
let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: accentColor), linkAttribute: { contents in
|
||||
|
|
@ -328,7 +331,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||
let backgroundComponent: AnyComponent<Empty>?
|
||||
if product.storeProduct.id == context.component.selectedProductId {
|
||||
backgroundComponent = AnyComponent(
|
||||
ItemLoadingComponent(color: environment.theme.list.itemAccentColor)
|
||||
ItemShimmeringLoadingComponent(color: environment.theme.list.itemAccentColor)
|
||||
)
|
||||
} else {
|
||||
backgroundComponent = nil
|
||||
|
|
@ -814,11 +817,9 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
|||
switch context.component.purpose {
|
||||
case .generic:
|
||||
titleText = strings.Stars_Purchase_GetStars
|
||||
case let .topUp(requiredStars, _):
|
||||
titleText = strings.Stars_Purchase_StarsNeeded(Int32(requiredStars))
|
||||
case .gift:
|
||||
titleText = strings.Stars_Purchase_GiftStars
|
||||
case let .transfer(_, requiredStars), let .reactions(_, requiredStars), let .subscription(_, requiredStars, _), let .unlockMedia(requiredStars):
|
||||
case let .topUp(requiredStars, _), let .transfer(_, requiredStars), let .reactions(_, requiredStars), let .subscription(_, requiredStars, _), let .unlockMedia(requiredStars), let .starGift(_, requiredStars):
|
||||
titleText = strings.Stars_Purchase_StarsNeeded(Int32(requiredStars))
|
||||
}
|
||||
|
||||
|
|
@ -1238,6 +1239,8 @@ private extension StarsPurchasePurpose {
|
|||
return [peerId]
|
||||
case let .subscription(peerId, _, _):
|
||||
return [peerId]
|
||||
case let .starGift(peerId, _):
|
||||
return [peerId]
|
||||
default:
|
||||
return []
|
||||
}
|
||||
|
|
@ -1255,6 +1258,8 @@ private extension StarsPurchasePurpose {
|
|||
return requiredStars
|
||||
case let .unlockMedia(requiredStars):
|
||||
return requiredStars
|
||||
case let .starGift(_, requiredStars):
|
||||
return requiredStars
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ final class StarsTransactionsScreenComponent: Component {
|
|||
|
||||
if let starView = self.starView.view {
|
||||
let starPosition = CGPoint(x: self.scrollView.frame.width / 2.0, y: topInset + starView.bounds.height / 2.0 - 30.0 - titleOffset * titleScale)
|
||||
|
||||
headerTransition.setPosition(view: starView, position: starPosition)
|
||||
headerTransition.setScale(view: starView, scale: titleScale)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -919,7 +919,7 @@ final class StoryItemContentComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
let shimmeringMediaAreas: [MediaArea] = component.item.mediaAreas.filter { mediaArea in
|
||||
var shimmeringMediaAreas: [MediaArea] = component.item.mediaAreas.filter { mediaArea in
|
||||
if case .link = mediaArea {
|
||||
return true
|
||||
} else if case .venue = mediaArea {
|
||||
|
|
@ -929,6 +929,10 @@ final class StoryItemContentComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
if component.peer.id.isTelegramNotifications {
|
||||
shimmeringMediaAreas = []
|
||||
}
|
||||
|
||||
if !shimmeringMediaAreas.isEmpty {
|
||||
let mediaAreasEffectView: StoryItemLoadingEffectView
|
||||
if let current = self.mediaAreasEffectView {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ swift_library(
|
|||
"//submodules/Display",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||
"//submodules/Components/MultilineTextWithEntitiesComponent",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/AccountContext"
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -3,18 +3,24 @@ import UIKit
|
|||
import Display
|
||||
import ComponentFlow
|
||||
import PlainButtonComponent
|
||||
import MultilineTextWithEntitiesComponent
|
||||
import TextFormat
|
||||
import AccountContext
|
||||
|
||||
public final class TabSelectorComponent: Component {
|
||||
public struct Colors: Equatable {
|
||||
public var foreground: UIColor
|
||||
public var selection: UIColor
|
||||
public var simple: Bool
|
||||
|
||||
public init(
|
||||
foreground: UIColor,
|
||||
selection: UIColor
|
||||
selection: UIColor,
|
||||
simple: Bool = false
|
||||
) {
|
||||
self.foreground = foreground
|
||||
self.selection = selection
|
||||
self.simple = simple
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +51,7 @@ public final class TabSelectorComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
public let context: AccountContext?
|
||||
public let colors: Colors
|
||||
public let customLayout: CustomLayout?
|
||||
public let items: [Item]
|
||||
|
|
@ -53,6 +60,7 @@ public final class TabSelectorComponent: Component {
|
|||
public let transitionFraction: CGFloat?
|
||||
|
||||
public init(
|
||||
context: AccountContext? = nil,
|
||||
colors: Colors,
|
||||
customLayout: CustomLayout? = nil,
|
||||
items: [Item],
|
||||
|
|
@ -60,6 +68,7 @@ public final class TabSelectorComponent: Component {
|
|||
setSelectedId: @escaping (AnyHashable) -> Void,
|
||||
transitionFraction: CGFloat? = nil
|
||||
) {
|
||||
self.context = context
|
||||
self.colors = colors
|
||||
self.customLayout = customLayout
|
||||
self.items = items
|
||||
|
|
@ -69,6 +78,9 @@ public final class TabSelectorComponent: Component {
|
|||
}
|
||||
|
||||
public static func ==(lhs: TabSelectorComponent, rhs: TabSelectorComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.colors != rhs.colors {
|
||||
return false
|
||||
}
|
||||
|
|
@ -211,6 +223,7 @@ public final class TabSelectorComponent: Component {
|
|||
transition: .immediate,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
content: AnyComponent(ItemComponent(
|
||||
context: component.context,
|
||||
text: item.title,
|
||||
font: itemFont,
|
||||
color: component.colors.foreground,
|
||||
|
|
@ -254,7 +267,7 @@ public final class TabSelectorComponent: Component {
|
|||
}
|
||||
itemTransition.setPosition(view: itemTitleView, position: itemTitleFrame.origin)
|
||||
itemTransition.setBounds(view: itemTitleView, bounds: CGRect(origin: CGPoint(), size: itemTitleFrame.size))
|
||||
itemTransition.setAlpha(view: itemTitleView, alpha: item.id == component.selectedId || isLineSelection ? 1.0 : 0.4)
|
||||
itemTransition.setAlpha(view: itemTitleView, alpha: item.id == component.selectedId || isLineSelection || component.colors.simple ? 1.0 : 0.4)
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
|
@ -302,7 +315,7 @@ public final class TabSelectorComponent: Component {
|
|||
self.contentSize = CGSize(width: contentWidth, height: baseHeight + verticalInset * 2.0)
|
||||
self.disablesInteractiveTransitionGestureRecognizer = contentWidth > availableSize.width
|
||||
|
||||
if let selectedBackgroundRect {
|
||||
if let selectedBackgroundRect, self.bounds.width > 0.0 {
|
||||
self.scrollRectToVisible(selectedBackgroundRect.insetBy(dx: -spacing, dy: 0.0), animated: false)
|
||||
}
|
||||
|
||||
|
|
@ -331,6 +344,7 @@ extension CGRect {
|
|||
}
|
||||
|
||||
private final class ItemComponent: CombinedComponent {
|
||||
let context: AccountContext?
|
||||
let text: String
|
||||
let font: UIFont
|
||||
let color: UIColor
|
||||
|
|
@ -338,12 +352,14 @@ private final class ItemComponent: CombinedComponent {
|
|||
let selectionFraction: CGFloat
|
||||
|
||||
init(
|
||||
context: AccountContext?,
|
||||
text: String,
|
||||
font: UIFont,
|
||||
color: UIColor,
|
||||
selectedColor: UIColor,
|
||||
selectionFraction: CGFloat
|
||||
) {
|
||||
self.context = context
|
||||
self.text = text
|
||||
self.font = font
|
||||
self.color = color
|
||||
|
|
@ -352,6 +368,9 @@ private final class ItemComponent: CombinedComponent {
|
|||
}
|
||||
|
||||
static func ==(lhs: ItemComponent, rhs: ItemComponent) -> Bool {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
|
|
@ -371,17 +390,25 @@ private final class ItemComponent: CombinedComponent {
|
|||
}
|
||||
|
||||
static var body: Body {
|
||||
let title = Child(Text.self)
|
||||
let selectedTitle = Child(Text.self)
|
||||
let title = Child(MultilineTextWithEntitiesComponent.self)
|
||||
let selectedTitle = Child(MultilineTextWithEntitiesComponent.self)
|
||||
|
||||
return { context in
|
||||
let component = context.component
|
||||
|
||||
|
||||
let attributedTitle = NSMutableAttributedString(string: component.text, font: component.font, textColor: component.color)
|
||||
var range = (attributedTitle.string as NSString).range(of: "⭐️")
|
||||
if range.location != NSNotFound {
|
||||
attributedTitle.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: range)
|
||||
}
|
||||
|
||||
let title = title.update(
|
||||
component: Text(
|
||||
text: component.text,
|
||||
font: component.font,
|
||||
color: component.color
|
||||
component: MultilineTextWithEntitiesComponent(
|
||||
context: component.context,
|
||||
animationCache: component.context?.animationCache,
|
||||
animationRenderer: component.context?.animationRenderer,
|
||||
placeholderColor: .white,
|
||||
text: .plain(attributedTitle)
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
transition: .immediate
|
||||
|
|
@ -391,11 +418,19 @@ private final class ItemComponent: CombinedComponent {
|
|||
.opacity(1.0 - component.selectionFraction)
|
||||
)
|
||||
|
||||
let selectedAttributedTitle = NSMutableAttributedString(string: component.text, font: component.font, textColor: component.selectedColor)
|
||||
range = (selectedAttributedTitle.string as NSString).range(of: "⭐️")
|
||||
if range.location != NSNotFound {
|
||||
selectedAttributedTitle.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: range)
|
||||
}
|
||||
|
||||
let selectedTitle = selectedTitle.update(
|
||||
component: Text(
|
||||
text: component.text,
|
||||
font: component.font,
|
||||
color: component.selectedColor
|
||||
component: MultilineTextWithEntitiesComponent(
|
||||
context: nil,
|
||||
animationCache: nil,
|
||||
animationRenderer: nil,
|
||||
placeholderColor: .white,
|
||||
text: .plain(selectedAttributedTitle)
|
||||
),
|
||||
availableSize: context.availableSize,
|
||||
transition: .immediate
|
||||
|
|
|
|||
12
submodules/TelegramUI/Images.xcassets/Chat/Message/GiftRibbon.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Message/GiftRibbon.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "giftline_chat.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
83
submodules/TelegramUI/Images.xcassets/Chat/Message/GiftRibbon.imageset/giftline_chat.pdf
vendored
Normal file
83
submodules/TelegramUI/Images.xcassets/Chat/Message/GiftRibbon.imageset/giftline_chat.pdf
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 2.784424 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
62.376457 30.839119 m
|
||||
33.623550 59.592026 l
|
||||
31.548130 61.667446 30.510420 62.705158 29.299419 63.447258 c
|
||||
28.225752 64.105202 27.055216 64.590057 25.830782 64.884018 c
|
||||
24.449732 65.215576 22.982187 65.215576 20.047100 65.215576 c
|
||||
7.725484 65.215576 l
|
||||
5.302220 65.215576 4.090588 65.215576 3.529531 64.736389 c
|
||||
3.042711 64.320602 2.784362 63.696896 2.834592 63.058659 c
|
||||
2.892483 62.323093 3.749237 61.466339 5.462745 59.752831 c
|
||||
62.537258 2.678318 l
|
||||
64.250763 0.964813 65.107521 0.108055 65.843079 0.050171 c
|
||||
66.481316 -0.000061 67.105026 0.258286 67.520813 0.745110 c
|
||||
68.000000 1.306164 68.000000 2.517796 68.000000 4.941059 c
|
||||
68.000000 17.262676 l
|
||||
68.000000 20.197762 68.000000 21.665306 67.668442 23.046356 c
|
||||
67.374481 24.270794 66.889626 25.441330 66.231682 26.514996 c
|
||||
65.489578 27.725994 64.451874 28.763702 62.376457 30.839119 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
962
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 68.000000 68.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001052 00000 n
|
||||
0000001074 00000 n
|
||||
0000001247 00000 n
|
||||
0000001321 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
1380
|
||||
%%EOF
|
||||
12
submodules/TelegramUI/Images.xcassets/Peer Info/HiddenIcon.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Peer Info/HiddenIcon.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "hidden_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Peer Info/HiddenIcon.imageset/hidden_30.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Peer Info/HiddenIcon.imageset/hidden_30.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Premium/GiftRibbon.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/GiftRibbon.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "giftline_cell.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
84
submodules/TelegramUI/Images.xcassets/Premium/GiftRibbon.imageset/giftline_cell.pdf
vendored
Normal file
84
submodules/TelegramUI/Images.xcassets/Premium/GiftRibbon.imageset/giftline_cell.pdf
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 0.000000 2.784363 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
52.376450 30.839190 m
|
||||
33.623550 49.592087 l
|
||||
31.548130 51.667507 30.510420 52.705219 29.299419 53.447319 c
|
||||
28.225752 54.105263 27.055216 54.590115 25.830782 54.884075 c
|
||||
24.449732 55.215637 22.982187 55.215637 20.047100 55.215637 c
|
||||
7.725484 55.215637 l
|
||||
5.302220 55.215637 4.090588 55.215637 3.529531 54.736450 c
|
||||
3.042711 54.320667 2.784362 53.696957 2.834592 53.058720 c
|
||||
2.892483 52.323154 3.749236 51.466400 5.462744 49.752892 c
|
||||
52.537258 2.678379 l
|
||||
54.250763 0.964874 55.107517 0.108120 55.843082 0.050228 c
|
||||
56.481319 0.000000 57.105030 0.258350 57.520813 0.745167 c
|
||||
58.000000 1.306225 58.000000 2.517857 58.000000 4.941120 c
|
||||
58.000000 17.262737 l
|
||||
58.000000 20.197823 58.000000 21.665367 57.668438 23.046417 c
|
||||
57.374477 24.270853 56.889626 25.441389 56.231682 26.515057 c
|
||||
55.489586 27.726049 54.451885 28.763756 52.376484 30.839149 c
|
||||
52.376450 30.839190 l
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
983
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 58.000000 58.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001073 00000 n
|
||||
0000001095 00000 n
|
||||
0000001268 00000 n
|
||||
0000001342 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
1401
|
||||
%%EOF
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"provides-namespace" : true
|
||||
}
|
||||
}
|
||||
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Gift.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Gift.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "gift_30 (4).pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Gift.imageset/gift_30 (4).pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Gift.imageset/gift_30 (4).pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Media.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Media.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "unlock_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Media.imageset/unlock_30.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Media.imageset/unlock_30.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Miniapp.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Miniapp.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "bot_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Miniapp.imageset/bot_30.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Miniapp.imageset/bot_30.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Reaction.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Reaction.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "cash_30.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
62
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Reaction.imageset/cash_30.pdf
vendored
Normal file
62
submodules/TelegramUI/Images.xcassets/Premium/StarsPerk/Reaction.imageset/cash_30.pdf
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Filter /FlateDecode
|
||||
/Length 3 0 R
|
||||
>>
|
||||
stream
|
||||
xe•KŽT1EçYE<59>‘‰óõ<14>KxjRwK¨%ÖÏÉç%ÔÈïĹvl'õáóÓŸ_×Ó·/Ÿ¾›ûëz3¿<33>·®ÿî6Þ/kEBÔì·q½˜åö¿ñv½"6*Îæœ\©<>—&[Åå”É&§Qä!c;~sn›]flIØ›NϱÚ6tð»Ì¦=`r~ni‚#fŒx-t™¾¡e¸Ø0ðêK]ë&S§Ëü4ó.Ãþb¢-%Ö¸²óÙ¦”¼¦
¼®]ô®Ñ:Ñ<>&6–J¾ýqZˆê
]_6œÑ<C593><0C>&¶ÑéA:TÈnZèÍU<çoÖ«À—D/”)[õ}³°i±R%Ôò€9ÉA9t±©:ïÇq’N¿É8<C389>³¢¾¦“ªUýGp£ù2&¬\Š<›jcФß`õ¥’;*IK$…Øûìã<C3AC>Ī0p\sÂ{*ÏôÖ‡Ø\mЬ1´#Q¥æ§¶èðZˆ³y›|<7C>J=}6ˆûš7…éžJú5Tªhw/ÇCpÂb#íb†ˆ¬¡ºàÙæ(™ÍÓ,„ÞêÉ„©éÑ’Œ^¾aËZmˆ>ĺY¥]ýÈ…rDñu
|
||||
$>äá`¹Öš!*ŽHÕjM@%ŸIZ/R*‘é^l5b)dÅ[,Û’Äa1fï¸ö #0ëÔxÎMb_Ô¤ì[,ÚØæ«â`.–Šh+͘ր|o
|
||||
h–p!êºæAÁšßV;ÐÚ·NHv¼Ò9’ -æÄ©`òx™e—f—xþŠp×âÌc:Ð;àœ#ô$}¯!mà”*rë[
|
||||
¡{bݼX«Õ=ì¶byîFÜWïAµP¶ÖŒ+vÌp^Æv<C386>o,å¡oÌ´xž¯ÈpƒHËYZÚ“¶g^=Ù”Cs<43><1D><©p }-zPؼQ×ìTY=™Ë1óÚiS±™|Ûë’E:íaê,(¹'c7Ó‘yÂ9ä¢dq·f+n†öн)™S7áâ3(‰vbñüi)ÊsNCÆDñx:§™R²û¤óI}æ‘ÿñμš¯æ/²ô¤r
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
797
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000000915 00000 n
|
||||
0000000937 00000 n
|
||||
0000001110 00000 n
|
||||
0000001184 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
1243
|
||||
%%EOF
|
||||
|
|
@ -2370,7 +2370,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
if let primary = primary {
|
||||
for context in contexts {
|
||||
if let context = context, context.account.id == primary {
|
||||
self.openChatWhenReady(accountId: nil, peerId: peerId, threadId: nil, storyId: nil)
|
||||
self.openChatWhenReady(accountId: nil, peerId: peerId, threadId: nil, storyId: nil, openAppIfAny: true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -2378,7 +2378,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
|
||||
for context in contexts {
|
||||
if let context = context {
|
||||
self.openChatWhenReady(accountId: context.account.id, peerId: peerId, threadId: nil, storyId: nil)
|
||||
self.openChatWhenReady(accountId: context.account.id, peerId: peerId, threadId: nil, storyId: nil, openAppIfAny: true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -2464,7 +2464,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
}))
|
||||
}
|
||||
|
||||
private func openChatWhenReady(accountId: AccountRecordId?, peerId: PeerId, threadId: Int64?, messageId: MessageId? = nil, activateInput: Bool = false, storyId: StoryId?) {
|
||||
private func openChatWhenReady(accountId: AccountRecordId?, peerId: PeerId, threadId: Int64?, messageId: MessageId? = nil, activateInput: Bool = false, storyId: StoryId?, openAppIfAny: Bool = false) {
|
||||
let signal = self.sharedContextPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue
|
||||
|
|
@ -2483,7 +2483,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
|||
}
|
||||
self.openChatWhenReadyDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { context in
|
||||
context.openChatWithPeerId(peerId: peerId, threadId: threadId, messageId: messageId, activateInput: activateInput, storyId: storyId)
|
||||
context.openChatWithPeerId(peerId: peerId, threadId: threadId, messageId: messageId, activateInput: activateInput, storyId: storyId, openAppIfAny: openAppIfAny)
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -894,7 +894,7 @@ final class AuthorizedApplicationContext {
|
|||
}))
|
||||
}
|
||||
|
||||
func openChatWithPeerId(peerId: PeerId, threadId: Int64?, messageId: MessageId? = nil, activateInput: Bool = false, storyId: StoryId?) {
|
||||
func openChatWithPeerId(peerId: PeerId, threadId: Int64?, messageId: MessageId? = nil, activateInput: Bool = false, storyId: StoryId?, openAppIfAny: Bool = false) {
|
||||
if let storyId {
|
||||
var controllers = self.rootController.viewControllers
|
||||
controllers = controllers.filter { c in
|
||||
|
|
@ -945,7 +945,11 @@ final class AuthorizedApplicationContext {
|
|||
chatLocation = .peer(peer)
|
||||
}
|
||||
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
|
||||
if openAppIfAny, let parentController = self.rootController.viewControllers.last as? ViewController {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true)
|
||||
} else {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
|||
|> afterDisposed {
|
||||
updateProgress()
|
||||
})
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak parentController] result in
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak parentController] result in
|
||||
guard let parentController else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1113,12 +1113,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
} else {
|
||||
strongSelf.present(BotReceiptController(context: strongSelf.context, messageId: message.id), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
/*for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute {
|
||||
//strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId))
|
||||
break
|
||||
}
|
||||
}*/
|
||||
return true
|
||||
case .setChatTheme:
|
||||
strongSelf.presentThemeSelection()
|
||||
|
|
@ -1185,6 +1179,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
let controller = PremiumIntroScreen(context: strongSelf.context, source: .gift(from: fromPeerId, to: toPeerId, duration: duration, giftCode: nil))
|
||||
strongSelf.push(controller)
|
||||
return true
|
||||
case .starGift:
|
||||
let controller = strongSelf.context.sharedContext.makeGiftViewScreen(context: strongSelf.context, message: EngineMessage(message))
|
||||
strongSelf.push(controller)
|
||||
return true
|
||||
case .giftStars:
|
||||
let controller = strongSelf.context.sharedContext.makeStarsGiftScreen(context: strongSelf.context, message: EngineMessage(message))
|
||||
strongSelf.push(controller)
|
||||
|
|
|
|||
|
|
@ -351,7 +351,8 @@ private func extractAssociatedData(
|
|||
chatThemes: [TelegramTheme],
|
||||
deviceContactsNumbers: Set<String>,
|
||||
isInline: Bool,
|
||||
showSensitiveContent: Bool
|
||||
showSensitiveContent: Bool,
|
||||
starGifts: [Int64 : TelegramMediaFile]
|
||||
) -> ChatMessageItemAssociatedData {
|
||||
var automaticDownloadPeerId: EnginePeer.Id?
|
||||
var automaticMediaDownloadPeerType: MediaAutoDownloadPeerType = .channel
|
||||
|
|
@ -406,7 +407,7 @@ private func extractAssociatedData(
|
|||
automaticDownloadPeerId = message.peerId
|
||||
}
|
||||
|
||||
return ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadPeerId: automaticDownloadPeerId, automaticDownloadNetworkType: automaticDownloadNetworkType, preferredStoryHighQuality: preferredStoryHighQuality, isRecentActions: false, subject: subject, contactsPeerIds: contactsPeerIds, channelDiscussionGroup: channelDiscussionGroup, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, accountPeer: accountPeer, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, topicAuthorId: topicAuthorId, hasBots: hasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: isInline, showSensitiveContent: showSensitiveContent)
|
||||
return ChatMessageItemAssociatedData(automaticDownloadPeerType: automaticMediaDownloadPeerType, automaticDownloadPeerId: automaticDownloadPeerId, automaticDownloadNetworkType: automaticDownloadNetworkType, preferredStoryHighQuality: preferredStoryHighQuality, isRecentActions: false, subject: subject, contactsPeerIds: contactsPeerIds, channelDiscussionGroup: channelDiscussionGroup, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, accountPeer: accountPeer, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, topicAuthorId: topicAuthorId, hasBots: hasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: isInline, showSensitiveContent: showSensitiveContent, starGifts: starGifts)
|
||||
}
|
||||
|
||||
private extension ChatHistoryLocationInput {
|
||||
|
|
@ -1610,6 +1611,17 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
let starGifts: Signal<[Int64 : TelegramMediaFile], NoError> = context.engine.payments.cachedStarGifts()
|
||||
|> map { gifts in
|
||||
var files: [Int64 : TelegramMediaFile] = [:]
|
||||
if let gifts {
|
||||
for gift in gifts {
|
||||
files[gift.id] = gift.file
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
let messageViewQueue = Queue.mainQueue()
|
||||
let historyViewTransitionDisposable = combineLatest(queue: messageViewQueue,
|
||||
historyViewUpdate,
|
||||
|
|
@ -1636,8 +1648,9 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||
audioTranscriptionTrial,
|
||||
chatThemes,
|
||||
deviceContactsNumbers,
|
||||
contentSettings
|
||||
).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings in
|
||||
contentSettings,
|
||||
starGifts
|
||||
).startStrict(next: { [weak self] update, chatPresentationData, selectedMessages, updatingMedia, networkType, preferredStoryHighQuality, animatedEmojiStickers, additionalAnimatedEmojiStickers, customChannelDiscussionReadState, customThreadOutgoingReadState, availableReactions, availableMessageEffects, savedMessageTags, defaultReaction, accountPeer, suggestAudioTranscription, promises, topicAuthorId, translationState, maxReadStoryId, recommendedChannels, audioTranscriptionTrial, chatThemes, deviceContactsNumbers, contentSettings, starGifts in
|
||||
let (historyAppearsCleared, pendingUnpinnedAllMessages, pendingRemovedMessages, currentlyPlayingMessageIdAndType, scrollToMessageId, chatHasBots, allAdMessages) = promises
|
||||
|
||||
func applyHole() {
|
||||
|
|
@ -1856,7 +1869,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
|
|||
translateToLanguage = languageCode
|
||||
}
|
||||
|
||||
let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, preferredStoryHighQuality: preferredStoryHighQuality, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageIdAndType?.0, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, accountPeer: accountPeer, topicAuthorId: topicAuthorId, hasBots: chatHasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: !rotated, showSensitiveContent: contentSettings.ignoreContentRestrictionReasons.contains("sensitive"))
|
||||
let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, preferredStoryHighQuality: preferredStoryHighQuality, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageIdAndType?.0, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, availableMessageEffects: availableMessageEffects, savedMessageTags: savedMessageTags, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, accountPeer: accountPeer, topicAuthorId: topicAuthorId, hasBots: chatHasBots, translateToLanguage: translateToLanguage, maxReadStoryId: maxReadStoryId, recommendedChannels: recommendedChannels, audioTranscriptionTrial: audioTranscriptionTrial, chatThemes: chatThemes, deviceContactsNumbers: deviceContactsNumbers, isInline: !rotated, showSensitiveContent: contentSettings.ignoreContentRestrictionReasons.contains("sensitive"), starGifts: starGifts)
|
||||
|
||||
var includeEmbeddedSavedChatInfo = false
|
||||
if case let .replyThread(message) = chatLocation, message.peerId == context.account.peerId, !rotated {
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ import StarsTransferScreen
|
|||
import StarsTransactionScreen
|
||||
import StarsWithdrawalScreen
|
||||
import MiniAppListScreen
|
||||
import GiftOptionsScreen
|
||||
import GiftViewScreen
|
||||
import StarsIntroScreen
|
||||
|
||||
private final class AccountUserInterfaceInUseContext {
|
||||
let subscribers = Bag<(Bool) -> Void>()
|
||||
|
|
@ -2203,26 +2206,20 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let limit: Int32 = 10
|
||||
var reachedLimitImpl: ((Int32) -> Void)?
|
||||
var presentBirthdayPickerImpl: (() -> Void)?
|
||||
let mode: ContactMultiselectionControllerMode
|
||||
var starsMode: ContactSelectionControllerMode = .generic
|
||||
var currentBirthdays: [EnginePeer.Id: TelegramBirthday]?
|
||||
|
||||
if case let .chatList(birthdays) = source, let birthdays, !birthdays.isEmpty {
|
||||
mode = .premiumGifting(birthdays: birthdays, selectToday: true, hasActions: true)
|
||||
starsMode = .starsGifting(birthdays: birthdays, hasActions: true)
|
||||
currentBirthdays = birthdays
|
||||
} else if case let .settings(birthdays) = source, let birthdays, !birthdays.isEmpty {
|
||||
mode = .premiumGifting(birthdays: birthdays, selectToday: false, hasActions: true)
|
||||
currentBirthdays = birthdays
|
||||
} else if case let .stars(birthdays) = source {
|
||||
mode = .premiumGifting(birthdays: birthdays, selectToday: false, hasActions: false)
|
||||
starsMode = .starsGifting(birthdays: birthdays, hasActions: false)
|
||||
starsMode = .starsGifting(birthdays: birthdays, hasActions: true)
|
||||
currentBirthdays = birthdays
|
||||
} else {
|
||||
mode = .premiumGifting(birthdays: nil, selectToday: false, hasActions: true)
|
||||
starsMode = .starsGifting(birthdays: nil, hasActions: true)
|
||||
}
|
||||
|
||||
|
||||
let contactOptions: Signal<[ContactListAdditionalOption], NoError>
|
||||
if currentBirthdays != nil || "".isEmpty {
|
||||
contactOptions = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Birthday(id: context.account.peerId))
|
||||
|
|
@ -2248,104 +2245,122 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
var openProfileImpl: ((EnginePeer) -> Void)?
|
||||
var sendMessageImpl: ((EnginePeer) -> Void)?
|
||||
|
||||
//TODO:localize
|
||||
let controller: ViewController
|
||||
if case .stars = source {
|
||||
let options = Promise<[StarsGiftOption]>()
|
||||
options.set(context.engine.payments.starsGiftOptions(peerId: nil))
|
||||
// if case .stars = source {
|
||||
// let options = Promise<[StarsGiftOption]>()
|
||||
// options.set(context.engine.payments.starsGiftOptions(peerId: nil))
|
||||
let options = Promise<[PremiumGiftCodeOption]>()
|
||||
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
||||
let contactsController = context.sharedContext.makeContactSelectionController(ContactSelectionControllerParams(
|
||||
context: context,
|
||||
mode: starsMode,
|
||||
autoDismiss: false,
|
||||
title: { strings in return strings.Stars_Purchase_GiftStars },
|
||||
options: contactOptions
|
||||
))
|
||||
let _ = (contactsController.result
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
if let (peers, _, _, _, _, _) = result, let contactPeer = peers.first, case let .peer(peer, _, _) = contactPeer {
|
||||
completion?([peer.id])
|
||||
title: { strings in return "Gift Premium or Stars" },
|
||||
options: contactOptions,
|
||||
openProfile: { peer in
|
||||
openProfileImpl?(peer)
|
||||
},
|
||||
sendMessage: { peer in
|
||||
sendMessageImpl?(peer)
|
||||
}
|
||||
})
|
||||
controller = contactsController
|
||||
} else {
|
||||
let options = Promise<[PremiumGiftCodeOption]>()
|
||||
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
||||
let contactsController = context.sharedContext.makeContactMultiselectionController(
|
||||
ContactMultiselectionControllerParams(
|
||||
context: context,
|
||||
mode: mode,
|
||||
options: contactOptions,
|
||||
isPeerEnabled: { peer in
|
||||
if case let .user(user) = peer, user.botInfo == nil && !peer.isService && !user.flags.contains(.isSupport) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
limit: limit,
|
||||
reachedLimit: { limit in
|
||||
reachedLimitImpl?(limit)
|
||||
},
|
||||
openProfile: { peer in
|
||||
openProfileImpl?(peer)
|
||||
},
|
||||
sendMessage: { peer in
|
||||
sendMessageImpl?(peer)
|
||||
}
|
||||
)
|
||||
)
|
||||
))
|
||||
let _ = combineLatest(queue: Queue.mainQueue(), contactsController.result, options.get())
|
||||
.startStandalone(next: { [weak contactsController] result, options in
|
||||
guard let controller = contactsController else {
|
||||
return
|
||||
}
|
||||
var peerIds: [PeerId] = []
|
||||
if case let .result(peerIdsValue, _) = result {
|
||||
peerIds = peerIdsValue.compactMap({ peerId in
|
||||
if case let .peer(peerId) = peerId {
|
||||
return peerId
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
})
|
||||
}
|
||||
guard !peerIds.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
||||
let mappedOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
|
||||
var pushImpl: ((ViewController) -> Void)?
|
||||
var filterImpl: (() -> Void)?
|
||||
let giftController = PremiumGiftScreen(context: context, peerIds: peerIds, options: mappedOptions, source: source, pushController: { c in
|
||||
pushImpl?(c)
|
||||
}, completion: {
|
||||
filterImpl?()
|
||||
if let (peers, _, _, _, _, _) = result, let contactPeer = peers.first, case let .peer(peer, _, _) = contactPeer, let starsContext = context.starsContext {
|
||||
let premiumOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
|
||||
let giftController = GiftOptionsScreen(context: context, starsContext: starsContext, peerId: peer.id, premiumOptions: premiumOptions)
|
||||
giftController.navigationPresentation = .modal
|
||||
contactsController?.push(giftController)
|
||||
|
||||
// completion?([peer.id])
|
||||
|
||||
if case .chatList = source, let _ = currentBirthdays {
|
||||
let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone()
|
||||
}
|
||||
})
|
||||
pushImpl = { [weak giftController] c in
|
||||
giftController?.push(c)
|
||||
}
|
||||
filterImpl = { [weak giftController] in
|
||||
if let navigationController = giftController?.navigationController as? NavigationController {
|
||||
var controllers = navigationController.viewControllers
|
||||
controllers = controllers.filter { !($0 is ContactMultiselectionController) && !($0 is PremiumGiftScreen) }
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
}
|
||||
}
|
||||
controller.push(giftController)
|
||||
})
|
||||
controller = contactsController
|
||||
}
|
||||
// } else {
|
||||
// let options = Promise<[PremiumGiftCodeOption]>()
|
||||
// options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
||||
// let contactsController = context.sharedContext.makeContactMultiselectionController(
|
||||
// ContactMultiselectionControllerParams(
|
||||
// context: context,
|
||||
// mode: mode,
|
||||
// options: contactOptions,
|
||||
// isPeerEnabled: { peer in
|
||||
// if case let .user(user) = peer, user.botInfo == nil && !peer.isService && !user.flags.contains(.isSupport) {
|
||||
// return true
|
||||
// } else {
|
||||
// return false
|
||||
// }
|
||||
// },
|
||||
// limit: limit,
|
||||
// reachedLimit: { limit in
|
||||
// reachedLimitImpl?(limit)
|
||||
// },
|
||||
// openProfile: { peer in
|
||||
// openProfileImpl?(peer)
|
||||
// },
|
||||
// sendMessage: { peer in
|
||||
// sendMessageImpl?(peer)
|
||||
// }
|
||||
// )
|
||||
// )
|
||||
// let _ = combineLatest(queue: Queue.mainQueue(), contactsController.result, options.get())
|
||||
// .startStandalone(next: { [weak contactsController] result, options in
|
||||
// guard let controller = contactsController else {
|
||||
// return
|
||||
// }
|
||||
// var peerIds: [PeerId] = []
|
||||
// if case let .result(peerIdsValue, _) = result {
|
||||
// peerIds = peerIdsValue.compactMap({ peerId in
|
||||
// if case let .peer(peerId) = peerId {
|
||||
// return peerId
|
||||
// } else {
|
||||
// return nil
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// guard !peerIds.isEmpty else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// let mappedOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
|
||||
// var pushImpl: ((ViewController) -> Void)?
|
||||
// var filterImpl: (() -> Void)?
|
||||
// let giftController = PremiumGiftScreen(context: context, peerIds: peerIds, options: mappedOptions, source: source, pushController: { c in
|
||||
// pushImpl?(c)
|
||||
// }, completion: {
|
||||
// filterImpl?()
|
||||
//
|
||||
// if case .chatList = source, let _ = currentBirthdays {
|
||||
// let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone()
|
||||
// }
|
||||
// })
|
||||
// pushImpl = { [weak giftController] c in
|
||||
// giftController?.push(c)
|
||||
// }
|
||||
// filterImpl = { [weak giftController] in
|
||||
// if let navigationController = giftController?.navigationController as? NavigationController {
|
||||
// var controllers = navigationController.viewControllers
|
||||
// controllers = controllers.filter { !($0 is ContactMultiselectionController) && !($0 is PremiumGiftScreen) }
|
||||
// navigationController.setViewControllers(controllers, animated: true)
|
||||
// }
|
||||
// }
|
||||
// controller.push(giftController)
|
||||
// })
|
||||
// controller = contactsController
|
||||
// }
|
||||
|
||||
reachedLimitImpl = { [weak controller] limit in
|
||||
guard let controller else {
|
||||
return
|
||||
}
|
||||
HapticFeedback().error()
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Premium_Gift_ContactSelection_MaximumReached("\(limit)").string, timeout: nil, customUndoText: nil), elevatedLayout: true, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
// reachedLimitImpl = { [weak controller] limit in
|
||||
// guard let controller else {
|
||||
// return
|
||||
// }
|
||||
// HapticFeedback().error()
|
||||
// controller.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Premium_Gift_ContactSelection_MaximumReached("\(limit)").string, timeout: nil, customUndoText: nil), elevatedLayout: true, position: .bottom, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
// }
|
||||
|
||||
sendMessageImpl = { [weak self, weak controller] peer in
|
||||
guard let self, let controller, let navigationController = controller.navigationController as? NavigationController else {
|
||||
|
|
@ -2796,6 +2811,14 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
return StarsTransactionScreen(context: context, subject: .boost(peerId, boost))
|
||||
}
|
||||
|
||||
public func makeStarsIntroScreen(context: AccountContext) -> ViewController {
|
||||
return StarsIntroScreen(context: context)
|
||||
}
|
||||
|
||||
public func makeGiftViewScreen(context: AccountContext, message: EngineMessage) -> ViewController {
|
||||
return GiftViewScreen(context: context, subject: .message(message))
|
||||
}
|
||||
|
||||
public func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError> {
|
||||
return MiniAppListScreen.initialData(context: context)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,12 +186,38 @@ private func manageableSpotlightContacts(appBasePath: String, accounts: Signal<[
|
|||
return accounts
|
||||
|> mapToSignal { accounts -> Signal<[[EnginePeer.Id: SpotlightIndexStorageItem]], NoError> in
|
||||
return combineLatest(queue: queue, accounts.map { account -> Signal<[EnginePeer.Id: SpotlightIndexStorageItem], NoError> in
|
||||
return TelegramEngine(account: account).data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)
|
||||
let engine = TelegramEngine(account: account)
|
||||
let recentApps = engine.peers.recentApps()
|
||||
|> mapToSignal { peerIds -> Signal<[EnginePeer], NoError> in
|
||||
return engine.data.get(
|
||||
EngineDataMap(
|
||||
peerIds.map { peerId -> TelegramEngine.EngineData.Item.Peer.Peer in
|
||||
return TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||
}
|
||||
)
|
||||
)
|
||||
|> map { result -> [EnginePeer] in
|
||||
var peers: [EnginePeer] = []
|
||||
for (_, maybePeer) in result {
|
||||
if let peer = maybePeer {
|
||||
peers.append(peer)
|
||||
}
|
||||
}
|
||||
return peers
|
||||
}
|
||||
}
|
||||
return combineLatest(
|
||||
engine.data.subscribe(
|
||||
TelegramEngine.EngineData.Item.Contacts.List(includePresences: false)
|
||||
),
|
||||
recentApps
|
||||
)
|
||||
|> map { view -> [EnginePeer.Id: SpotlightIndexStorageItem] in
|
||||
|> map { view, recentApps -> [EnginePeer.Id: SpotlightIndexStorageItem] in
|
||||
var result: [EnginePeer.Id: SpotlightIndexStorageItem] = [:]
|
||||
for peer in view.peers {
|
||||
var peers: [EnginePeer] = []
|
||||
peers.append(contentsOf: view.peers)
|
||||
peers.append(contentsOf: recentApps)
|
||||
for peer in peers {
|
||||
if case let .user(user) = peer {
|
||||
let avatarSourcePath = smallestImageRepresentation(user.photo).flatMap { representation -> String? in
|
||||
let resourcePath = account.postbox.mediaBox.resourcePath(representation.resource)
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ public final class ChatTextInputTextCustomEmojiAttribute: NSObject, Codable {
|
|||
case nameColors([UInt32])
|
||||
case stars(tinted: Bool)
|
||||
case ton
|
||||
case animation(name: String)
|
||||
}
|
||||
|
||||
public let interactivelySelectedFromPackId: ItemCollectionId?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue