mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Merge commit '62ff5b04ece5a28032b7ae830970d7d77af7ca3d' into lottie-temp
This commit is contained in:
commit
f14b1161ea
@ -12190,3 +12190,19 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"EmojiPacks.UnarchiveEmojiPacksConfirmation_1" = "Unarchive %@ Pack";
|
"EmojiPacks.UnarchiveEmojiPacksConfirmation_1" = "Unarchive %@ Pack";
|
||||||
"EmojiPacks.UnarchiveEmojiPacksConfirmation_any" = "Unarchive %@ Packs";
|
"EmojiPacks.UnarchiveEmojiPacksConfirmation_any" = "Unarchive %@ Packs";
|
||||||
|
|
||||||
|
"HashtagSearch.ThisChat" = "This Chat";
|
||||||
|
"HashtagSearch.MyMessages" = "My Messages";
|
||||||
|
"HashtagSearch.PublicPosts" = "Public Posts";
|
||||||
|
|
||||||
|
"Chat.Context.Phone.AddToContacts" = "Add to Contacts";
|
||||||
|
"Chat.Context.Phone.CreateNewContact" = "Create New Contact";
|
||||||
|
"Chat.Context.Phone.AddToExistingContact" = "Add to Existing Contact";
|
||||||
|
"Chat.Context.Phone.SendMessage" = "Send Message";
|
||||||
|
"Chat.Context.Phone.TelegramVoiceCall" = "Telegram Voice Call";
|
||||||
|
"Chat.Context.Phone.TelegramVideoCall" = "Telegram Video Call";
|
||||||
|
"Chat.Context.Phone.InviteToTelegram" = "Invite to Telegram";
|
||||||
|
"Chat.Context.Phone.CallViaCarrier" = "Call via Carrier";
|
||||||
|
"Chat.Context.Phone.CopyNumber" = "Copy Number";
|
||||||
|
"Chat.Context.Phone.NotOnTelegram" = "This number is not on Telegram.";
|
||||||
|
"Chat.Context.Phone.ViewProfile" = "View Profile";
|
||||||
|
@ -933,7 +933,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makeOverlayAudioPlayerController(context: AccountContext, chatLocation: ChatLocation, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, playlistLocation: SharedMediaPlaylistLocation?, parentNavigationController: NavigationController?) -> ViewController & OverlayAudioPlayerController
|
func makeOverlayAudioPlayerController(context: AccountContext, chatLocation: ChatLocation, type: MediaManagerPlayerType, initialMessageId: MessageId, initialOrder: MusicPlaybackSettingsOrder, playlistLocation: SharedMediaPlaylistLocation?, parentNavigationController: NavigationController?) -> ViewController & OverlayAudioPlayerController
|
||||||
func makePeerInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, fromChat: Bool, requestsContext: PeerInvitationImportersContext?) -> ViewController?
|
func makePeerInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, fromChat: Bool, requestsContext: PeerInvitationImportersContext?) -> ViewController?
|
||||||
func makeChannelAdminController(context: AccountContext, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant) -> ViewController?
|
func makeChannelAdminController(context: AccountContext, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant) -> ViewController?
|
||||||
func makeDeviceContactInfoController(context: AccountContext, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController
|
func makeDeviceContactInfoController(context: ShareControllerAccountContext, environment: ShareControllerEnvironment, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController
|
||||||
func makePeersNearbyController(context: AccountContext) -> ViewController
|
func makePeersNearbyController(context: AccountContext) -> ViewController
|
||||||
func makeComposeController(context: AccountContext) -> ViewController
|
func makeComposeController(context: AccountContext) -> ViewController
|
||||||
func makeChatListController(context: AccountContext, location: ChatListControllerLocation, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool, previewing: Bool, enableDebugActions: Bool) -> ChatListController
|
func makeChatListController(context: AccountContext, location: ChatListControllerLocation, controlsHistoryPreload: Bool, hideNetworkActivityStatus: Bool, previewing: Bool, enableDebugActions: Bool) -> ChatListController
|
||||||
@ -1248,3 +1248,28 @@ public struct StickersSearchConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol ShareControllerAccountContext: AnyObject {
|
||||||
|
var accountId: AccountRecordId { get }
|
||||||
|
var accountPeerId: EnginePeer.Id { get }
|
||||||
|
var stateManager: AccountStateManager { get }
|
||||||
|
var engineData: TelegramEngine.EngineData { get }
|
||||||
|
var animationCache: AnimationCache { get }
|
||||||
|
var animationRenderer: MultiAnimationRenderer { get }
|
||||||
|
var contentSettings: ContentSettings { get }
|
||||||
|
var appConfiguration: AppConfiguration { get }
|
||||||
|
|
||||||
|
func resolveInlineStickers(fileIds: [Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol ShareControllerEnvironment: AnyObject {
|
||||||
|
var presentationData: PresentationData { get }
|
||||||
|
var updatedPresentationData: Signal<PresentationData, NoError> { get }
|
||||||
|
var isMainApp: Bool { get }
|
||||||
|
var energyUsageSettings: EnergyUsageSettings { get }
|
||||||
|
|
||||||
|
var mediaManager: MediaManager? { get }
|
||||||
|
|
||||||
|
func setAccountUserInterfaceInUse(id: AccountRecordId) -> Disposable
|
||||||
|
func donateSendMessageIntent(account: ShareControllerAccountContext, peerIds: [EnginePeer.Id])
|
||||||
|
}
|
||||||
|
@ -971,6 +971,7 @@ public protocol ChatController: ViewController {
|
|||||||
var chatLocation: ChatLocation { get }
|
var chatLocation: ChatLocation { get }
|
||||||
var canReadHistory: ValuePromise<Bool> { get }
|
var canReadHistory: ValuePromise<Bool> { get }
|
||||||
var parentController: ViewController? { get set }
|
var parentController: ViewController? { get set }
|
||||||
|
var customNavigationController: NavigationController? { get set }
|
||||||
|
|
||||||
var purposefulAction: (() -> Void)? { get set }
|
var purposefulAction: (() -> Void)? { get set }
|
||||||
|
|
||||||
|
@ -28,13 +28,22 @@ public final class BotCheckoutController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static func fetch(context: AccountContext, source: BotPaymentInvoiceSource) -> Signal<InputData, FetchError> {
|
public static func fetch(context: AccountContext, source: BotPaymentInvoiceSource) -> Signal<InputData, FetchError> {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let theme = context.sharedContext.currentPresentationData.with { $0 }.theme
|
||||||
let themeParams: [String: Any] = [
|
let themeParams: [String: Any] = [
|
||||||
"bg_color": Int32(bitPattern: presentationData.theme.list.plainBackgroundColor.argb),
|
"bg_color": Int32(bitPattern: theme.list.plainBackgroundColor.rgb),
|
||||||
"text_color": Int32(bitPattern: presentationData.theme.list.itemPrimaryTextColor.argb),
|
"secondary_bg_color": Int32(bitPattern: theme.list.blocksBackgroundColor.rgb),
|
||||||
"link_color": Int32(bitPattern: presentationData.theme.list.itemAccentColor.argb),
|
"text_color": Int32(bitPattern: theme.list.itemPrimaryTextColor.rgb),
|
||||||
"button_color": Int32(bitPattern: presentationData.theme.list.itemCheckColors.fillColor.argb),
|
"hint_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||||
"button_text_color": Int32(bitPattern: presentationData.theme.list.itemCheckColors.foregroundColor.argb)
|
"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)
|
return context.engine.payments.fetchBotPaymentForm(source: source, themeParams: themeParams)
|
||||||
|
@ -23,6 +23,7 @@ import StoryContainerScreen
|
|||||||
import ChatListHeaderComponent
|
import ChatListHeaderComponent
|
||||||
import TelegramIntents
|
import TelegramIntents
|
||||||
import UndoUI
|
import UndoUI
|
||||||
|
import ShareController
|
||||||
|
|
||||||
private final class HeaderContextReferenceContentSource: ContextReferenceContentSource {
|
private final class HeaderContextReferenceContentSource: ContextReferenceContentSource {
|
||||||
private let controller: ViewController
|
private let controller: ViewController
|
||||||
@ -309,7 +310,7 @@ public class ContactsController: ViewController {
|
|||||||
guard let strongSelf = self, let value = value else {
|
guard let strongSelf = self, let value = value else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .vcard(nil, id, value), completed: nil, cancelled: nil), completion: { [weak self] in
|
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .vcard(nil, id, value), completed: nil, cancelled: nil), completion: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
|
strongSelf.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
|
||||||
}
|
}
|
||||||
@ -741,7 +742,7 @@ public class ContactsController: ViewController {
|
|||||||
case .allowed:
|
case .allowed:
|
||||||
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||||
if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
|
if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
|
||||||
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -755,7 +756,7 @@ public class ContactsController: ViewController {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
|
if let navigationController = strongSelf.context.sharedContext.mainWindow?.viewController as? NavigationController {
|
||||||
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil))
|
navigationController.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}), completed: nil, cancelled: nil))
|
}), completed: nil, cancelled: nil))
|
||||||
|
@ -121,6 +121,19 @@ public final class ContextActionNode: ASDisplayNode, ContextActionNodeProtocol {
|
|||||||
statusNode.attributedText = NSAttributedString(string: value, font: subtitleFont, textColor: presentationData.theme.contextMenu.secondaryColor)
|
statusNode.attributedText = NSAttributedString(string: value, font: subtitleFont, textColor: presentationData.theme.contextMenu.secondaryColor)
|
||||||
statusNode.maximumNumberOfLines = 1
|
statusNode.maximumNumberOfLines = 1
|
||||||
self.statusNode = statusNode
|
self.statusNode = statusNode
|
||||||
|
case let .secondLineWithAttributedValue(value):
|
||||||
|
self.textNode.maximumNumberOfLines = 1
|
||||||
|
let statusNode = ImmediateTextNode()
|
||||||
|
statusNode.isAccessibilityElement = false
|
||||||
|
statusNode.isUserInteractionEnabled = false
|
||||||
|
statusNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
let mutableString = value.mutableCopy() as! NSMutableAttributedString
|
||||||
|
mutableString.addAttribute(.foregroundColor, value: presentationData.theme.contextMenu.secondaryColor, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
mutableString.addAttribute(.font, value: subtitleFont, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
statusNode.attributedText = mutableString
|
||||||
|
statusNode.maximumNumberOfLines = 1
|
||||||
|
self.statusNode = statusNode
|
||||||
case .multiline:
|
case .multiline:
|
||||||
self.textNode.maximumNumberOfLines = 0
|
self.textNode.maximumNumberOfLines = 0
|
||||||
self.statusNode = nil
|
self.statusNode = nil
|
||||||
@ -350,10 +363,15 @@ public final class ContextActionNode: ASDisplayNode, ContextActionNodeProtocol {
|
|||||||
|
|
||||||
self.textNode.attributedText = NSAttributedString(string: self.action.text, font: titleFont, textColor: textColor)
|
self.textNode.attributedText = NSAttributedString(string: self.action.text, font: titleFont, textColor: textColor)
|
||||||
|
|
||||||
|
let subtitleFont = Font.regular(presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0)
|
||||||
switch self.action.textLayout {
|
switch self.action.textLayout {
|
||||||
case let .secondLineWithValue(value):
|
case let .secondLineWithValue(value):
|
||||||
let subtitleFont = Font.regular(presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0)
|
|
||||||
self.statusNode?.attributedText = NSAttributedString(string: value, font: subtitleFont, textColor: presentationData.theme.contextMenu.secondaryColor)
|
self.statusNode?.attributedText = NSAttributedString(string: value, font: subtitleFont, textColor: presentationData.theme.contextMenu.secondaryColor)
|
||||||
|
case let .secondLineWithAttributedValue(value):
|
||||||
|
let mutableString = value.mutableCopy() as! NSMutableAttributedString
|
||||||
|
mutableString.addAttribute(.foregroundColor, value: presentationData.theme.contextMenu.secondaryColor, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
mutableString.addAttribute(.font, value: subtitleFont, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
self.statusNode?.attributedText = mutableString
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ public enum ContextMenuActionItemTextLayout {
|
|||||||
case singleLine
|
case singleLine
|
||||||
case twoLinesMax
|
case twoLinesMax
|
||||||
case secondLineWithValue(String)
|
case secondLineWithValue(String)
|
||||||
|
case secondLineWithAttributedValue(NSAttributedString)
|
||||||
case multiline
|
case multiline
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2150,6 +2151,7 @@ public protocol ContextExtractedContentSource: AnyObject {
|
|||||||
var initialAppearanceOffset: CGPoint { get }
|
var initialAppearanceOffset: CGPoint { get }
|
||||||
var centerVertically: Bool { get }
|
var centerVertically: Bool { get }
|
||||||
var keepInPlace: Bool { get }
|
var keepInPlace: Bool { get }
|
||||||
|
var adjustContentHorizontally: Bool { get }
|
||||||
var adjustContentForSideInset: Bool { get }
|
var adjustContentForSideInset: Bool { get }
|
||||||
var ignoreContentTouches: Bool { get }
|
var ignoreContentTouches: Bool { get }
|
||||||
var blurBackground: Bool { get }
|
var blurBackground: Bool { get }
|
||||||
@ -2170,6 +2172,10 @@ public extension ContextExtractedContentSource {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var adjustContentHorizontally: Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var adjustContentForSideInset: Bool {
|
var adjustContentForSideInset: Bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -229,20 +229,6 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
|||||||
|
|
||||||
self.highlightBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
|
self.highlightBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
|
||||||
|
|
||||||
var subtitle: String?
|
|
||||||
switch self.item.textLayout {
|
|
||||||
case .singleLine:
|
|
||||||
self.titleLabelNode.maximumNumberOfLines = 1
|
|
||||||
case .twoLinesMax:
|
|
||||||
self.titleLabelNode.maximumNumberOfLines = 2
|
|
||||||
case let .secondLineWithValue(subtitleValue):
|
|
||||||
self.titleLabelNode.maximumNumberOfLines = 1
|
|
||||||
subtitle = subtitleValue
|
|
||||||
case .multiline:
|
|
||||||
self.titleLabelNode.maximumNumberOfLines = 0
|
|
||||||
self.titleLabelNode.lineSpacing = 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
var forcedHeight: CGFloat?
|
var forcedHeight: CGFloat?
|
||||||
var titleVerticalOffset: CGFloat?
|
var titleVerticalOffset: CGFloat?
|
||||||
let titleFont: UIFont
|
let titleFont: UIFont
|
||||||
@ -265,6 +251,30 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
|||||||
let subtitleFont = Font.regular(presentationData.listsFontSize.baseDisplaySize * 14.0 / 17.0)
|
let subtitleFont = Font.regular(presentationData.listsFontSize.baseDisplaySize * 14.0 / 17.0)
|
||||||
let subtitleColor = presentationData.theme.contextMenu.secondaryColor
|
let subtitleColor = presentationData.theme.contextMenu.secondaryColor
|
||||||
|
|
||||||
|
var subtitle: NSAttributedString?
|
||||||
|
switch self.item.textLayout {
|
||||||
|
case .singleLine:
|
||||||
|
self.titleLabelNode.maximumNumberOfLines = 1
|
||||||
|
case .twoLinesMax:
|
||||||
|
self.titleLabelNode.maximumNumberOfLines = 2
|
||||||
|
case let .secondLineWithValue(subtitleValue):
|
||||||
|
self.titleLabelNode.maximumNumberOfLines = 1
|
||||||
|
subtitle = NSAttributedString(
|
||||||
|
string: subtitleValue,
|
||||||
|
font: subtitleFont,
|
||||||
|
textColor: subtitleColor
|
||||||
|
)
|
||||||
|
case let .secondLineWithAttributedValue(subtitleValue):
|
||||||
|
self.titleLabelNode.maximumNumberOfLines = 1
|
||||||
|
let mutableString = subtitleValue.mutableCopy() as! NSMutableAttributedString
|
||||||
|
mutableString.addAttribute(.foregroundColor, value: subtitleColor, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
mutableString.addAttribute(.font, value: subtitleFont, range: NSRange(location: 0, length: mutableString.length))
|
||||||
|
subtitle = mutableString
|
||||||
|
case .multiline:
|
||||||
|
self.titleLabelNode.maximumNumberOfLines = 0
|
||||||
|
self.titleLabelNode.lineSpacing = 0.1
|
||||||
|
}
|
||||||
|
|
||||||
let titleColor: UIColor
|
let titleColor: UIColor
|
||||||
switch self.item.textColor {
|
switch self.item.textColor {
|
||||||
case .primary:
|
case .primary:
|
||||||
@ -308,13 +318,7 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
|||||||
|
|
||||||
self.titleLabelNode.isUserInteractionEnabled = self.titleLabelNode.tapAttributeAction != nil && self.item.action == nil
|
self.titleLabelNode.isUserInteractionEnabled = self.titleLabelNode.tapAttributeAction != nil && self.item.action == nil
|
||||||
|
|
||||||
self.subtitleNode.attributedText = subtitle.flatMap { subtitle in
|
self.subtitleNode.attributedText = subtitle
|
||||||
return NSAttributedString(
|
|
||||||
string: subtitle,
|
|
||||||
font: subtitleFont,
|
|
||||||
textColor: subtitleColor
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var iconSize: CGSize?
|
var iconSize: CGSize?
|
||||||
if let iconSource = self.item.iconSource {
|
if let iconSource = self.item.iconSource {
|
||||||
|
@ -1064,6 +1064,9 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
if let contentNode = itemContentNode {
|
if let contentNode = itemContentNode {
|
||||||
var contentFrame = CGRect(origin: CGPoint(x: contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX, y: contentRect.minY - contentNode.containingItem.contentRect.minY + contentVerticalOffset + additionalVisibleOffsetY), size: contentNode.containingItem.view.bounds.size)
|
var contentFrame = CGRect(origin: CGPoint(x: contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX, y: contentRect.minY - contentNode.containingItem.contentRect.minY + contentVerticalOffset + additionalVisibleOffsetY), size: contentNode.containingItem.view.bounds.size)
|
||||||
if case let .extracted(extracted) = self.source {
|
if case let .extracted(extracted) = self.source {
|
||||||
|
if extracted.adjustContentHorizontally {
|
||||||
|
contentFrame.origin.x = combinedActionsFrame.minX
|
||||||
|
}
|
||||||
if extracted.centerVertically {
|
if extracted.centerVertically {
|
||||||
if combinedActionsFrame.height.isZero {
|
if combinedActionsFrame.height.isZero {
|
||||||
contentFrame.origin.y = floorToScreenPixels((layout.size.height - contentFrame.height) / 2.0)
|
contentFrame.origin.y = floorToScreenPixels((layout.size.height - contentFrame.height) / 2.0)
|
||||||
@ -1160,7 +1163,10 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
let contentX = contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX
|
let contentX = contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX
|
||||||
let contentWidth = contentNode.containingItem.view.bounds.size.width
|
let contentWidth = contentNode.containingItem.view.bounds.size.width
|
||||||
let contentHeight = contentNode.containingItem.view.bounds.size.height
|
let contentHeight = contentNode.containingItem.view.bounds.size.height
|
||||||
if case let .extracted(extracted) = self.source, extracted.centerVertically {
|
if case let .extracted(extracted) = self.source, extracted.adjustContentHorizontally {
|
||||||
|
let fixedContentX = self.actionsContainerNode.frame.minX
|
||||||
|
animationInContentXDistance = fixedContentX - contentX
|
||||||
|
} else if case let .extracted(extracted) = self.source, extracted.centerVertically {
|
||||||
if actionsSize.height.isZero {
|
if actionsSize.height.isZero {
|
||||||
var initialContentRect = contentRect
|
var initialContentRect = contentRect
|
||||||
initialContentRect.origin.y += extracted.initialAppearanceOffset.y
|
initialContentRect.origin.y += extracted.initialAppearanceOffset.y
|
||||||
@ -1429,7 +1435,10 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
|||||||
var animationInContentXDistance: CGFloat = 0.0
|
var animationInContentXDistance: CGFloat = 0.0
|
||||||
let contentX = contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX
|
let contentX = contentParentGlobalFrame.minX + contentRect.minX - contentNode.containingItem.contentRect.minX
|
||||||
let contentWidth = contentNode.containingItem.view.bounds.size.width
|
let contentWidth = contentNode.containingItem.view.bounds.size.width
|
||||||
if case let .extracted(extracted) = self.source, extracted.centerVertically {
|
if case let .extracted(extracted) = self.source, extracted.adjustContentHorizontally {
|
||||||
|
let fixedContentX = self.actionsContainerNode.frame.minX
|
||||||
|
animationInContentXDistance = contentX - fixedContentX
|
||||||
|
} else if case let .extracted(extracted) = self.source, extracted.centerVertically {
|
||||||
if actionsSize.height.isZero {
|
if actionsSize.height.isZero {
|
||||||
// let fixedContentY = floorToScreenPixels((layout.size.height - contentHeight) / 2.0)
|
// let fixedContentY = floorToScreenPixels((layout.size.height - contentHeight) / 2.0)
|
||||||
animationInContentYDistance = 0.0 //contentY - fixedContentY
|
animationInContentYDistance = 0.0 //contentY - fixedContentY
|
||||||
|
@ -330,7 +330,7 @@ public func generateTintedImage(image: UIImage?, color: UIColor, backgroundColor
|
|||||||
return tintedImage
|
return tintedImage
|
||||||
}
|
}
|
||||||
|
|
||||||
public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> UIImage? {
|
public func generateGradientTintedImage(image: UIImage?, colors: [UIColor], direction: GradientImageDirection = .vertical) -> UIImage? {
|
||||||
guard let image = image else {
|
guard let image = image else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -357,7 +357,21 @@ public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> U
|
|||||||
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||||
|
|
||||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
let start: CGPoint
|
||||||
|
let end: CGPoint
|
||||||
|
switch direction {
|
||||||
|
case .horizontal:
|
||||||
|
start = .zero
|
||||||
|
end = CGPoint(x: imageRect.width, y: 0.0)
|
||||||
|
case .vertical:
|
||||||
|
start = CGPoint(x: 0.0, y: imageRect.height)
|
||||||
|
end = .zero
|
||||||
|
case .diagonal:
|
||||||
|
start = CGPoint(x: 0.0, y: 0.0)
|
||||||
|
end = CGPoint(x: imageRect.width, y: imageRect.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.drawLinearGradient(gradient, start: start, end: end, options: CGGradientDrawingOptions())
|
||||||
} else if !colors.isEmpty {
|
} else if !colors.isEmpty {
|
||||||
context.setFillColor(colors[0].cgColor)
|
context.setFillColor(colors[0].cgColor)
|
||||||
context.fill(imageRect)
|
context.fill(imageRect)
|
||||||
|
@ -1327,8 +1327,6 @@ private extension UIBezierPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extension UIImageView {
|
extension UIImageView {
|
||||||
func setDrawingAnimatedImage(data: Data) {
|
func setDrawingAnimatedImage(data: Data) {
|
||||||
DispatchQueue.global().async {
|
DispatchQueue.global().async {
|
||||||
@ -1354,48 +1352,3 @@ extension UIImageView {
|
|||||||
self.animationRepeatCount = 0
|
self.animationRepeatCount = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private func prerenderEntityTransformations(entity: DrawingEntity, image: UIImage, colorSpace: CGColorSpace) -> UIImage {
|
|
||||||
// let imageSize = image.size
|
|
||||||
//
|
|
||||||
// let angle: CGFloat
|
|
||||||
// var scale: CGFloat
|
|
||||||
// let position: CGPoint
|
|
||||||
//
|
|
||||||
// if let entity = entity as? DrawingStickerEntity {
|
|
||||||
// angle = -entity.rotation
|
|
||||||
// scale = entity.scale
|
|
||||||
// position = entity.position
|
|
||||||
// } else {
|
|
||||||
// fatalError()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let rotatedSize = CGSize(
|
|
||||||
// width: abs(imageSize.width * cos(angle)) + abs(imageSize.height * sin(angle)),
|
|
||||||
// height: abs(imageSize.width * sin(angle)) + abs(imageSize.height * cos(angle))
|
|
||||||
// )
|
|
||||||
// let newSize = CGSize(width: rotatedSize.width * scale, height: rotatedSize.height * scale)
|
|
||||||
//
|
|
||||||
// let newImage = generateImage(newSize, contextGenerator: { size, context in
|
|
||||||
// context.setAllowsAntialiasing(true)
|
|
||||||
// context.setShouldAntialias(true)
|
|
||||||
// context.interpolationQuality = .high
|
|
||||||
// context.clear(CGRect(origin: .zero, size: size))
|
|
||||||
// context.translateBy(x: newSize.width * 0.5, y: newSize.height * 0.5)
|
|
||||||
// context.rotate(by: angle)
|
|
||||||
// context.scaleBy(x: scale, y: scale)
|
|
||||||
// let drawRect = CGRect(
|
|
||||||
// x: -imageSize.width * 0.5,
|
|
||||||
// y: -imageSize.height * 0.5,
|
|
||||||
// width: imageSize.width,
|
|
||||||
// height: imageSize.height
|
|
||||||
// )
|
|
||||||
// if let cgImage = image.cgImage {
|
|
||||||
// context.draw(cgImage, in: drawRect)
|
|
||||||
// }
|
|
||||||
// }, scale: 1.0)!
|
|
||||||
//
|
|
||||||
// let _ = position
|
|
||||||
//
|
|
||||||
// return newImage
|
|
||||||
//}
|
|
||||||
|
@ -582,6 +582,7 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
case prizeDescription
|
case prizeDescription
|
||||||
case randomId
|
case randomId
|
||||||
case untilDate
|
case untilDate
|
||||||
|
case stars
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PurposeType: Int32 {
|
enum PurposeType: Int32 {
|
||||||
@ -591,6 +592,7 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
case gift
|
case gift
|
||||||
case giftCode
|
case giftCode
|
||||||
case giveaway
|
case giveaway
|
||||||
|
case stars
|
||||||
}
|
}
|
||||||
|
|
||||||
case subscription
|
case subscription
|
||||||
@ -599,6 +601,7 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
case gift(peerId: EnginePeer.Id)
|
case gift(peerId: EnginePeer.Id)
|
||||||
case giftCode(peerIds: [EnginePeer.Id], boostPeer: EnginePeer.Id?)
|
case giftCode(peerIds: [EnginePeer.Id], boostPeer: EnginePeer.Id?)
|
||||||
case giveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32)
|
case giveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32)
|
||||||
|
case stars(count: Int64)
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
@ -631,6 +634,8 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
randomId: try container.decode(Int64.self, forKey: .randomId),
|
randomId: try container.decode(Int64.self, forKey: .randomId),
|
||||||
untilDate: try container.decode(Int32.self, forKey: .untilDate)
|
untilDate: try container.decode(Int32.self, forKey: .untilDate)
|
||||||
)
|
)
|
||||||
|
case .stars:
|
||||||
|
self = .stars(count: try container.decode(Int64.self, forKey: .stars))
|
||||||
default:
|
default:
|
||||||
throw DecodingError.generic
|
throw DecodingError.generic
|
||||||
}
|
}
|
||||||
@ -663,6 +668,9 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
try container.encodeIfPresent(prizeDescription, forKey: .prizeDescription)
|
try container.encodeIfPresent(prizeDescription, forKey: .prizeDescription)
|
||||||
try container.encode(randomId, forKey: .randomId)
|
try container.encode(randomId, forKey: .randomId)
|
||||||
try container.encode(untilDate, forKey: .untilDate)
|
try container.encode(untilDate, forKey: .untilDate)
|
||||||
|
case let .stars(count):
|
||||||
|
try container.encode(PurposeType.stars.rawValue, forKey: .type)
|
||||||
|
try container.encode(count, forKey: .stars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,6 +688,8 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
self = .giftCode(peerIds: peerIds, boostPeer: boostPeer)
|
self = .giftCode(peerIds: peerIds, boostPeer: boostPeer)
|
||||||
case let .giveaway(boostPeer, additionalPeerIds, countries, onlyNewSubscribers, showWinners, prizeDescription, randomId, untilDate, _, _):
|
case let .giveaway(boostPeer, additionalPeerIds, countries, onlyNewSubscribers, showWinners, prizeDescription, randomId, untilDate, _, _):
|
||||||
self = .giveaway(boostPeer: boostPeer, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate)
|
self = .giveaway(boostPeer: boostPeer, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate)
|
||||||
|
case let .stars(count, _, _):
|
||||||
|
self = .stars(count: count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,6 +708,8 @@ private final class PendingInAppPurchaseState: Codable {
|
|||||||
return .giftCode(peerIds: peerIds, boostPeer: boostPeer, currency: currency, amount: amount)
|
return .giftCode(peerIds: peerIds, boostPeer: boostPeer, currency: currency, amount: amount)
|
||||||
case let .giveaway(boostPeer, additionalPeerIds, countries, onlyNewSubscribers, showWinners, prizeDescription, randomId, untilDate):
|
case let .giveaway(boostPeer, additionalPeerIds, countries, onlyNewSubscribers, showWinners, prizeDescription, randomId, untilDate):
|
||||||
return .giveaway(boostPeer: boostPeer, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate, currency: currency, amount: amount)
|
return .giveaway(boostPeer: boostPeer, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate, currency: currency, amount: amount)
|
||||||
|
case let .stars(count):
|
||||||
|
return .stars(count: count, currency: currency, amount: amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1995,7 +1995,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, ASS
|
|||||||
let changeEmailActionButtonFrame: CGRect
|
let changeEmailActionButtonFrame: CGRect
|
||||||
let resendCodeActionFrame: CGRect
|
let resendCodeActionFrame: CGRect
|
||||||
let resendCodeActionButtonFrame: CGRect
|
let resendCodeActionButtonFrame: CGRect
|
||||||
if changeEmailActionSize.width + resendCodeActionSize.width > layout.size.width - buttonFrame.minX * 2.0 {
|
if changeEmailActionSize.width + resendCodeActionSize.width > layout.size.width - buttonFrame.minX * 2.0 - 32.0 {
|
||||||
changeEmailActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
|
changeEmailActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.minY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
|
||||||
changeEmailActionFrame = CGRect(origin: CGPoint(x: changeEmailActionButtonFrame.minX + floor((changeEmailActionButtonFrame.width - changeEmailActionSize.width) / 2.0), y: changeEmailActionButtonFrame.minY + floor((changeEmailActionButtonFrame.height - changeEmailActionSize.height) / 2.0)), size: changeEmailActionSize)
|
changeEmailActionFrame = CGRect(origin: CGPoint(x: changeEmailActionButtonFrame.minX + floor((changeEmailActionButtonFrame.width - changeEmailActionSize.width) / 2.0), y: changeEmailActionButtonFrame.minY + floor((changeEmailActionButtonFrame.height - changeEmailActionSize.height) / 2.0)), size: changeEmailActionSize)
|
||||||
resendCodeActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.maxY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
|
resendCodeActionButtonFrame = CGRect(origin: CGPoint(x: buttonFrame.minX, y: buttonFrame.maxY), size: CGSize(width: buttonFrame.width, height: buttonFrame.height))
|
||||||
|
@ -24,6 +24,8 @@ import UndoUI
|
|||||||
import GalleryUI
|
import GalleryUI
|
||||||
import PeerAvatarGalleryUI
|
import PeerAvatarGalleryUI
|
||||||
import Postbox
|
import Postbox
|
||||||
|
import ShareController
|
||||||
|
import ContextUI
|
||||||
|
|
||||||
private enum DeviceContactInfoAction {
|
private enum DeviceContactInfoAction {
|
||||||
case sendMessage
|
case sendMessage
|
||||||
@ -33,7 +35,7 @@ private enum DeviceContactInfoAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class DeviceContactInfoControllerArguments {
|
private final class DeviceContactInfoControllerArguments {
|
||||||
let context: AccountContext
|
let accountContext: AccountContext?
|
||||||
let isPlain: Bool
|
let isPlain: Bool
|
||||||
let updateEditingName: (ItemListAvatarAndNameInfoItemName) -> Void
|
let updateEditingName: (ItemListAvatarAndNameInfoItemName) -> Void
|
||||||
let updatePhone: (Int64, String) -> Void
|
let updatePhone: (Int64, String) -> Void
|
||||||
@ -50,8 +52,8 @@ private final class DeviceContactInfoControllerArguments {
|
|||||||
let updateShareViaException: (Bool) -> Void
|
let updateShareViaException: (Bool) -> Void
|
||||||
let openAvatar: (EnginePeer) -> Void
|
let openAvatar: (EnginePeer) -> Void
|
||||||
|
|
||||||
init(context: AccountContext, isPlain: Bool, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updatePhone: @escaping (Int64, String) -> Void, updatePhoneLabel: @escaping (Int64, String) -> Void, deletePhone: @escaping (Int64) -> Void, setPhoneIdWithRevealedOptions: @escaping (Int64?, Int64?) -> Void, addPhoneNumber: @escaping () -> Void, performAction: @escaping (DeviceContactInfoAction) -> Void, toggleSelection: @escaping (DeviceContactInfoDataId) -> Void, callPhone: @escaping (String) -> Void, openUrl: @escaping (String) -> Void, openAddress: @escaping (DeviceContactAddressData) -> Void, displayCopyContextMenu: @escaping (DeviceContactInfoEntryTag, String) -> Void, updateShareViaException: @escaping (Bool) -> Void, openAvatar: @escaping (EnginePeer) -> Void) {
|
init(accountContext: AccountContext?, isPlain: Bool, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updatePhone: @escaping (Int64, String) -> Void, updatePhoneLabel: @escaping (Int64, String) -> Void, deletePhone: @escaping (Int64) -> Void, setPhoneIdWithRevealedOptions: @escaping (Int64?, Int64?) -> Void, addPhoneNumber: @escaping () -> Void, performAction: @escaping (DeviceContactInfoAction) -> Void, toggleSelection: @escaping (DeviceContactInfoDataId) -> Void, callPhone: @escaping (String) -> Void, openUrl: @escaping (String) -> Void, openAddress: @escaping (DeviceContactAddressData) -> Void, displayCopyContextMenu: @escaping (DeviceContactInfoEntryTag, String) -> Void, updateShareViaException: @escaping (Bool) -> Void, openAvatar: @escaping (EnginePeer) -> Void) {
|
||||||
self.context = context
|
self.accountContext = accountContext
|
||||||
self.isPlain = isPlain
|
self.isPlain = isPlain
|
||||||
self.updateEditingName = updateEditingName
|
self.updateEditingName = updateEditingName
|
||||||
self.updatePhone = updatePhone
|
self.updatePhone = updatePhone
|
||||||
@ -404,7 +406,10 @@ private enum DeviceContactInfoEntry: ItemListNodeEntry {
|
|||||||
let arguments = arguments as! DeviceContactInfoControllerArguments
|
let arguments = arguments as! DeviceContactInfoControllerArguments
|
||||||
switch self {
|
switch self {
|
||||||
case let .info(_, _, _, dateTimeFormat, peer, state, jobSummary, _, hiddenAvatar):
|
case let .info(_, _, _, dateTimeFormat, peer, state, jobSummary, _, hiddenAvatar):
|
||||||
return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .contact, peer: peer, presence: nil, label: jobSummary, memberCount: nil, state: state, sectionId: self.section, style: arguments.isPlain ? .plain : .blocks(withTopInset: false, withExtendedBottomInset: true), editingNameUpdated: { editingName in
|
guard let accountContext = arguments.accountContext else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
return ItemListAvatarAndNameInfoItem(accountContext: accountContext, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .contact, peer: peer, presence: nil, label: jobSummary, memberCount: nil, state: state, sectionId: self.section, style: arguments.isPlain ? .plain : .blocks(withTopInset: false, withExtendedBottomInset: true), editingNameUpdated: { editingName in
|
||||||
arguments.updateEditingName(editingName)
|
arguments.updateEditingName(editingName)
|
||||||
}, avatarTapped: {
|
}, avatarTapped: {
|
||||||
if peer.smallProfileImage != nil {
|
if peer.smallProfileImage != nil {
|
||||||
@ -625,7 +630,7 @@ private func filteredContactData(contactData: DeviceContactExtendedData, exclude
|
|||||||
return DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumbers: phoneNumbers), middleName: contactData.middleName, prefix: contactData.prefix, suffix: contactData.suffix, organization: includeJob ? contactData.organization : "", jobTitle: includeJob ? contactData.jobTitle : "", department: includeJob ? contactData.department : "", emailAddresses: emailAddresses, urls: urls, addresses: addresses, birthdayDate: includeBirthday ? contactData.birthdayDate : nil, socialProfiles: socialProfiles, instantMessagingProfiles: instantMessagingProfiles, note: includeNote ? contactData.note : "")
|
return DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumbers: phoneNumbers), middleName: contactData.middleName, prefix: contactData.prefix, suffix: contactData.suffix, organization: includeJob ? contactData.organization : "", jobTitle: includeJob ? contactData.jobTitle : "", department: includeJob ? contactData.department : "", emailAddresses: emailAddresses, urls: urls, addresses: addresses, birthdayDate: includeBirthday ? contactData.birthdayDate : nil, socialProfiles: socialProfiles, instantMessagingProfiles: instantMessagingProfiles, note: includeNote ? contactData.note : "")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deviceContactInfoEntries(account: Account, engine: TelegramEngine, presentationData: PresentationData, peer: EnginePeer?, isShare: Bool, shareViaException: Bool, contactData: DeviceContactExtendedData, isContact: Bool, state: DeviceContactInfoState, selecting: Bool, editingPhoneNumbers: Bool, hiddenAvatar: TelegramMediaImageRepresentation?) -> [DeviceContactInfoEntry] {
|
private func deviceContactInfoEntries(context: ShareControllerAccountContext, presentationData: PresentationData, peer: EnginePeer?, isShare: Bool, shareViaException: Bool, contactData: DeviceContactExtendedData, isContact: Bool, state: DeviceContactInfoState, selecting: Bool, editingPhoneNumbers: Bool, hiddenAvatar: TelegramMediaImageRepresentation?) -> [DeviceContactInfoEntry] {
|
||||||
var entries: [DeviceContactInfoEntry] = []
|
var entries: [DeviceContactInfoEntry] = []
|
||||||
|
|
||||||
var editingName: ItemListAvatarAndNameInfoItemName?
|
var editingName: ItemListAvatarAndNameInfoItemName?
|
||||||
@ -738,16 +743,20 @@ private func deviceContactInfoEntries(account: Account, engine: TelegramEngine,
|
|||||||
|
|
||||||
var addressIndex = 0
|
var addressIndex = 0
|
||||||
for address in contactData.addresses {
|
for address in contactData.addresses {
|
||||||
let signal = geocodeLocation(address: address.asPostalAddress)
|
let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>
|
||||||
|> mapToSignal { coordinates -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> in
|
if let context = context as? ShareControllerAppAccountContext {
|
||||||
if let (latitude, longitude) = coordinates {
|
signal = geocodeLocation(address: address.asPostalAddress)
|
||||||
let resource = MapSnapshotMediaResource(latitude: latitude, longitude: longitude, width: 90, height: 90)
|
|> mapToSignal { coordinates -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> in
|
||||||
return chatMapSnapshotImage(engine: engine, resource: resource)
|
if let (latitude, longitude) = coordinates {
|
||||||
} else {
|
let resource = MapSnapshotMediaResource(latitude: latitude, longitude: longitude, width: 90, height: 90)
|
||||||
return .single({ _ in return nil })
|
return chatMapSnapshotImage(engine: context.context.engine, resource: resource)
|
||||||
|
} else {
|
||||||
|
return .single({ _ in return nil })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
signal = .single({ _ in return nil })
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.append(.address(entries.count, addressIndex, presentationData.theme, localizedGenericContactFieldLabel(label: address.label, strings: presentationData.strings), address, signal, selecting ? !state.excludedComponents.contains(.address(address)) : nil))
|
entries.append(.address(entries.count, addressIndex, presentationData.theme, localizedGenericContactFieldLabel(label: address.label, strings: presentationData.strings), address, signal, selecting ? !state.excludedComponents.contains(.address(address)) : nil))
|
||||||
addressIndex += 1
|
addressIndex += 1
|
||||||
}
|
}
|
||||||
@ -828,7 +837,7 @@ private final class DeviceContactInfoController: ItemListController, MFMessageCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deviceContactInfoController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController {
|
public func deviceContactInfoController(context: ShareControllerAccountContext, environment: ShareControllerEnvironment, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController {
|
||||||
var initialState = DeviceContactInfoState()
|
var initialState = DeviceContactInfoState()
|
||||||
if case let .create(peer, contactData, _, _, _) = subject {
|
if case let .create(peer, contactData, _, _, _) = subject {
|
||||||
var peerPhoneNumber: String?
|
var peerPhoneNumber: String?
|
||||||
@ -876,7 +885,11 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
|
|
||||||
var displayCopyContextMenuImpl: ((DeviceContactInfoEntryTag, String) -> Void)?
|
var displayCopyContextMenuImpl: ((DeviceContactInfoEntryTag, String) -> Void)?
|
||||||
|
|
||||||
|
let presentationData = environment.presentationData
|
||||||
let callImpl: (String) -> Void = { number in
|
let callImpl: (String) -> Void = { number in
|
||||||
|
guard let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
|
return
|
||||||
|
}
|
||||||
let user: Signal<TelegramUser?, NoError>
|
let user: Signal<TelegramUser?, NoError>
|
||||||
if let peer = subject.peer {
|
if let peer = subject.peer {
|
||||||
user = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|
user = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|
||||||
@ -890,10 +903,10 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
} else {
|
} else {
|
||||||
user = .single(nil)
|
user = .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = (user
|
let _ = (user
|
||||||
|> deliverOnMainQueue).start(next: { user in
|
|> deliverOnMainQueue).start(next: { user in
|
||||||
if let user = user, let phone = user.phone, formatPhoneNumber(phone) == formatPhoneNumber(number) {
|
if let user = user, let phone = user.phone, formatPhoneNumber(phone) == formatPhoneNumber(number) {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
let controller = ActionSheetController(presentationData: presentationData)
|
let controller = ActionSheetController(presentationData: presentationData)
|
||||||
let dismissAction: () -> Void = { [weak controller] in
|
let dismissAction: () -> Void = { [weak controller] in
|
||||||
controller?.dismissAnimated()
|
controller?.dismissAnimated()
|
||||||
@ -932,7 +945,13 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
shareViaException = shareViaExceptionValue
|
shareViaException = shareViaExceptionValue
|
||||||
}
|
}
|
||||||
|
|
||||||
let arguments = DeviceContactInfoControllerArguments(context: context, isPlain: !isShare, updateEditingName: { editingName in
|
let accountContext: AccountContext?
|
||||||
|
if let context = context as? ShareControllerAppAccountContext {
|
||||||
|
accountContext = context.context
|
||||||
|
} else {
|
||||||
|
accountContext = nil
|
||||||
|
}
|
||||||
|
let arguments = DeviceContactInfoControllerArguments(accountContext: accountContext, isPlain: !isShare, updateEditingName: { editingName in
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
if let _ = state.editingState {
|
if let _ = state.editingState {
|
||||||
@ -952,6 +971,9 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
}, updatePhoneLabel: { id, currentLabel in
|
}, updatePhoneLabel: { id, currentLabel in
|
||||||
|
guard let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
|
return
|
||||||
|
}
|
||||||
pushControllerImpl?(phoneLabelController(context: context, currentLabel: currentLabel, completion: { value in
|
pushControllerImpl?(phoneLabelController(context: context, currentLabel: currentLabel, completion: { value in
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
@ -1000,7 +1022,6 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
if subject.contactData.basicData.phoneNumbers.count == 1 {
|
if subject.contactData.basicData.phoneNumbers.count == 1 {
|
||||||
inviteAction(subject.contactData.basicData.phoneNumbers[0].value)
|
inviteAction(subject.contactData.basicData.phoneNumbers[0].value)
|
||||||
} else {
|
} else {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
let controller = ActionSheetController(presentationData: presentationData)
|
let controller = ActionSheetController(presentationData: presentationData)
|
||||||
let dismissAction: () -> Void = { [weak controller] in
|
let dismissAction: () -> Void = { [weak controller] in
|
||||||
controller?.dismissAnimated()
|
controller?.dismissAnimated()
|
||||||
@ -1020,7 +1041,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}
|
}
|
||||||
case .createContact:
|
case .createContact:
|
||||||
pushControllerImpl?(deviceContactInfoController(context: context, subject: .create(peer: subject.peer, contactData: subject.contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
pushControllerImpl?(deviceContactInfoController(context: context, environment: environment, subject: .create(peer: subject.peer, contactData: subject.contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
||||||
dismissImpl?(false)
|
dismissImpl?(false)
|
||||||
}), completed: nil, cancelled: nil))
|
}), completed: nil, cancelled: nil))
|
||||||
case .addToExisting:
|
case .addToExisting:
|
||||||
@ -1059,9 +1080,9 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
})
|
})
|
||||||
|
|
||||||
let hiddenAvatarPromise = Promise<TelegramMediaImageRepresentation?>(nil)
|
let hiddenAvatarPromise = Promise<TelegramMediaImageRepresentation?>(nil)
|
||||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
let updatedPresentationData = updatedPresentationData?.signal ?? environment.updatedPresentationData
|
||||||
let previousEditingPhoneIds = Atomic<Set<Int64>?>(value: nil)
|
let previousEditingPhoneIds = Atomic<Set<Int64>?>(value: nil)
|
||||||
let signal = combineLatest(presentationData, statePromise.get(), contactData, hiddenAvatarPromise.get())
|
let signal = combineLatest(updatedPresentationData, statePromise.get(), contactData, hiddenAvatarPromise.get())
|
||||||
|> map { presentationData, state, peerAndContactData, hiddenAvatar -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|> map { presentationData, state, peerAndContactData, hiddenAvatar -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||||
var presentationData = presentationData
|
var presentationData = presentationData
|
||||||
let updatedTheme = presentationData.theme.withModalBlocksBackground()
|
let updatedTheme = presentationData.theme.withModalBlocksBackground()
|
||||||
@ -1116,6 +1137,9 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
|
|
||||||
rightNavigationButton = ItemListNavigationButton(content: .text(isShare ? presentationData.strings.Common_Done : presentationData.strings.Compose_Create), style: .bold, enabled: (isShare || !filteredPhoneNumbers.isEmpty) && composedContactData != nil, action: {
|
rightNavigationButton = ItemListNavigationButton(content: .text(isShare ? presentationData.strings.Common_Done : presentationData.strings.Compose_Create), style: .bold, enabled: (isShare || !filteredPhoneNumbers.isEmpty) && composedContactData != nil, action: {
|
||||||
if let composedContactData = composedContactData {
|
if let composedContactData = composedContactData {
|
||||||
|
guard let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
|
return
|
||||||
|
}
|
||||||
var addToPrivacyExceptions = false
|
var addToPrivacyExceptions = false
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
@ -1129,7 +1153,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
if share, filteredPhoneNumbers.count <= 1, let peer = peer {
|
if share, filteredPhoneNumbers.count <= 1, let peer = peer {
|
||||||
addContactDisposable.set((context.engine.contacts.addContactInteractively(peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
addContactDisposable.set((context.engine.contacts.addContactInteractively(peerId: peer.id, firstName: composedContactData.basicData.firstName, lastName: composedContactData.basicData.lastName, phoneNumber: filteredPhoneNumbers.first?.value ?? "", addToPrivacyExceptions: shareViaException && addToPrivacyExceptions)
|
||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: (environment.presentationData, updatedPresentationData), title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
let _ = (contactDataManager.createContactWithData(composedContactData)
|
let _ = (contactDataManager.createContactWithData(composedContactData)
|
||||||
|> deliverOnMainQueue).start(next: { contactIdAndData in
|
|> deliverOnMainQueue).start(next: { contactIdAndData in
|
||||||
@ -1250,7 +1274,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId)
|
focusItemTag = DeviceContactInfoEntryTag.editingPhone(insertedPhoneId)
|
||||||
}
|
}
|
||||||
|
|
||||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: deviceContactInfoEntries(account: context.account, engine: context.engine, presentationData: presentationData, peer: peerAndContactData.0, isShare: isShare, shareViaException: shareViaException, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones, hiddenAvatar: hiddenAvatar), style: isShare ? .blocks : .plain, focusItemTag: focusItemTag)
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: deviceContactInfoEntries(context: context, presentationData: presentationData, peer: peerAndContactData.0, isShare: isShare, shareViaException: shareViaException, contactData: peerAndContactData.2, isContact: peerAndContactData.1 != nil, state: state, selecting: selecting, editingPhoneNumbers: editingPhones, hiddenAvatar: hiddenAvatar), style: isShare ? .blocks : .plain, focusItemTag: focusItemTag)
|
||||||
|
|
||||||
return (controllerState, (listState, arguments))
|
return (controllerState, (listState, arguments))
|
||||||
}
|
}
|
||||||
@ -1258,24 +1282,27 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
actionsDisposable.dispose()
|
actionsDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = DeviceContactInfoController(context: context, state: signal)
|
let controller = DeviceContactInfoController(presentationData: ItemListPresentationData(environment.presentationData), updatedPresentationData: environment.updatedPresentationData |> map { ItemListPresentationData($0) }, state: signal, tabBarItem: nil)
|
||||||
controller.navigationPresentation = .modal
|
controller.navigationPresentation = .modal
|
||||||
addToExistingImpl = { [weak controller] in
|
addToExistingImpl = { [weak controller] in
|
||||||
guard let controller = controller else {
|
guard let controller, let accountContext = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addContactToExisting(context: context, parentController: controller, contactData: subject.contactData, completion: { peer, contactId, contactData in
|
addContactToExisting(context: accountContext, parentController: controller, contactData: subject.contactData, completion: { peer, contactId, contactData in
|
||||||
replaceControllerImpl?(deviceContactInfoController(context: context, subject: .vcard(peer?._asPeer(), contactId, contactData), completed: nil, cancelled: nil))
|
replaceControllerImpl?(deviceContactInfoController(context: context, environment: environment, subject: .vcard(peer?._asPeer(), contactId, contactData), completed: nil, cancelled: nil))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
openChatImpl = { [weak controller] peerId in
|
openChatImpl = { [weak controller] peerId in
|
||||||
|
guard let controller, let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
|
return
|
||||||
|
}
|
||||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
|> deliverOnMainQueue).start(next: { [weak controller] peer in
|
||||||
guard let peer = peer else {
|
guard let peer, let controller else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let navigationController = (controller?.navigationController as? NavigationController) {
|
if let navigationController = (controller.navigationController as? NavigationController) {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1301,7 +1328,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
inviteImpl = { [weak controller] numbers in
|
inviteImpl = { [weak controller] numbers in
|
||||||
controller?.inviteContact(presentationData: context.sharedContext.currentPresentationData.with { $0 }, numbers: numbers)
|
controller?.inviteContact(presentationData: environment.presentationData, numbers: numbers)
|
||||||
}
|
}
|
||||||
openAddressImpl = { [weak controller] address in
|
openAddressImpl = { [weak controller] address in
|
||||||
guard let _ = controller else {
|
guard let _ = controller else {
|
||||||
@ -1309,7 +1336,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
openUrlImpl = { [weak controller] url in
|
openUrlImpl = { [weak controller] url in
|
||||||
guard let controller = controller else {
|
guard let controller, let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: controller.navigationController as? NavigationController, dismissInput: { [weak controller] in
|
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: controller.navigationController as? NavigationController, dismissInput: { [weak controller] in
|
||||||
@ -1319,7 +1346,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
|
|
||||||
displayCopyContextMenuImpl = { [weak controller] tag, value in
|
displayCopyContextMenuImpl = { [weak controller] tag, value in
|
||||||
if let strongController = controller {
|
if let strongController = controller {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = environment.presentationData
|
||||||
var resultItemNode: ListViewItemNode?
|
var resultItemNode: ListViewItemNode?
|
||||||
let _ = strongController.frameForItemNode({ itemNode in
|
let _ = strongController.frameForItemNode({ itemNode in
|
||||||
if let itemNode = itemNode as? ItemListTextWithLabelItemNode {
|
if let itemNode = itemNode as? ItemListTextWithLabelItemNode {
|
||||||
@ -1350,6 +1377,9 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
openAvatarImpl = { [weak controller] peer in
|
openAvatarImpl = { [weak controller] peer in
|
||||||
|
guard let context = (context as? ShareControllerAppAccountContext)?.context else {
|
||||||
|
return
|
||||||
|
}
|
||||||
let avatarController = AvatarGalleryController(context: context, peer: peer, replaceRootController: { _, _ in
|
let avatarController = AvatarGalleryController(context: context, peer: peer, replaceRootController: { _, _ in
|
||||||
})
|
})
|
||||||
hiddenAvatarPromise.set(
|
hiddenAvatarPromise.set(
|
||||||
@ -1413,7 +1443,7 @@ private func addContactToExisting(context: AccountContext, parentController: Vie
|
|||||||
let _ = (dataSignal
|
let _ = (dataSignal
|
||||||
|> deliverOnMainQueue).start(next: { peer, stableId in
|
|> deliverOnMainQueue).start(next: { peer, stableId in
|
||||||
guard let stableId = stableId else {
|
guard let stableId = stableId else {
|
||||||
parentController.present(deviceContactInfoController(context: context, subject: .create(peer: peer?._asPeer(), contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
parentController.present(deviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), subject: .create(peer: peer?._asPeer(), contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
||||||
}), completed: nil, cancelled: nil), in: .window(.root))
|
}), completed: nil, cancelled: nil), in: .window(.root))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1459,7 +1489,7 @@ func addContactOptionsController(context: AccountContext, peer: EnginePeer?, con
|
|||||||
controller.setItemGroups([
|
controller.setItemGroups([
|
||||||
ActionSheetItemGroup(items: [
|
ActionSheetItemGroup(items: [
|
||||||
ActionSheetButtonItem(title: presentationData.strings.Profile_CreateNewContact, action: { [weak controller] in
|
ActionSheetButtonItem(title: presentationData.strings.Profile_CreateNewContact, action: { [weak controller] in
|
||||||
controller?.present(context.sharedContext.makeDeviceContactInfoController(context: context, subject: .create(peer: peer?._asPeer(), contactData: contactData, isSharing: peer != nil, shareViaException: false, completion: { _, _, _ in
|
controller?.present(context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), subject: .create(peer: peer?._asPeer(), contactData: contactData, isSharing: peer != nil, shareViaException: false, completion: { _, _, _ in
|
||||||
}), completed: nil, cancelled: nil), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
}), completed: nil, cancelled: nil), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
dismissAction()
|
dismissAction()
|
||||||
}),
|
}),
|
||||||
@ -1476,3 +1506,32 @@ func addContactOptionsController(context: AccountContext, peer: EnginePeer?, con
|
|||||||
])
|
])
|
||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func pushContactContextOptionsController(context: AccountContext, contextController: ContextControllerProtocol, presentationData: PresentationData, peer: EnginePeer?, contactData: DeviceContactExtendedData, parentController: ViewController, push: @escaping (ViewController) -> Void) {
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: presentationData.strings.Common_Back, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Back"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { c, _ in
|
||||||
|
c?.popItems()
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
items.append(.separator)
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: presentationData.strings.Chat_Context_Phone_CreateNewContact, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
push(context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), subject: .create(peer: peer?._asPeer(), contactData: contactData, isSharing: peer != nil, shareViaException: false, completion: { _, _, _ in
|
||||||
|
}), completed: nil, cancelled: nil))
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: presentationData.strings.Chat_Context_Phone_AddToExistingContact, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MoveToContacts"), color: theme.contextMenu.primaryColor) }, action: { [weak parentController] _, f in
|
||||||
|
f(.default)
|
||||||
|
guard let parentController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
addContactToExisting(context: context, parentController: parentController, contactData: contactData, completion: { peer, contactId, contactData in
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
contextController.pushItems(items: .single(ContextController.Items(content: .list(items))))
|
||||||
|
}
|
||||||
|
@ -59,7 +59,7 @@ public func openAddPersonContactImpl(context: AccountContext, updatedPresentatio
|
|||||||
shareViaException = statusSettings.contains(.addExceptionWhenAddingContact)
|
shareViaException = statusSettings.contains(.addExceptionWhenAddingContact)
|
||||||
}
|
}
|
||||||
|
|
||||||
pushController(deviceContactInfoController(context: context, updatedPresentationData: updatedPresentationData, subject: .create(peer: user, contactData: contactData, isSharing: true, shareViaException: shareViaException, completion: { peer, stableId, contactData in
|
pushController(deviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), updatedPresentationData: updatedPresentationData, subject: .create(peer: user, contactData: contactData, isSharing: true, shareViaException: shareViaException, completion: { peer, stableId, contactData in
|
||||||
if let peer = peer as? TelegramUser {
|
if let peer = peer as? TelegramUser {
|
||||||
completion()
|
completion()
|
||||||
|
|
||||||
|
@ -304,18 +304,6 @@ private func collectExternalShareItems(strings: PresentationStrings, dateTimeFor
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol ShareControllerEnvironment: AnyObject {
|
|
||||||
var presentationData: PresentationData { get }
|
|
||||||
var updatedPresentationData: Signal<PresentationData, NoError> { get }
|
|
||||||
var isMainApp: Bool { get }
|
|
||||||
var energyUsageSettings: EnergyUsageSettings { get }
|
|
||||||
|
|
||||||
var mediaManager: MediaManager? { get }
|
|
||||||
|
|
||||||
func setAccountUserInterfaceInUse(id: AccountRecordId) -> Disposable
|
|
||||||
func donateSendMessageIntent(account: ShareControllerAccountContext, peerIds: [EnginePeer.Id])
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class ShareControllerAppEnvironment: ShareControllerEnvironment {
|
public final class ShareControllerAppEnvironment: ShareControllerEnvironment {
|
||||||
let sharedContext: SharedAccountContext
|
let sharedContext: SharedAccountContext
|
||||||
|
|
||||||
@ -353,19 +341,6 @@ public final class ShareControllerAppEnvironment: ShareControllerEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol ShareControllerAccountContext: AnyObject {
|
|
||||||
var accountId: AccountRecordId { get }
|
|
||||||
var accountPeerId: EnginePeer.Id { get }
|
|
||||||
var stateManager: AccountStateManager { get }
|
|
||||||
var engineData: TelegramEngine.EngineData { get }
|
|
||||||
var animationCache: AnimationCache { get }
|
|
||||||
var animationRenderer: MultiAnimationRenderer { get }
|
|
||||||
var contentSettings: ContentSettings { get }
|
|
||||||
var appConfiguration: AppConfiguration { get }
|
|
||||||
|
|
||||||
func resolveInlineStickers(fileIds: [Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class ShareControllerAppAccountContext: ShareControllerAccountContext {
|
public final class ShareControllerAppAccountContext: ShareControllerAccountContext {
|
||||||
public let context: AccountContext
|
public let context: AccountContext
|
||||||
|
|
||||||
|
@ -349,7 +349,6 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate
|
|||||||
var disabledPeerSelected: ((EnginePeer) -> Void)?
|
var disabledPeerSelected: ((EnginePeer) -> Void)?
|
||||||
|
|
||||||
let ready = Promise<Bool>()
|
let ready = Promise<Bool>()
|
||||||
private var didSetReady = false
|
|
||||||
|
|
||||||
private var controllerInteraction: ShareControllerInteraction?
|
private var controllerInteraction: ShareControllerInteraction?
|
||||||
|
|
||||||
|
@ -371,6 +371,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
|
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
|
||||||
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
|
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
|
||||||
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
|
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
|
||||||
|
dict[497236696] = { return Api.InputInvoice.parse_inputInvoiceStars($0) }
|
||||||
dict[-122978821] = { return Api.InputMedia.parse_inputMediaContact($0) }
|
dict[-122978821] = { return Api.InputMedia.parse_inputMediaContact($0) }
|
||||||
dict[-428884101] = { return Api.InputMedia.parse_inputMediaDice($0) }
|
dict[-428884101] = { return Api.InputMedia.parse_inputMediaDice($0) }
|
||||||
dict[860303448] = { return Api.InputMedia.parse_inputMediaDocument($0) }
|
dict[860303448] = { return Api.InputMedia.parse_inputMediaDocument($0) }
|
||||||
@ -459,6 +460,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1551868097] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumGiftCode($0) }
|
dict[-1551868097] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumGiftCode($0) }
|
||||||
dict[369444042] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumGiveaway($0) }
|
dict[369444042] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumGiveaway($0) }
|
||||||
dict[-1502273946] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumSubscription($0) }
|
dict[-1502273946] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentPremiumSubscription($0) }
|
||||||
|
dict[1326377183] = { return Api.InputStorePaymentPurpose.parse_inputStorePaymentStars($0) }
|
||||||
dict[1012306921] = { return Api.InputTheme.parse_inputTheme($0) }
|
dict[1012306921] = { return Api.InputTheme.parse_inputTheme($0) }
|
||||||
dict[-175567375] = { return Api.InputTheme.parse_inputThemeSlug($0) }
|
dict[-175567375] = { return Api.InputTheme.parse_inputThemeSlug($0) }
|
||||||
dict[-1881255857] = { return Api.InputThemeSettings.parse_inputThemeSettings($0) }
|
dict[-1881255857] = { return Api.InputThemeSettings.parse_inputThemeSettings($0) }
|
||||||
@ -866,6 +868,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) }
|
dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) }
|
||||||
dict[-1108478618] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
dict[-1108478618] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
||||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||||
|
dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) }
|
||||||
|
dict[1939194818] = { return Api.StarsTransaction.parse_starsTransaction($0) }
|
||||||
dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
|
dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
|
||||||
dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) }
|
dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) }
|
||||||
dict[-1901828938] = { return Api.StatsGraph.parse_statsGraph($0) }
|
dict[-1901828938] = { return Api.StatsGraph.parse_statsGraph($0) }
|
||||||
@ -1030,6 +1034,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[2103604867] = { return Api.Update.parse_updateSentStoryReaction($0) }
|
dict[2103604867] = { return Api.Update.parse_updateSentStoryReaction($0) }
|
||||||
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
|
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
|
||||||
dict[-245208620] = { return Api.Update.parse_updateSmsJob($0) }
|
dict[-245208620] = { return Api.Update.parse_updateSmsJob($0) }
|
||||||
|
dict[263737752] = { return Api.Update.parse_updateStarsBalance($0) }
|
||||||
dict[834816008] = { return Api.Update.parse_updateStickerSets($0) }
|
dict[834816008] = { return Api.Update.parse_updateStickerSets($0) }
|
||||||
dict[196268545] = { return Api.Update.parse_updateStickerSetsOrder($0) }
|
dict[196268545] = { return Api.Update.parse_updateStickerSetsOrder($0) }
|
||||||
dict[738741697] = { return Api.Update.parse_updateStoriesStealthMode($0) }
|
dict[738741697] = { return Api.Update.parse_updateStoriesStealthMode($0) }
|
||||||
@ -1292,6 +1297,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) }
|
dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) }
|
||||||
dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) }
|
dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) }
|
||||||
dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
|
dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) }
|
||||||
|
dict[-1930105248] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
|
||||||
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
|
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
|
||||||
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
|
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
|
||||||
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
|
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
|
||||||
@ -1365,7 +1371,7 @@ public extension Api {
|
|||||||
return parser(reader)
|
return parser(reader)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
telegramApiLog("Type constructor \(String(UInt32(bitPattern: signature), radix: 16, uppercase: false)) not found")
|
telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1953,6 +1959,10 @@ public extension Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.SponsoredMessageReportOption:
|
case let _1 as Api.SponsoredMessageReportOption:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.StarsTopupOption:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.StarsTransaction:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.StatsAbsValueAndPrev:
|
case let _1 as Api.StatsAbsValueAndPrev:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.StatsDateRangeDays:
|
case let _1 as Api.StatsDateRangeDays:
|
||||||
@ -2303,6 +2313,8 @@ public extension Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.payments.SavedInfo:
|
case let _1 as Api.payments.SavedInfo:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.payments.StarsStatus:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.payments.ValidatedRequestedInfo:
|
case let _1 as Api.payments.ValidatedRequestedInfo:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.phone.ExportedGroupCallInvite:
|
case let _1 as Api.phone.ExportedGroupCallInvite:
|
||||||
|
@ -1,3 +1,591 @@
|
|||||||
|
public extension Api {
|
||||||
|
indirect enum InputMedia: TypeConstructorDescription {
|
||||||
|
case inputMediaContact(phoneNumber: String, firstName: String, lastName: String, vcard: String)
|
||||||
|
case inputMediaDice(emoticon: String)
|
||||||
|
case inputMediaDocument(flags: Int32, id: Api.InputDocument, ttlSeconds: Int32?, query: String?)
|
||||||
|
case inputMediaDocumentExternal(flags: Int32, url: String, ttlSeconds: Int32?)
|
||||||
|
case inputMediaEmpty
|
||||||
|
case inputMediaGame(id: Api.InputGame)
|
||||||
|
case inputMediaGeoLive(flags: Int32, geoPoint: Api.InputGeoPoint, heading: Int32?, period: Int32?, proximityNotificationRadius: Int32?)
|
||||||
|
case inputMediaGeoPoint(geoPoint: Api.InputGeoPoint)
|
||||||
|
case inputMediaInvoice(flags: Int32, title: String, description: String, photo: Api.InputWebDocument?, invoice: Api.Invoice, payload: Buffer, provider: String, providerData: Api.DataJSON, startParam: String?, extendedMedia: Api.InputMedia?)
|
||||||
|
case inputMediaPhoto(flags: Int32, id: Api.InputPhoto, ttlSeconds: Int32?)
|
||||||
|
case inputMediaPhotoExternal(flags: Int32, url: String, ttlSeconds: Int32?)
|
||||||
|
case inputMediaPoll(flags: Int32, poll: Api.Poll, correctAnswers: [Buffer]?, solution: String?, solutionEntities: [Api.MessageEntity]?)
|
||||||
|
case inputMediaStory(peer: Api.InputPeer, id: Int32)
|
||||||
|
case inputMediaUploadedDocument(flags: Int32, file: Api.InputFile, thumb: Api.InputFile?, mimeType: String, attributes: [Api.DocumentAttribute], stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
|
||||||
|
case inputMediaUploadedPhoto(flags: Int32, file: Api.InputFile, stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
|
||||||
|
case inputMediaVenue(geoPoint: Api.InputGeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String)
|
||||||
|
case inputMediaWebPage(flags: Int32, url: String)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-122978821)
|
||||||
|
}
|
||||||
|
serializeString(phoneNumber, buffer: buffer, boxed: false)
|
||||||
|
serializeString(firstName, buffer: buffer, boxed: false)
|
||||||
|
serializeString(lastName, buffer: buffer, boxed: false)
|
||||||
|
serializeString(vcard, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputMediaDice(let emoticon):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-428884101)
|
||||||
|
}
|
||||||
|
serializeString(emoticon, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputMediaDocument(let flags, let id, let ttlSeconds, let query):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(860303448)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
id.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(query!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-78455655)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(url, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaEmpty:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1771768449)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputMediaGame(let id):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-750828557)
|
||||||
|
}
|
||||||
|
id.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1759532989)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
geoPoint.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(heading!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(period!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(proximityNotificationRadius!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaGeoPoint(let geoPoint):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-104578748)
|
||||||
|
}
|
||||||
|
geoPoint.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1900697899)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(title, buffer: buffer, boxed: false)
|
||||||
|
serializeString(description, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {photo!.serialize(buffer, true)}
|
||||||
|
invoice.serialize(buffer, true)
|
||||||
|
serializeBytes(payload, buffer: buffer, boxed: false)
|
||||||
|
serializeString(provider, buffer: buffer, boxed: false)
|
||||||
|
providerData.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {extendedMedia!.serialize(buffer, true)}
|
||||||
|
break
|
||||||
|
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1279654347)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
id.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-440664550)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(url, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(261416433)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
poll.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(correctAnswers!.count))
|
||||||
|
for item in correctAnswers! {
|
||||||
|
serializeBytes(item, buffer: buffer, boxed: false)
|
||||||
|
}}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(solution!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(solutionEntities!.count))
|
||||||
|
for item in solutionEntities! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
|
break
|
||||||
|
case .inputMediaStory(let peer, let id):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1979852936)
|
||||||
|
}
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt32(id, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let ttlSeconds):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1530447553)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
file.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {thumb!.serialize(buffer, true)}
|
||||||
|
serializeString(mimeType, buffer: buffer, boxed: false)
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(attributes.count))
|
||||||
|
for item in attributes {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(stickers!.count))
|
||||||
|
for item in stickers! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(505969924)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
file.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(stickers!.count))
|
||||||
|
for item in stickers! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1052959727)
|
||||||
|
}
|
||||||
|
geoPoint.serialize(buffer, true)
|
||||||
|
serializeString(title, buffer: buffer, boxed: false)
|
||||||
|
serializeString(address, buffer: buffer, boxed: false)
|
||||||
|
serializeString(provider, buffer: buffer, boxed: false)
|
||||||
|
serializeString(venueId, buffer: buffer, boxed: false)
|
||||||
|
serializeString(venueType, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputMediaWebPage(let flags, let url):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1038383031)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(url, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
||||||
|
return ("inputMediaContact", [("phoneNumber", phoneNumber as Any), ("firstName", firstName as Any), ("lastName", lastName as Any), ("vcard", vcard as Any)])
|
||||||
|
case .inputMediaDice(let emoticon):
|
||||||
|
return ("inputMediaDice", [("emoticon", emoticon as Any)])
|
||||||
|
case .inputMediaDocument(let flags, let id, let ttlSeconds, let query):
|
||||||
|
return ("inputMediaDocument", [("flags", flags as Any), ("id", id as Any), ("ttlSeconds", ttlSeconds as Any), ("query", query as Any)])
|
||||||
|
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds):
|
||||||
|
return ("inputMediaDocumentExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any)])
|
||||||
|
case .inputMediaEmpty:
|
||||||
|
return ("inputMediaEmpty", [])
|
||||||
|
case .inputMediaGame(let id):
|
||||||
|
return ("inputMediaGame", [("id", id as Any)])
|
||||||
|
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
||||||
|
return ("inputMediaGeoLive", [("flags", flags as Any), ("geoPoint", geoPoint as Any), ("heading", heading as Any), ("period", period as Any), ("proximityNotificationRadius", proximityNotificationRadius as Any)])
|
||||||
|
case .inputMediaGeoPoint(let geoPoint):
|
||||||
|
return ("inputMediaGeoPoint", [("geoPoint", geoPoint as Any)])
|
||||||
|
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
||||||
|
return ("inputMediaInvoice", [("flags", flags as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("payload", payload as Any), ("provider", provider as Any), ("providerData", providerData as Any), ("startParam", startParam as Any), ("extendedMedia", extendedMedia as Any)])
|
||||||
|
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
||||||
|
return ("inputMediaPhoto", [("flags", flags as Any), ("id", id as Any), ("ttlSeconds", ttlSeconds as Any)])
|
||||||
|
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
||||||
|
return ("inputMediaPhotoExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any)])
|
||||||
|
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
||||||
|
return ("inputMediaPoll", [("flags", flags as Any), ("poll", poll as Any), ("correctAnswers", correctAnswers as Any), ("solution", solution as Any), ("solutionEntities", solutionEntities as Any)])
|
||||||
|
case .inputMediaStory(let peer, let id):
|
||||||
|
return ("inputMediaStory", [("peer", peer as Any), ("id", id as Any)])
|
||||||
|
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let ttlSeconds):
|
||||||
|
return ("inputMediaUploadedDocument", [("flags", flags as Any), ("file", file as Any), ("thumb", thumb as Any), ("mimeType", mimeType as Any), ("attributes", attributes as Any), ("stickers", stickers as Any), ("ttlSeconds", ttlSeconds as Any)])
|
||||||
|
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
||||||
|
return ("inputMediaUploadedPhoto", [("flags", flags as Any), ("file", file as Any), ("stickers", stickers as Any), ("ttlSeconds", ttlSeconds as Any)])
|
||||||
|
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
||||||
|
return ("inputMediaVenue", [("geoPoint", geoPoint as Any), ("title", title as Any), ("address", address as Any), ("provider", provider as Any), ("venueId", venueId as Any), ("venueType", venueType as Any)])
|
||||||
|
case .inputMediaWebPage(let flags, let url):
|
||||||
|
return ("inputMediaWebPage", [("flags", flags as Any), ("url", url as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputMediaContact(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputMedia.inputMediaContact(phoneNumber: _1!, firstName: _2!, lastName: _3!, vcard: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaDice(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputMedia.inputMediaDice(emoticon: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaDocument(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputDocument?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputDocument
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||||
|
var _4: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputMedia.inputMediaDocument(flags: _1!, id: _2!, ttlSeconds: _3, query: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaDocumentExternal(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.InputMedia.inputMediaDocumentExternal(flags: _1!, url: _2!, ttlSeconds: _3)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaEmpty(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
return Api.InputMedia.inputMediaEmpty
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaGame(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Api.InputGame?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.InputGame
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputMedia.inputMediaGame(id: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaGeoLive(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputGeoPoint?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
||||||
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
||||||
|
var _5: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||||
|
return Api.InputMedia.inputMediaGeoLive(flags: _1!, geoPoint: _2!, heading: _3, period: _4, proximityNotificationRadius: _5)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaGeoPoint(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Api.InputGeoPoint?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.InputMedia.inputMediaGeoPoint(geoPoint: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaInvoice(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: Api.InputWebDocument?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_4 = Api.parse(reader, signature: signature) as? Api.InputWebDocument
|
||||||
|
} }
|
||||||
|
var _5: Api.Invoice?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_5 = Api.parse(reader, signature: signature) as? Api.Invoice
|
||||||
|
}
|
||||||
|
var _6: Buffer?
|
||||||
|
_6 = parseBytes(reader)
|
||||||
|
var _7: String?
|
||||||
|
_7 = parseString(reader)
|
||||||
|
var _8: Api.DataJSON?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_8 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
||||||
|
}
|
||||||
|
var _9: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_9 = parseString(reader) }
|
||||||
|
var _10: Api.InputMedia?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_10 = Api.parse(reader, signature: signature) as? Api.InputMedia
|
||||||
|
} }
|
||||||
|
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
|
||||||
|
let _c7 = _7 != nil
|
||||||
|
let _c8 = _8 != nil
|
||||||
|
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
|
||||||
|
let _c10 = (Int(_1!) & Int(1 << 2) == 0) || _10 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
|
||||||
|
return Api.InputMedia.inputMediaInvoice(flags: _1!, title: _2!, description: _3!, photo: _4, invoice: _5!, payload: _6!, provider: _7!, providerData: _8!, startParam: _9, extendedMedia: _10)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaPhoto(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputPhoto?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.InputMedia.inputMediaPhoto(flags: _1!, id: _2!, ttlSeconds: _3)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaPhotoExternal(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.InputMedia.inputMediaPhotoExternal(flags: _1!, url: _2!, ttlSeconds: _3)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaPoll(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Poll?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Poll
|
||||||
|
}
|
||||||
|
var _3: [Buffer]?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: Buffer.self)
|
||||||
|
} }
|
||||||
|
var _4: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||||
|
var _5: [Api.MessageEntity]?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||||
|
} }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||||
|
return Api.InputMedia.inputMediaPoll(flags: _1!, poll: _2!, correctAnswers: _3, solution: _4, solutionEntities: _5)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaStory(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Api.InputPeer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.InputPeer
|
||||||
|
}
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputMedia.inputMediaStory(peer: _1!, id: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaUploadedDocument(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputFile?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
||||||
|
}
|
||||||
|
var _3: Api.InputFile?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.InputFile
|
||||||
|
} }
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
var _5: [Api.DocumentAttribute]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.DocumentAttribute.self)
|
||||||
|
}
|
||||||
|
var _6: [Api.InputDocument]?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
||||||
|
} }
|
||||||
|
var _7: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_7 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _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
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||||
|
return Api.InputMedia.inputMediaUploadedDocument(flags: _1!, file: _2!, thumb: _3, mimeType: _4!, attributes: _5!, stickers: _6, ttlSeconds: _7)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaUploadedPhoto(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputFile?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
||||||
|
}
|
||||||
|
var _3: [Api.InputDocument]?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
||||||
|
} }
|
||||||
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputMedia.inputMediaUploadedPhoto(flags: _1!, file: _2!, stickers: _3, ttlSeconds: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaVenue(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Api.InputGeoPoint?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
||||||
|
}
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
var _5: String?
|
||||||
|
_5 = parseString(reader)
|
||||||
|
var _6: String?
|
||||||
|
_6 = parseString(reader)
|
||||||
|
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.InputMedia.inputMediaVenue(geoPoint: _1!, title: _2!, address: _3!, provider: _4!, venueId: _5!, venueType: _6!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaWebPage(_ reader: BufferReader) -> InputMedia? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputMedia.inputMediaWebPage(flags: _1!, url: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum InputMessage: TypeConstructorDescription {
|
enum InputMessage: TypeConstructorDescription {
|
||||||
case inputMessageCallbackQuery(id: Int32, queryId: Int64)
|
case inputMessageCallbackQuery(id: Int32, queryId: Int64)
|
||||||
@ -468,323 +1056,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum InputPeerNotifySettings: TypeConstructorDescription {
|
|
||||||
case inputPeerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, sound: Api.NotificationSound?, storiesMuted: Api.Bool?, storiesHideSender: Api.Bool?, storiesSound: Api.NotificationSound?)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputPeerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound, let storiesMuted, let storiesHideSender, let storiesSound):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-892638494)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {showPreviews!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {silent!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(muteUntil!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {sound!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 6) != 0 {storiesMuted!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 7) != 0 {storiesHideSender!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 8) != 0 {storiesSound!.serialize(buffer, true)}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputPeerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound, let storiesMuted, let storiesHideSender, let storiesSound):
|
|
||||||
return ("inputPeerNotifySettings", [("flags", flags as Any), ("showPreviews", showPreviews as Any), ("silent", silent as Any), ("muteUntil", muteUntil as Any), ("sound", sound as Any), ("storiesMuted", storiesMuted as Any), ("storiesHideSender", storiesHideSender as Any), ("storiesSound", storiesSound as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputPeerNotifySettings(_ reader: BufferReader) -> InputPeerNotifySettings? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.Bool?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
|
||||||
} }
|
|
||||||
var _3: Api.Bool?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_3 = Api.parse(reader, signature: signature) as? Api.Bool
|
|
||||||
} }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
|
||||||
var _5: Api.NotificationSound?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_5 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
|
||||||
} }
|
|
||||||
var _6: Api.Bool?
|
|
||||||
if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_6 = Api.parse(reader, signature: signature) as? Api.Bool
|
|
||||||
} }
|
|
||||||
var _7: Api.Bool?
|
|
||||||
if Int(_1!) & Int(1 << 7) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_7 = Api.parse(reader, signature: signature) as? Api.Bool
|
|
||||||
} }
|
|
||||||
var _8: Api.NotificationSound?
|
|
||||||
if Int(_1!) & Int(1 << 8) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_8 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
|
||||||
} }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
|
||||||
let _c6 = (Int(_1!) & Int(1 << 6) == 0) || _6 != nil
|
|
||||||
let _c7 = (Int(_1!) & Int(1 << 7) == 0) || _7 != nil
|
|
||||||
let _c8 = (Int(_1!) & Int(1 << 8) == 0) || _8 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
|
||||||
return Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: _1!, showPreviews: _2, silent: _3, muteUntil: _4, sound: _5, storiesMuted: _6, storiesHideSender: _7, storiesSound: _8)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputPhoneCall: TypeConstructorDescription {
|
|
||||||
case inputPhoneCall(id: Int64, accessHash: Int64)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputPhoneCall(let id, let accessHash):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(506920429)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputPhoneCall(let id, let accessHash):
|
|
||||||
return ("inputPhoneCall", [("id", id as Any), ("accessHash", accessHash as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputPhoneCall(_ reader: BufferReader) -> InputPhoneCall? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputPhoneCall.inputPhoneCall(id: _1!, accessHash: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputPhoto: TypeConstructorDescription {
|
|
||||||
case inputPhoto(id: Int64, accessHash: Int64, fileReference: Buffer)
|
|
||||||
case inputPhotoEmpty
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputPhoto(let id, let accessHash, let fileReference):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1001634122)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputPhotoEmpty:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(483901197)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputPhoto(let id, let accessHash, let fileReference):
|
|
||||||
return ("inputPhoto", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any)])
|
|
||||||
case .inputPhotoEmpty:
|
|
||||||
return ("inputPhotoEmpty", [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputPhoto(_ reader: BufferReader) -> InputPhoto? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputPhoto.inputPhoto(id: _1!, accessHash: _2!, fileReference: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPhotoEmpty(_ reader: BufferReader) -> InputPhoto? {
|
|
||||||
return Api.InputPhoto.inputPhotoEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputPrivacyKey: TypeConstructorDescription {
|
|
||||||
case inputPrivacyKeyAbout
|
|
||||||
case inputPrivacyKeyAddedByPhone
|
|
||||||
case inputPrivacyKeyBirthday
|
|
||||||
case inputPrivacyKeyChatInvite
|
|
||||||
case inputPrivacyKeyForwards
|
|
||||||
case inputPrivacyKeyPhoneCall
|
|
||||||
case inputPrivacyKeyPhoneNumber
|
|
||||||
case inputPrivacyKeyPhoneP2P
|
|
||||||
case inputPrivacyKeyProfilePhoto
|
|
||||||
case inputPrivacyKeyStatusTimestamp
|
|
||||||
case inputPrivacyKeyVoiceMessages
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputPrivacyKeyAbout:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(941870144)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyAddedByPhone:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-786326563)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyBirthday:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-698740276)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyChatInvite:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1107622874)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyForwards:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1529000952)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyPhoneCall:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-88417185)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyPhoneNumber:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(55761658)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyPhoneP2P:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-610373422)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyProfilePhoto:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1461304012)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyStatusTimestamp:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1335282456)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputPrivacyKeyVoiceMessages:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1360618136)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputPrivacyKeyAbout:
|
|
||||||
return ("inputPrivacyKeyAbout", [])
|
|
||||||
case .inputPrivacyKeyAddedByPhone:
|
|
||||||
return ("inputPrivacyKeyAddedByPhone", [])
|
|
||||||
case .inputPrivacyKeyBirthday:
|
|
||||||
return ("inputPrivacyKeyBirthday", [])
|
|
||||||
case .inputPrivacyKeyChatInvite:
|
|
||||||
return ("inputPrivacyKeyChatInvite", [])
|
|
||||||
case .inputPrivacyKeyForwards:
|
|
||||||
return ("inputPrivacyKeyForwards", [])
|
|
||||||
case .inputPrivacyKeyPhoneCall:
|
|
||||||
return ("inputPrivacyKeyPhoneCall", [])
|
|
||||||
case .inputPrivacyKeyPhoneNumber:
|
|
||||||
return ("inputPrivacyKeyPhoneNumber", [])
|
|
||||||
case .inputPrivacyKeyPhoneP2P:
|
|
||||||
return ("inputPrivacyKeyPhoneP2P", [])
|
|
||||||
case .inputPrivacyKeyProfilePhoto:
|
|
||||||
return ("inputPrivacyKeyProfilePhoto", [])
|
|
||||||
case .inputPrivacyKeyStatusTimestamp:
|
|
||||||
return ("inputPrivacyKeyStatusTimestamp", [])
|
|
||||||
case .inputPrivacyKeyVoiceMessages:
|
|
||||||
return ("inputPrivacyKeyVoiceMessages", [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputPrivacyKeyAbout(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyAbout
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyAddedByPhone(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyAddedByPhone
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyBirthday(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyBirthday
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyChatInvite(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyChatInvite
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyForwards(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyForwards
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyPhoneCall(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyPhoneCall
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyPhoneNumber(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyPhoneNumber
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyPhoneP2P(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyPhoneP2P
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyProfilePhoto(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyProfilePhoto
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyStatusTimestamp(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyStatusTimestamp
|
|
||||||
}
|
|
||||||
public static func parse_inputPrivacyKeyVoiceMessages(_ reader: BufferReader) -> InputPrivacyKey? {
|
|
||||||
return Api.InputPrivacyKey.inputPrivacyKeyVoiceMessages
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,323 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum InputPeerNotifySettings: TypeConstructorDescription {
|
||||||
|
case inputPeerNotifySettings(flags: Int32, showPreviews: Api.Bool?, silent: Api.Bool?, muteUntil: Int32?, sound: Api.NotificationSound?, storiesMuted: Api.Bool?, storiesHideSender: Api.Bool?, storiesSound: Api.NotificationSound?)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputPeerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound, let storiesMuted, let storiesHideSender, let storiesSound):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-892638494)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {showPreviews!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {silent!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(muteUntil!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {sound!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 6) != 0 {storiesMuted!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 7) != 0 {storiesHideSender!.serialize(buffer, true)}
|
||||||
|
if Int(flags) & Int(1 << 8) != 0 {storiesSound!.serialize(buffer, true)}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputPeerNotifySettings(let flags, let showPreviews, let silent, let muteUntil, let sound, let storiesMuted, let storiesHideSender, let storiesSound):
|
||||||
|
return ("inputPeerNotifySettings", [("flags", flags as Any), ("showPreviews", showPreviews as Any), ("silent", silent as Any), ("muteUntil", muteUntil as Any), ("sound", sound as Any), ("storiesMuted", storiesMuted as Any), ("storiesHideSender", storiesHideSender as Any), ("storiesSound", storiesSound as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputPeerNotifySettings(_ reader: BufferReader) -> InputPeerNotifySettings? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Bool?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
} }
|
||||||
|
var _3: Api.Bool?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
} }
|
||||||
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||||
|
var _5: Api.NotificationSound?
|
||||||
|
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_5 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||||
|
} }
|
||||||
|
var _6: Api.Bool?
|
||||||
|
if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_6 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
} }
|
||||||
|
var _7: Api.Bool?
|
||||||
|
if Int(_1!) & Int(1 << 7) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_7 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||||
|
} }
|
||||||
|
var _8: Api.NotificationSound?
|
||||||
|
if Int(_1!) & Int(1 << 8) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_8 = Api.parse(reader, signature: signature) as? Api.NotificationSound
|
||||||
|
} }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||||
|
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
||||||
|
let _c6 = (Int(_1!) & Int(1 << 6) == 0) || _6 != nil
|
||||||
|
let _c7 = (Int(_1!) & Int(1 << 7) == 0) || _7 != nil
|
||||||
|
let _c8 = (Int(_1!) & Int(1 << 8) == 0) || _8 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||||
|
return Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: _1!, showPreviews: _2, silent: _3, muteUntil: _4, sound: _5, storiesMuted: _6, storiesHideSender: _7, storiesSound: _8)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum InputPhoneCall: TypeConstructorDescription {
|
||||||
|
case inputPhoneCall(id: Int64, accessHash: Int64)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputPhoneCall(let id, let accessHash):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(506920429)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputPhoneCall(let id, let accessHash):
|
||||||
|
return ("inputPhoneCall", [("id", id as Any), ("accessHash", accessHash as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputPhoneCall(_ reader: BufferReader) -> InputPhoneCall? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputPhoneCall.inputPhoneCall(id: _1!, accessHash: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum InputPhoto: TypeConstructorDescription {
|
||||||
|
case inputPhoto(id: Int64, accessHash: Int64, fileReference: Buffer)
|
||||||
|
case inputPhotoEmpty
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputPhoto(let id, let accessHash, let fileReference):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1001634122)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputPhotoEmpty:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(483901197)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputPhoto(let id, let accessHash, let fileReference):
|
||||||
|
return ("inputPhoto", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any)])
|
||||||
|
case .inputPhotoEmpty:
|
||||||
|
return ("inputPhotoEmpty", [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputPhoto(_ reader: BufferReader) -> InputPhoto? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.InputPhoto.inputPhoto(id: _1!, accessHash: _2!, fileReference: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPhotoEmpty(_ reader: BufferReader) -> InputPhoto? {
|
||||||
|
return Api.InputPhoto.inputPhotoEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum InputPrivacyKey: TypeConstructorDescription {
|
||||||
|
case inputPrivacyKeyAbout
|
||||||
|
case inputPrivacyKeyAddedByPhone
|
||||||
|
case inputPrivacyKeyBirthday
|
||||||
|
case inputPrivacyKeyChatInvite
|
||||||
|
case inputPrivacyKeyForwards
|
||||||
|
case inputPrivacyKeyPhoneCall
|
||||||
|
case inputPrivacyKeyPhoneNumber
|
||||||
|
case inputPrivacyKeyPhoneP2P
|
||||||
|
case inputPrivacyKeyProfilePhoto
|
||||||
|
case inputPrivacyKeyStatusTimestamp
|
||||||
|
case inputPrivacyKeyVoiceMessages
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputPrivacyKeyAbout:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(941870144)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyAddedByPhone:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-786326563)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyBirthday:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-698740276)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyChatInvite:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1107622874)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyForwards:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1529000952)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyPhoneCall:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-88417185)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyPhoneNumber:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(55761658)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyPhoneP2P:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-610373422)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyProfilePhoto:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1461304012)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyStatusTimestamp:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1335282456)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case .inputPrivacyKeyVoiceMessages:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1360618136)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputPrivacyKeyAbout:
|
||||||
|
return ("inputPrivacyKeyAbout", [])
|
||||||
|
case .inputPrivacyKeyAddedByPhone:
|
||||||
|
return ("inputPrivacyKeyAddedByPhone", [])
|
||||||
|
case .inputPrivacyKeyBirthday:
|
||||||
|
return ("inputPrivacyKeyBirthday", [])
|
||||||
|
case .inputPrivacyKeyChatInvite:
|
||||||
|
return ("inputPrivacyKeyChatInvite", [])
|
||||||
|
case .inputPrivacyKeyForwards:
|
||||||
|
return ("inputPrivacyKeyForwards", [])
|
||||||
|
case .inputPrivacyKeyPhoneCall:
|
||||||
|
return ("inputPrivacyKeyPhoneCall", [])
|
||||||
|
case .inputPrivacyKeyPhoneNumber:
|
||||||
|
return ("inputPrivacyKeyPhoneNumber", [])
|
||||||
|
case .inputPrivacyKeyPhoneP2P:
|
||||||
|
return ("inputPrivacyKeyPhoneP2P", [])
|
||||||
|
case .inputPrivacyKeyProfilePhoto:
|
||||||
|
return ("inputPrivacyKeyProfilePhoto", [])
|
||||||
|
case .inputPrivacyKeyStatusTimestamp:
|
||||||
|
return ("inputPrivacyKeyStatusTimestamp", [])
|
||||||
|
case .inputPrivacyKeyVoiceMessages:
|
||||||
|
return ("inputPrivacyKeyVoiceMessages", [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputPrivacyKeyAbout(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyAbout
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyAddedByPhone(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyAddedByPhone
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyBirthday(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyBirthday
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyChatInvite(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyChatInvite
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyForwards(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyForwards
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyPhoneCall(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyPhoneCall
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyPhoneNumber(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyPhoneNumber
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyPhoneP2P(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyPhoneP2P
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyProfilePhoto(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyProfilePhoto
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyStatusTimestamp(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyStatusTimestamp
|
||||||
|
}
|
||||||
|
public static func parse_inputPrivacyKeyVoiceMessages(_ reader: BufferReader) -> InputPrivacyKey? {
|
||||||
|
return Api.InputPrivacyKey.inputPrivacyKeyVoiceMessages
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum InputPrivacyRule: TypeConstructorDescription {
|
enum InputPrivacyRule: TypeConstructorDescription {
|
||||||
case inputPrivacyValueAllowAll
|
case inputPrivacyValueAllowAll
|
||||||
@ -508,355 +828,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
indirect enum InputSingleMedia: TypeConstructorDescription {
|
|
||||||
case inputSingleMedia(flags: Int32, media: Api.InputMedia, randomId: Int64, message: String, entities: [Api.MessageEntity]?)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputSingleMedia(let flags, let media, let randomId, let message, let entities):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(482797855)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
media.serialize(buffer, true)
|
|
||||||
serializeInt64(randomId, buffer: buffer, boxed: false)
|
|
||||||
serializeString(message, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(entities!.count))
|
|
||||||
for item in entities! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputSingleMedia(let flags, let media, let randomId, let message, let entities):
|
|
||||||
return ("inputSingleMedia", [("flags", flags as Any), ("media", media as Any), ("randomId", randomId as Any), ("message", message as Any), ("entities", entities as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputSingleMedia(_ reader: BufferReader) -> InputSingleMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputMedia?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputMedia
|
|
||||||
}
|
|
||||||
var _3: Int64?
|
|
||||||
_3 = reader.readInt64()
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
var _5: [Api.MessageEntity]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
|
||||||
} }
|
|
||||||
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
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputSingleMedia.inputSingleMedia(flags: _1!, media: _2!, randomId: _3!, message: _4!, entities: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputStickerSet: TypeConstructorDescription {
|
|
||||||
case inputStickerSetAnimatedEmoji
|
|
||||||
case inputStickerSetAnimatedEmojiAnimations
|
|
||||||
case inputStickerSetDice(emoticon: String)
|
|
||||||
case inputStickerSetEmojiChannelDefaultStatuses
|
|
||||||
case inputStickerSetEmojiDefaultStatuses
|
|
||||||
case inputStickerSetEmojiDefaultTopicIcons
|
|
||||||
case inputStickerSetEmojiGenericAnimations
|
|
||||||
case inputStickerSetEmpty
|
|
||||||
case inputStickerSetID(id: Int64, accessHash: Int64)
|
|
||||||
case inputStickerSetPremiumGifts
|
|
||||||
case inputStickerSetShortName(shortName: String)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickerSetAnimatedEmoji:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(42402760)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetAnimatedEmojiAnimations:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(215889721)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetDice(let emoticon):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-427863538)
|
|
||||||
}
|
|
||||||
serializeString(emoticon, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputStickerSetEmojiChannelDefaultStatuses:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1232373075)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetEmojiDefaultStatuses:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(701560302)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetEmojiDefaultTopicIcons:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1153562857)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetEmojiGenericAnimations:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(80008398)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetEmpty:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-4838507)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetID(let id, let accessHash):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1645763991)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputStickerSetPremiumGifts:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-930399486)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputStickerSetShortName(let shortName):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-2044933984)
|
|
||||||
}
|
|
||||||
serializeString(shortName, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickerSetAnimatedEmoji:
|
|
||||||
return ("inputStickerSetAnimatedEmoji", [])
|
|
||||||
case .inputStickerSetAnimatedEmojiAnimations:
|
|
||||||
return ("inputStickerSetAnimatedEmojiAnimations", [])
|
|
||||||
case .inputStickerSetDice(let emoticon):
|
|
||||||
return ("inputStickerSetDice", [("emoticon", emoticon as Any)])
|
|
||||||
case .inputStickerSetEmojiChannelDefaultStatuses:
|
|
||||||
return ("inputStickerSetEmojiChannelDefaultStatuses", [])
|
|
||||||
case .inputStickerSetEmojiDefaultStatuses:
|
|
||||||
return ("inputStickerSetEmojiDefaultStatuses", [])
|
|
||||||
case .inputStickerSetEmojiDefaultTopicIcons:
|
|
||||||
return ("inputStickerSetEmojiDefaultTopicIcons", [])
|
|
||||||
case .inputStickerSetEmojiGenericAnimations:
|
|
||||||
return ("inputStickerSetEmojiGenericAnimations", [])
|
|
||||||
case .inputStickerSetEmpty:
|
|
||||||
return ("inputStickerSetEmpty", [])
|
|
||||||
case .inputStickerSetID(let id, let accessHash):
|
|
||||||
return ("inputStickerSetID", [("id", id as Any), ("accessHash", accessHash as Any)])
|
|
||||||
case .inputStickerSetPremiumGifts:
|
|
||||||
return ("inputStickerSetPremiumGifts", [])
|
|
||||||
case .inputStickerSetShortName(let shortName):
|
|
||||||
return ("inputStickerSetShortName", [("shortName", shortName as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputStickerSetAnimatedEmoji(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetAnimatedEmoji
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetAnimatedEmojiAnimations(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetAnimatedEmojiAnimations
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetDice(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputStickerSet.inputStickerSetDice(emoticon: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetEmojiChannelDefaultStatuses(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetEmojiChannelDefaultStatuses
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetEmojiDefaultStatuses(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetEmojiDefaultStatuses
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetEmojiDefaultTopicIcons(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetEmojiDefaultTopicIcons
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetEmojiGenericAnimations(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetEmojiGenericAnimations
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetEmpty(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetEmpty
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetID(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputStickerSet.inputStickerSetID(id: _1!, accessHash: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetPremiumGifts(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
return Api.InputStickerSet.inputStickerSetPremiumGifts
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetShortName(_ reader: BufferReader) -> InputStickerSet? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputStickerSet.inputStickerSetShortName(shortName: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputStickerSetItem: TypeConstructorDescription {
|
|
||||||
case inputStickerSetItem(flags: Int32, document: Api.InputDocument, emoji: String, maskCoords: Api.MaskCoords?, keywords: String?)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickerSetItem(let flags, let document, let emoji, let maskCoords, let keywords):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(853188252)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
document.serialize(buffer, true)
|
|
||||||
serializeString(emoji, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {maskCoords!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(keywords!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickerSetItem(let flags, let document, let emoji, let maskCoords, let keywords):
|
|
||||||
return ("inputStickerSetItem", [("flags", flags as Any), ("document", document as Any), ("emoji", emoji as Any), ("maskCoords", maskCoords as Any), ("keywords", keywords as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputStickerSetItem(_ reader: BufferReader) -> InputStickerSetItem? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputDocument?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputDocument
|
|
||||||
}
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: Api.MaskCoords?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_4 = Api.parse(reader, signature: signature) as? Api.MaskCoords
|
|
||||||
} }
|
|
||||||
var _5: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputStickerSetItem.inputStickerSetItem(flags: _1!, document: _2!, emoji: _3!, maskCoords: _4, keywords: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
enum InputStickeredMedia: TypeConstructorDescription {
|
|
||||||
case inputStickeredMediaDocument(id: Api.InputDocument)
|
|
||||||
case inputStickeredMediaPhoto(id: Api.InputPhoto)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickeredMediaDocument(let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(70813275)
|
|
||||||
}
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputStickeredMediaPhoto(let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1251549527)
|
|
||||||
}
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputStickeredMediaDocument(let id):
|
|
||||||
return ("inputStickeredMediaDocument", [("id", id as Any)])
|
|
||||||
case .inputStickeredMediaPhoto(let id):
|
|
||||||
return ("inputStickeredMediaPhoto", [("id", id as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputStickeredMediaDocument(_ reader: BufferReader) -> InputStickeredMedia? {
|
|
||||||
var _1: Api.InputDocument?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputDocument
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputStickeredMedia.inputStickeredMediaDocument(id: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputStickeredMediaPhoto(_ reader: BufferReader) -> InputStickeredMedia? {
|
|
||||||
var _1: Api.InputPhoto?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputStickeredMedia.inputStickeredMediaPhoto(id: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
10698
submodules/TelegramApi/Sources/Api36.swift
Normal file
10698
submodules/TelegramApi/Sources/Api36.swift
Normal file
File diff suppressed because it is too large
Load Diff
@ -911,6 +911,7 @@ public extension Api {
|
|||||||
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
|
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
|
||||||
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
|
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
|
||||||
case inputInvoiceSlug(slug: String)
|
case inputInvoiceSlug(slug: String)
|
||||||
|
case inputInvoiceStars(option: Api.StarsTopupOption)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -934,6 +935,12 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
serializeString(slug, buffer: buffer, boxed: false)
|
serializeString(slug, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
|
case .inputInvoiceStars(let option):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(497236696)
|
||||||
|
}
|
||||||
|
option.serialize(buffer, true)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -945,6 +952,8 @@ public extension Api {
|
|||||||
return ("inputInvoicePremiumGiftCode", [("purpose", purpose as Any), ("option", option as Any)])
|
return ("inputInvoicePremiumGiftCode", [("purpose", purpose as Any), ("option", option as Any)])
|
||||||
case .inputInvoiceSlug(let slug):
|
case .inputInvoiceSlug(let slug):
|
||||||
return ("inputInvoiceSlug", [("slug", slug as Any)])
|
return ("inputInvoiceSlug", [("slug", slug as Any)])
|
||||||
|
case .inputInvoiceStars(let option):
|
||||||
|
return ("inputInvoiceStars", [("option", option as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,589 +1002,14 @@ public extension Api {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static func parse_inputInvoiceStars(_ reader: BufferReader) -> InputInvoice? {
|
||||||
}
|
var _1: Api.StarsTopupOption?
|
||||||
}
|
|
||||||
public extension Api {
|
|
||||||
indirect enum InputMedia: TypeConstructorDescription {
|
|
||||||
case inputMediaContact(phoneNumber: String, firstName: String, lastName: String, vcard: String)
|
|
||||||
case inputMediaDice(emoticon: String)
|
|
||||||
case inputMediaDocument(flags: Int32, id: Api.InputDocument, ttlSeconds: Int32?, query: String?)
|
|
||||||
case inputMediaDocumentExternal(flags: Int32, url: String, ttlSeconds: Int32?)
|
|
||||||
case inputMediaEmpty
|
|
||||||
case inputMediaGame(id: Api.InputGame)
|
|
||||||
case inputMediaGeoLive(flags: Int32, geoPoint: Api.InputGeoPoint, heading: Int32?, period: Int32?, proximityNotificationRadius: Int32?)
|
|
||||||
case inputMediaGeoPoint(geoPoint: Api.InputGeoPoint)
|
|
||||||
case inputMediaInvoice(flags: Int32, title: String, description: String, photo: Api.InputWebDocument?, invoice: Api.Invoice, payload: Buffer, provider: String, providerData: Api.DataJSON, startParam: String?, extendedMedia: Api.InputMedia?)
|
|
||||||
case inputMediaPhoto(flags: Int32, id: Api.InputPhoto, ttlSeconds: Int32?)
|
|
||||||
case inputMediaPhotoExternal(flags: Int32, url: String, ttlSeconds: Int32?)
|
|
||||||
case inputMediaPoll(flags: Int32, poll: Api.Poll, correctAnswers: [Buffer]?, solution: String?, solutionEntities: [Api.MessageEntity]?)
|
|
||||||
case inputMediaStory(peer: Api.InputPeer, id: Int32)
|
|
||||||
case inputMediaUploadedDocument(flags: Int32, file: Api.InputFile, thumb: Api.InputFile?, mimeType: String, attributes: [Api.DocumentAttribute], stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
|
|
||||||
case inputMediaUploadedPhoto(flags: Int32, file: Api.InputFile, stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
|
|
||||||
case inputMediaVenue(geoPoint: Api.InputGeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String)
|
|
||||||
case inputMediaWebPage(flags: Int32, url: String)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-122978821)
|
|
||||||
}
|
|
||||||
serializeString(phoneNumber, buffer: buffer, boxed: false)
|
|
||||||
serializeString(firstName, buffer: buffer, boxed: false)
|
|
||||||
serializeString(lastName, buffer: buffer, boxed: false)
|
|
||||||
serializeString(vcard, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaDice(let emoticon):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-428884101)
|
|
||||||
}
|
|
||||||
serializeString(emoticon, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaDocument(let flags, let id, let ttlSeconds, let query):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(860303448)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(query!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-78455655)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaEmpty:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1771768449)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputMediaGame(let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-750828557)
|
|
||||||
}
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1759532989)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(heading!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(period!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(proximityNotificationRadius!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaGeoPoint(let geoPoint):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-104578748)
|
|
||||||
}
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1900697899)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
|
||||||
serializeString(description, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {photo!.serialize(buffer, true)}
|
|
||||||
invoice.serialize(buffer, true)
|
|
||||||
serializeBytes(payload, buffer: buffer, boxed: false)
|
|
||||||
serializeString(provider, buffer: buffer, boxed: false)
|
|
||||||
providerData.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {extendedMedia!.serialize(buffer, true)}
|
|
||||||
break
|
|
||||||
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1279654347)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-440664550)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(261416433)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
poll.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(correctAnswers!.count))
|
|
||||||
for item in correctAnswers! {
|
|
||||||
serializeBytes(item, buffer: buffer, boxed: false)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(solution!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(solutionEntities!.count))
|
|
||||||
for item in solutionEntities! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
break
|
|
||||||
case .inputMediaStory(let peer, let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1979852936)
|
|
||||||
}
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1530447553)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
file.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {thumb!.serialize(buffer, true)}
|
|
||||||
serializeString(mimeType, buffer: buffer, boxed: false)
|
|
||||||
buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(attributes.count))
|
|
||||||
for item in attributes {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(stickers!.count))
|
|
||||||
for item in stickers! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(505969924)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
file.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(stickers!.count))
|
|
||||||
for item in stickers! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1052959727)
|
|
||||||
}
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
|
||||||
serializeString(address, buffer: buffer, boxed: false)
|
|
||||||
serializeString(provider, buffer: buffer, boxed: false)
|
|
||||||
serializeString(venueId, buffer: buffer, boxed: false)
|
|
||||||
serializeString(venueType, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaWebPage(let flags, let url):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1038383031)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
|
||||||
return ("inputMediaContact", [("phoneNumber", phoneNumber as Any), ("firstName", firstName as Any), ("lastName", lastName as Any), ("vcard", vcard as Any)])
|
|
||||||
case .inputMediaDice(let emoticon):
|
|
||||||
return ("inputMediaDice", [("emoticon", emoticon as Any)])
|
|
||||||
case .inputMediaDocument(let flags, let id, let ttlSeconds, let query):
|
|
||||||
return ("inputMediaDocument", [("flags", flags as Any), ("id", id as Any), ("ttlSeconds", ttlSeconds as Any), ("query", query as Any)])
|
|
||||||
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds):
|
|
||||||
return ("inputMediaDocumentExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaEmpty:
|
|
||||||
return ("inputMediaEmpty", [])
|
|
||||||
case .inputMediaGame(let id):
|
|
||||||
return ("inputMediaGame", [("id", id as Any)])
|
|
||||||
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
|
||||||
return ("inputMediaGeoLive", [("flags", flags as Any), ("geoPoint", geoPoint as Any), ("heading", heading as Any), ("period", period as Any), ("proximityNotificationRadius", proximityNotificationRadius as Any)])
|
|
||||||
case .inputMediaGeoPoint(let geoPoint):
|
|
||||||
return ("inputMediaGeoPoint", [("geoPoint", geoPoint as Any)])
|
|
||||||
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
|
||||||
return ("inputMediaInvoice", [("flags", flags as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("payload", payload as Any), ("provider", provider as Any), ("providerData", providerData as Any), ("startParam", startParam as Any), ("extendedMedia", extendedMedia as Any)])
|
|
||||||
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
|
||||||
return ("inputMediaPhoto", [("flags", flags as Any), ("id", id as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
|
||||||
return ("inputMediaPhotoExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
|
||||||
return ("inputMediaPoll", [("flags", flags as Any), ("poll", poll as Any), ("correctAnswers", correctAnswers as Any), ("solution", solution as Any), ("solutionEntities", solutionEntities as Any)])
|
|
||||||
case .inputMediaStory(let peer, let id):
|
|
||||||
return ("inputMediaStory", [("peer", peer as Any), ("id", id as Any)])
|
|
||||||
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let ttlSeconds):
|
|
||||||
return ("inputMediaUploadedDocument", [("flags", flags as Any), ("file", file as Any), ("thumb", thumb as Any), ("mimeType", mimeType as Any), ("attributes", attributes as Any), ("stickers", stickers as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
|
||||||
return ("inputMediaUploadedPhoto", [("flags", flags as Any), ("file", file as Any), ("stickers", stickers as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
|
||||||
return ("inputMediaVenue", [("geoPoint", geoPoint as Any), ("title", title as Any), ("address", address as Any), ("provider", provider as Any), ("venueId", venueId as Any), ("venueType", venueType as Any)])
|
|
||||||
case .inputMediaWebPage(let flags, let url):
|
|
||||||
return ("inputMediaWebPage", [("flags", flags as Any), ("url", url as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputMediaContact(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaContact(phoneNumber: _1!, firstName: _2!, lastName: _3!, vcard: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDice(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaDice(emoticon: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDocument(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputDocument?
|
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputDocument
|
_1 = Api.parse(reader, signature: signature) as? Api.StarsTopupOption
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
var _4: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaDocument(flags: _1!, id: _2!, ttlSeconds: _3, query: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDocumentExternal(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputMedia.inputMediaDocumentExternal(flags: _1!, url: _2!, ttlSeconds: _3)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaEmpty(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
return Api.InputMedia.inputMediaEmpty
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGame(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGame?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGame
|
|
||||||
}
|
}
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
if _c1 {
|
if _c1 {
|
||||||
return Api.InputMedia.inputMediaGame(id: _1!)
|
return Api.InputInvoice.inputInvoiceStars(option: _1!)
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGeoLive(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
|
||||||
var _5: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputMedia.inputMediaGeoLive(flags: _1!, geoPoint: _2!, heading: _3, period: _4, proximityNotificationRadius: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGeoPoint(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaGeoPoint(geoPoint: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaInvoice(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: Api.InputWebDocument?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_4 = Api.parse(reader, signature: signature) as? Api.InputWebDocument
|
|
||||||
} }
|
|
||||||
var _5: Api.Invoice?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_5 = Api.parse(reader, signature: signature) as? Api.Invoice
|
|
||||||
}
|
|
||||||
var _6: Buffer?
|
|
||||||
_6 = parseBytes(reader)
|
|
||||||
var _7: String?
|
|
||||||
_7 = parseString(reader)
|
|
||||||
var _8: Api.DataJSON?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_8 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
|
||||||
}
|
|
||||||
var _9: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_9 = parseString(reader) }
|
|
||||||
var _10: Api.InputMedia?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_10 = Api.parse(reader, signature: signature) as? Api.InputMedia
|
|
||||||
} }
|
|
||||||
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
|
|
||||||
let _c7 = _7 != nil
|
|
||||||
let _c8 = _8 != nil
|
|
||||||
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
|
|
||||||
let _c10 = (Int(_1!) & Int(1 << 2) == 0) || _10 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
|
|
||||||
return Api.InputMedia.inputMediaInvoice(flags: _1!, title: _2!, description: _3!, photo: _4, invoice: _5!, payload: _6!, provider: _7!, providerData: _8!, startParam: _9, extendedMedia: _10)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPhoto(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputPhoto?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputMedia.inputMediaPhoto(flags: _1!, id: _2!, ttlSeconds: _3)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPhotoExternal(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputMedia.inputMediaPhotoExternal(flags: _1!, url: _2!, ttlSeconds: _3)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPoll(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.Poll?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.Poll
|
|
||||||
}
|
|
||||||
var _3: [Buffer]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: Buffer.self)
|
|
||||||
} }
|
|
||||||
var _4: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
|
||||||
var _5: [Api.MessageEntity]?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
|
||||||
} }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputMedia.inputMediaPoll(flags: _1!, poll: _2!, correctAnswers: _3, solution: _4, solutionEntities: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaStory(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputPeer?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputPeer
|
|
||||||
}
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputMedia.inputMediaStory(peer: _1!, id: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaUploadedDocument(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputFile?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
}
|
|
||||||
var _3: Api.InputFile?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_3 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
} }
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
var _5: [Api.DocumentAttribute]?
|
|
||||||
if let _ = reader.readInt32() {
|
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.DocumentAttribute.self)
|
|
||||||
}
|
|
||||||
var _6: [Api.InputDocument]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
|
||||||
} }
|
|
||||||
var _7: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_7 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _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
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
|
||||||
return Api.InputMedia.inputMediaUploadedDocument(flags: _1!, file: _2!, thumb: _3, mimeType: _4!, attributes: _5!, stickers: _6, ttlSeconds: _7)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaUploadedPhoto(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputFile?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
}
|
|
||||||
var _3: [Api.InputDocument]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
|
||||||
} }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaUploadedPhoto(flags: _1!, file: _2!, stickers: _3, ttlSeconds: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaVenue(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
var _5: String?
|
|
||||||
_5 = parseString(reader)
|
|
||||||
var _6: String?
|
|
||||||
_6 = parseString(reader)
|
|
||||||
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.InputMedia.inputMediaVenue(geoPoint: _1!, title: _2!, address: _3!, provider: _4!, venueId: _5!, venueType: _6!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaWebPage(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputMedia.inputMediaWebPage(flags: _1!, url: _2!)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -128,7 +128,7 @@ enum AccountStateMutationOperation {
|
|||||||
case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction)
|
case UpdateStorySentReaction(peerId: PeerId, id: Int32, reaction: Api.Reaction)
|
||||||
case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String)
|
case UpdateNewAuthorization(isUnconfirmed: Bool, hash: Int64, date: Int32, device: String, location: String)
|
||||||
case UpdateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?)
|
case UpdateWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?)
|
||||||
case UpdateRevenueBalances(RevenueStats.Balances)
|
case UpdateRevenueBalances(peerId: PeerId, balances: RevenueStats.Balances)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HoleFromPreviousState {
|
struct HoleFromPreviousState {
|
||||||
@ -674,8 +674,8 @@ struct AccountMutableState {
|
|||||||
self.addOperation(.UpdateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date, device: device, location: location))
|
self.addOperation(.UpdateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date, device: device, location: location))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func updateRevenueBalances(_ balances: RevenueStats.Balances) {
|
mutating func updateRevenueBalances(peerId: PeerId, balances: RevenueStats.Balances) {
|
||||||
self.addOperation(.UpdateRevenueBalances(balances))
|
self.addOperation(.UpdateRevenueBalances(peerId: peerId, balances: balances))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func addOperation(_ operation: AccountStateMutationOperation) {
|
mutating func addOperation(_ operation: AccountStateMutationOperation) {
|
||||||
@ -824,7 +824,7 @@ struct AccountReplayedFinalState {
|
|||||||
let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id]
|
let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id]
|
||||||
let updateConfig: Bool
|
let updateConfig: Bool
|
||||||
let isPremiumUpdated: Bool
|
let isPremiumUpdated: Bool
|
||||||
let updatedRevenueBalances: RevenueStats.Balances?
|
let updatedRevenueBalances: [PeerId: RevenueStats.Balances]
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AccountFinalStateEvents {
|
struct AccountFinalStateEvents {
|
||||||
@ -851,13 +851,13 @@ struct AccountFinalStateEvents {
|
|||||||
let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id]
|
let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id]
|
||||||
let updateConfig: Bool
|
let updateConfig: Bool
|
||||||
let isPremiumUpdated: Bool
|
let isPremiumUpdated: Bool
|
||||||
let updatedRevenueBalances: RevenueStats.Balances?
|
let updatedRevenueBalances: [PeerId: RevenueStats.Balances]
|
||||||
|
|
||||||
var isEmpty: Bool {
|
var isEmpty: Bool {
|
||||||
return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedRevenueBalances == nil
|
return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedRevenueBalances.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set<PeerId> = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedRevenueBalances: RevenueStats.Balances? = nil) {
|
init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set<PeerId> = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedRevenueBalances: [PeerId: RevenueStats.Balances] = [:]) {
|
||||||
self.addedIncomingMessageIds = addedIncomingMessageIds
|
self.addedIncomingMessageIds = addedIncomingMessageIds
|
||||||
self.addedReactionEvents = addedReactionEvents
|
self.addedReactionEvents = addedReactionEvents
|
||||||
self.wasScheduledMessageIds = wasScheduledMessageIds
|
self.wasScheduledMessageIds = wasScheduledMessageIds
|
||||||
@ -938,6 +938,6 @@ struct AccountFinalStateEvents {
|
|||||||
|
|
||||||
let isPremiumUpdated = self.isPremiumUpdated || other.isPremiumUpdated
|
let isPremiumUpdated = self.isPremiumUpdated || other.isPremiumUpdated
|
||||||
|
|
||||||
return AccountFinalStateEvents(addedIncomingMessageIds: self.addedIncomingMessageIds + other.addedIncomingMessageIds, addedReactionEvents: self.addedReactionEvents + other.addedReactionEvents, wasScheduledMessageIds: self.wasScheduledMessageIds + other.wasScheduledMessageIds, deletedMessageIds: self.deletedMessageIds + other.deletedMessageIds, updatedTypingActivities: self.updatedTypingActivities, updatedWebpages: self.updatedWebpages, updatedCalls: self.updatedCalls + other.updatedCalls, addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData, updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants, storyUpdates: self.storyUpdates + other.storyUpdates, isContactUpdates: self.isContactUpdates + other.isContactUpdates, displayAlerts: self.displayAlerts + other.displayAlerts, dismissBotWebViews: self.dismissBotWebViews + other.dismissBotWebViews, delayNotificatonsUntil: delayNotificatonsUntil, updatedMaxMessageId: updatedMaxMessageId, updatedQts: updatedQts, externallyUpdatedPeerId: externallyUpdatedPeerId, authorizationListUpdated: authorizationListUpdated, updatedIncomingThreadReadStates: self.updatedIncomingThreadReadStates.merging(other.updatedIncomingThreadReadStates, uniquingKeysWith: { lhs, _ in lhs }), updateConfig: updateConfig, isPremiumUpdated: isPremiumUpdated, updatedRevenueBalances: self.updatedRevenueBalances != nil ? self.updatedRevenueBalances : other.updatedRevenueBalances)
|
return AccountFinalStateEvents(addedIncomingMessageIds: self.addedIncomingMessageIds + other.addedIncomingMessageIds, addedReactionEvents: self.addedReactionEvents + other.addedReactionEvents, wasScheduledMessageIds: self.wasScheduledMessageIds + other.wasScheduledMessageIds, deletedMessageIds: self.deletedMessageIds + other.deletedMessageIds, updatedTypingActivities: self.updatedTypingActivities, updatedWebpages: self.updatedWebpages, updatedCalls: self.updatedCalls + other.updatedCalls, addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData, updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants, storyUpdates: self.storyUpdates + other.storyUpdates, isContactUpdates: self.isContactUpdates + other.isContactUpdates, displayAlerts: self.displayAlerts + other.displayAlerts, dismissBotWebViews: self.dismissBotWebViews + other.dismissBotWebViews, delayNotificatonsUntil: delayNotificatonsUntil, updatedMaxMessageId: updatedMaxMessageId, updatedQts: updatedQts, externallyUpdatedPeerId: externallyUpdatedPeerId, authorizationListUpdated: authorizationListUpdated, updatedIncomingThreadReadStates: self.updatedIncomingThreadReadStates.merging(other.updatedIncomingThreadReadStates, uniquingKeysWith: { lhs, _ in lhs }), updateConfig: updateConfig, isPremiumUpdated: isPremiumUpdated, updatedRevenueBalances: self.updatedRevenueBalances.merging(other.updatedRevenueBalances, uniquingKeysWith: { lhs, _ in lhs }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1776,8 +1776,8 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||||||
updatedState.updateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date ?? 0, device: device ?? "", location: location ?? "")
|
updatedState.updateNewAuthorization(isUnconfirmed: isUnconfirmed, hash: hash, date: date ?? 0, device: device ?? "", location: location ?? "")
|
||||||
case let .updatePeerWallpaper(_, peer, wallpaper):
|
case let .updatePeerWallpaper(_, peer, wallpaper):
|
||||||
updatedState.updateWallpaper(peerId: peer.peerId, wallpaper: wallpaper.flatMap { TelegramWallpaper(apiWallpaper: $0) })
|
updatedState.updateWallpaper(peerId: peer.peerId, wallpaper: wallpaper.flatMap { TelegramWallpaper(apiWallpaper: $0) })
|
||||||
case let .updateBroadcastRevenueTransactions(_, balances):
|
case let .updateBroadcastRevenueTransactions(peer, balances):
|
||||||
updatedState.updateRevenueBalances(RevenueStats.Balances(apiRevenueBalances: balances))
|
updatedState.updateRevenueBalances(peerId: peer.peerId, balances: RevenueStats.Balances(apiRevenueBalances: balances))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -3402,7 +3402,7 @@ func replayFinalState(
|
|||||||
var deletedMessageIds: [DeletedMessageId] = []
|
var deletedMessageIds: [DeletedMessageId] = []
|
||||||
var syncAttachMenuBots = false
|
var syncAttachMenuBots = false
|
||||||
var updateConfig = false
|
var updateConfig = false
|
||||||
var updatedRevenueBalances: RevenueStats.Balances?
|
var updatedRevenueBalances: [PeerId: RevenueStats.Balances] = [:]
|
||||||
|
|
||||||
var holesFromPreviousStateMessageIds: [MessageId] = []
|
var holesFromPreviousStateMessageIds: [MessageId] = []
|
||||||
var clearHolesFromPreviousStateForChannelMessagesWithPts: [PeerIdAndMessageNamespace: Int32] = [:]
|
var clearHolesFromPreviousStateForChannelMessagesWithPts: [PeerIdAndMessageNamespace: Int32] = [:]
|
||||||
@ -4828,8 +4828,8 @@ func replayFinalState(
|
|||||||
} else {
|
} else {
|
||||||
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.NewSessionReviews, itemId: id.rawValue)
|
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.NewSessionReviews, itemId: id.rawValue)
|
||||||
}
|
}
|
||||||
case let .UpdateRevenueBalances(balances):
|
case let .UpdateRevenueBalances(peerId, balances):
|
||||||
updatedRevenueBalances = balances
|
updatedRevenueBalances[peerId] = balances
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ private final class UpdatedPeersNearbySubscriberContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class UpdatedRevenueBalancesSubscriberContext {
|
private final class UpdatedRevenueBalancesSubscriberContext {
|
||||||
let subscribers = Bag<(RevenueStats.Balances) -> Void>()
|
let subscribers = Bag<([PeerId: RevenueStats.Balances]) -> Void>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum DeletedMessageId: Hashable {
|
public enum DeletedMessageId: Hashable {
|
||||||
@ -1027,8 +1027,8 @@ public final class AccountStateManager {
|
|||||||
if let updatedPeersNearby = events.updatedPeersNearby {
|
if let updatedPeersNearby = events.updatedPeersNearby {
|
||||||
strongSelf.notifyUpdatedPeersNearby(updatedPeersNearby)
|
strongSelf.notifyUpdatedPeersNearby(updatedPeersNearby)
|
||||||
}
|
}
|
||||||
if let updatedRevenueBalances = events.updatedRevenueBalances {
|
if !events.updatedRevenueBalances.isEmpty {
|
||||||
strongSelf.notifyUpdatedRevenueBalances(updatedRevenueBalances)
|
strongSelf.notifyUpdatedRevenueBalances(events.updatedRevenueBalances)
|
||||||
}
|
}
|
||||||
if !events.updatedCalls.isEmpty {
|
if !events.updatedCalls.isEmpty {
|
||||||
for call in events.updatedCalls {
|
for call in events.updatedCalls {
|
||||||
@ -1602,7 +1602,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedRevenueBalances() -> Signal<RevenueStats.Balances, NoError> {
|
public func updatedRevenueBalances() -> Signal<[PeerId: RevenueStats.Balances], NoError> {
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
@ -1623,7 +1623,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func notifyUpdatedRevenueBalances(_ updatedRevenueBalances: RevenueStats.Balances) {
|
private func notifyUpdatedRevenueBalances(_ updatedRevenueBalances: [PeerId: RevenueStats.Balances]) {
|
||||||
for subscriber in self.updatedRevenueBalancesContext.subscribers.copyItems() {
|
for subscriber in self.updatedRevenueBalancesContext.subscribers.copyItems() {
|
||||||
subscriber(updatedRevenueBalances)
|
subscriber(updatedRevenueBalances)
|
||||||
}
|
}
|
||||||
@ -1916,7 +1916,7 @@ public final class AccountStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updatedRevenueBalances() -> Signal<RevenueStats.Balances, NoError> {
|
public func updatedRevenueBalances() -> Signal<[PeerId: RevenueStats.Balances], NoError> {
|
||||||
return self.impl.signalWith { impl, subscriber in
|
return self.impl.signalWith { impl, subscriber in
|
||||||
return impl.updatedRevenueBalances().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
|
return impl.updatedRevenueBalances().start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||||||
|
|
||||||
public class Serialization: NSObject, MTSerialization {
|
public class Serialization: NSObject, MTSerialization {
|
||||||
public func currentLayer() -> UInt {
|
public func currentLayer() -> UInt {
|
||||||
return 180
|
return 181
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parseMessage(_ data: Data!) -> Any! {
|
public func parseMessage(_ data: Data!) -> Any! {
|
||||||
|
@ -135,6 +135,7 @@ private final class RevenueStatsContextImpl {
|
|||||||
assert(Queue.mainQueue().isCurrent())
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
let account = self.account
|
let account = self.account
|
||||||
|
let peerId = self.peerId
|
||||||
let signal = requestRevenueStats(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId)
|
let signal = requestRevenueStats(postbox: self.account.postbox, network: self.account.network, peerId: self.peerId)
|
||||||
|> mapToSignal { initial -> Signal<RevenueStats?, NoError> in
|
|> mapToSignal { initial -> Signal<RevenueStats?, NoError> in
|
||||||
guard let initial else {
|
guard let initial else {
|
||||||
@ -143,8 +144,11 @@ private final class RevenueStatsContextImpl {
|
|||||||
return .single(initial)
|
return .single(initial)
|
||||||
|> then(
|
|> then(
|
||||||
account.stateManager.updatedRevenueBalances()
|
account.stateManager.updatedRevenueBalances()
|
||||||
|> map { balances in
|
|> mapToSignal { updates in
|
||||||
return initial.withUpdated(balances: balances)
|
if let balances = updates[peerId] {
|
||||||
|
return .single(initial.withUpdated(balances: balances))
|
||||||
|
}
|
||||||
|
return .complete()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ public enum AppStoreTransactionPurpose {
|
|||||||
case gift(peerId: EnginePeer.Id, currency: String, amount: Int64)
|
case gift(peerId: EnginePeer.Id, currency: String, amount: Int64)
|
||||||
case giftCode(peerIds: [EnginePeer.Id], boostPeer: EnginePeer.Id?, currency: String, amount: Int64)
|
case giftCode(peerIds: [EnginePeer.Id], boostPeer: EnginePeer.Id?, currency: String, amount: Int64)
|
||||||
case giveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32, currency: String, amount: Int64)
|
case giveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32, currency: String, amount: Int64)
|
||||||
|
case stars(count: Int64, currency: String, amount: Int64)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func apiInputStorePaymentPurpose(account: Account, purpose: AppStoreTransactionPurpose) -> Signal<Api.InputStorePaymentPurpose, NoError> {
|
private func apiInputStorePaymentPurpose(account: Account, purpose: AppStoreTransactionPurpose) -> Signal<Api.InputStorePaymentPurpose, NoError> {
|
||||||
@ -89,6 +90,8 @@ private func apiInputStorePaymentPurpose(account: Account, purpose: AppStoreTran
|
|||||||
return .single(.inputStorePaymentPremiumGiveaway(flags: flags, boostPeer: apiBoostPeer, additionalPeers: additionalPeers, countriesIso2: countries, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate, currency: currency, amount: amount))
|
return .single(.inputStorePaymentPremiumGiveaway(flags: flags, boostPeer: apiBoostPeer, additionalPeers: additionalPeers, countriesIso2: countries, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate, currency: currency, amount: amount))
|
||||||
}
|
}
|
||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
|
case let .stars(count, currency, amount):
|
||||||
|
return .single(.inputStorePaymentStars(flags: 0, stars: count, currency: currency, amount: amount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ public enum BotPaymentInvoiceSource {
|
|||||||
case slug(String)
|
case slug(String)
|
||||||
case premiumGiveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32, currency: String, amount: Int64, option: PremiumGiftCodeOption)
|
case premiumGiveaway(boostPeer: EnginePeer.Id, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32, currency: String, amount: Int64, option: PremiumGiftCodeOption)
|
||||||
case giftCode(users: [PeerId], currency: String, amount: Int64, option: PremiumGiftCodeOption)
|
case giftCode(users: [PeerId], currency: String, amount: Int64, option: PremiumGiftCodeOption)
|
||||||
|
case stars(option: StarsTopUpOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public struct BotPaymentInvoiceFields: OptionSet {
|
public struct BotPaymentInvoiceFields: OptionSet {
|
||||||
public var rawValue: Int32
|
public var rawValue: Int32
|
||||||
|
|
||||||
@ -257,8 +257,6 @@ private func _internal_parseInputInvoice(transaction: Transaction, source: BotPa
|
|||||||
|
|
||||||
return .inputInvoicePremiumGiftCode(purpose: inputPurpose, option: option)
|
return .inputInvoicePremiumGiftCode(purpose: inputPurpose, option: option)
|
||||||
case let .giftCode(users, currency, amount, option):
|
case let .giftCode(users, currency, amount, option):
|
||||||
|
|
||||||
|
|
||||||
var inputUsers: [Api.InputUser] = []
|
var inputUsers: [Api.InputUser] = []
|
||||||
if !users.isEmpty {
|
if !users.isEmpty {
|
||||||
for peerId in users {
|
for peerId in users {
|
||||||
@ -270,7 +268,6 @@ private func _internal_parseInputInvoice(transaction: Transaction, source: BotPa
|
|||||||
|
|
||||||
let inputPurpose: Api.InputStorePaymentPurpose = .inputStorePaymentPremiumGiftCode(flags: 0, users: inputUsers, boostPeer: nil, currency: currency, amount: amount)
|
let inputPurpose: Api.InputStorePaymentPurpose = .inputStorePaymentPremiumGiftCode(flags: 0, users: inputUsers, boostPeer: nil, currency: currency, amount: amount)
|
||||||
|
|
||||||
|
|
||||||
var flags: Int32 = 0
|
var flags: Int32 = 0
|
||||||
if let _ = option.storeProductId {
|
if let _ = option.storeProductId {
|
||||||
flags |= (1 << 0)
|
flags |= (1 << 0)
|
||||||
@ -282,7 +279,14 @@ private func _internal_parseInputInvoice(transaction: Transaction, source: BotPa
|
|||||||
let option: Api.PremiumGiftCodeOption = .premiumGiftCodeOption(flags: flags, users: option.users, months: option.months, storeProduct: option.storeProductId, storeQuantity: option.storeQuantity, currency: option.currency, amount: option.amount)
|
let option: Api.PremiumGiftCodeOption = .premiumGiftCodeOption(flags: flags, users: option.users, months: option.months, storeProduct: option.storeProductId, storeQuantity: option.storeQuantity, currency: option.currency, amount: option.amount)
|
||||||
|
|
||||||
return .inputInvoicePremiumGiftCode(purpose: inputPurpose, option: option)
|
return .inputInvoicePremiumGiftCode(purpose: inputPurpose, option: option)
|
||||||
|
case let .stars(option):
|
||||||
|
var flags: Int32 = 0
|
||||||
|
if let _ = option.storeProductId {
|
||||||
|
flags |= (1 << 0)
|
||||||
|
}
|
||||||
|
return .inputInvoiceStars(
|
||||||
|
option: .starsTopupOption(flags: flags, stars: option.count, storeProduct: option.storeProductId, currency: option.currency, amount: option.amount)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,6 +573,8 @@ func _internal_sendBotPaymentForm(account: Account, formId: Int64, source: BotPa
|
|||||||
}
|
}
|
||||||
case .giftCode:
|
case .giftCode:
|
||||||
receiptMessageId = nil
|
receiptMessageId = nil
|
||||||
|
case .stars:
|
||||||
|
receiptMessageId = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ public struct PremiumGiftCodeOption: Codable, Equatable {
|
|||||||
public let storeQuantity: Int32
|
public let storeQuantity: Int32
|
||||||
public let currency: String
|
public let currency: String
|
||||||
public let amount: Int64
|
public let amount: Int64
|
||||||
|
|
||||||
public init(users: Int32, months: Int32, storeProductId: String?, storeQuantity: Int32, currency: String, amount: Int64) {
|
public init(users: Int32, months: Int32, storeProductId: String?, storeQuantity: Int32, currency: String, amount: Int64) {
|
||||||
self.users = users
|
self.users = users
|
||||||
self.months = months
|
self.months = months
|
||||||
|
@ -0,0 +1,247 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
import MtProtoKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramApi
|
||||||
|
|
||||||
|
public struct StarsTopUpOption: Codable, Equatable {
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case count
|
||||||
|
case storeProductId
|
||||||
|
case currency
|
||||||
|
case amount
|
||||||
|
}
|
||||||
|
|
||||||
|
public let count: Int64
|
||||||
|
public let storeProductId: String?
|
||||||
|
public let currency: String
|
||||||
|
public let amount: Int64
|
||||||
|
|
||||||
|
public init(count: Int64, storeProductId: String?, currency: String, amount: Int64) {
|
||||||
|
self.count = count
|
||||||
|
self.storeProductId = storeProductId
|
||||||
|
self.currency = currency
|
||||||
|
self.amount = amount
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
self.count = try container.decode(Int64.self, forKey: .count)
|
||||||
|
self.storeProductId = try container.decodeIfPresent(String.self, forKey: .storeProductId)
|
||||||
|
self.currency = try container.decode(String.self, forKey: .currency)
|
||||||
|
self.amount = try container.decode(Int64.self, forKey: .amount)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(self.count, forKey: .count)
|
||||||
|
try container.encodeIfPresent(self.storeProductId, forKey: .storeProductId)
|
||||||
|
try container.encode(self.currency, forKey: .currency)
|
||||||
|
try container.encode(self.amount, forKey: .amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StarsTopUpOption {
|
||||||
|
init(apiStarsTopupOption: Api.StarsTopupOption) {
|
||||||
|
switch apiStarsTopupOption {
|
||||||
|
case let .starsTopupOption(_, stars, storeProduct, currency, amount):
|
||||||
|
self.init(count: stars, storeProductId: storeProduct, currency: currency, amount: amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func _internal_starsTopUpOptions(account: Account) -> Signal<[StarsTopUpOption], NoError> {
|
||||||
|
return account.network.request(Api.functions.payments.getStarsTopupOptions())
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<[Api.StarsTopupOption]?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
|> mapToSignal { results -> Signal<[StarsTopUpOption], NoError> in
|
||||||
|
if let results = results {
|
||||||
|
return .single(results.map { StarsTopUpOption(apiStarsTopupOption: $0) })
|
||||||
|
} else {
|
||||||
|
return .single([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct InternalStarsStatus {
|
||||||
|
let balance: Int64
|
||||||
|
let transactions: [StarsContext.State.Transaction]
|
||||||
|
let nextOffset: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestStarsState(account: Account, peerId: EnginePeer.Id, offset: String?) -> Signal<InternalStarsStatus?, NoError> {
|
||||||
|
return account.postbox.transaction { transaction -> Peer? in
|
||||||
|
return transaction.getPeer(peerId)
|
||||||
|
} |> mapToSignal { peer -> Signal<InternalStarsStatus?, NoError> in
|
||||||
|
guard let peer, let inputPeer = apiInputPeer(peer) else {
|
||||||
|
return .never()
|
||||||
|
}
|
||||||
|
|
||||||
|
let signal: Signal<Api.payments.StarsStatus, MTRpcError>
|
||||||
|
if let offset {
|
||||||
|
signal = account.network.request(Api.functions.payments.getStarsTransactions(flags: 0, peer: inputPeer, offset: offset))
|
||||||
|
} else {
|
||||||
|
signal = account.network.request(Api.functions.payments.getStarsStatus(peer: inputPeer))
|
||||||
|
}
|
||||||
|
|
||||||
|
return signal
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<Api.payments.StarsStatus?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<InternalStarsStatus?, NoError> in
|
||||||
|
guard let result else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
return account.postbox.transaction { transaction -> InternalStarsStatus? in
|
||||||
|
switch result {
|
||||||
|
case let .starsStatus(_, balance, history, nextOffset, chats, users):
|
||||||
|
let peers = AccumulatedPeers(chats: chats, users: users)
|
||||||
|
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers)
|
||||||
|
|
||||||
|
var parsedTransactions: [StarsContext.State.Transaction] = []
|
||||||
|
for entry in history {
|
||||||
|
switch entry {
|
||||||
|
case let .starsTransaction(id, stars, date, peer):
|
||||||
|
if let peer = transaction.getPeer(peer.peerId) {
|
||||||
|
parsedTransactions.append(StarsContext.State.Transaction(id: id, count: stars, date: date, peer: EnginePeer(peer)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InternalStarsStatus(balance: balance, transactions: parsedTransactions, nextOffset: nextOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class StarsContextImpl {
|
||||||
|
private let account: Account
|
||||||
|
private let peerId: EnginePeer.Id
|
||||||
|
|
||||||
|
private var _state: StarsContext.State? {
|
||||||
|
didSet {
|
||||||
|
if self._state != oldValue {
|
||||||
|
self._statePromise.set(.single(self._state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private let _statePromise = Promise<StarsContext.State?>()
|
||||||
|
var state: Signal<StarsContext.State?, NoError> {
|
||||||
|
return self._statePromise.get()
|
||||||
|
}
|
||||||
|
private var nextOffset: String?
|
||||||
|
|
||||||
|
private let disposable = MetaDisposable()
|
||||||
|
|
||||||
|
init(account: Account, peerId: EnginePeer.Id) {
|
||||||
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
|
self.account = account
|
||||||
|
self.peerId = peerId
|
||||||
|
|
||||||
|
self._state = nil
|
||||||
|
self._statePromise.set(.single(nil))
|
||||||
|
|
||||||
|
self.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
self.disposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
func load() {
|
||||||
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
|
self.disposable.set((requestStarsState(account: self.account, peerId: self.peerId, offset: nil)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||||
|
if let self {
|
||||||
|
if let status {
|
||||||
|
self._state = StarsContext.State(balance: status.balance, transactions: status.transactions)
|
||||||
|
self.nextOffset = status.nextOffset
|
||||||
|
} else {
|
||||||
|
self._state = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadMore() {
|
||||||
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
|
guard let currentState = self._state, let nextOffset = self.nextOffset else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.disposable.set((requestStarsState(account: self.account, peerId: self.peerId, offset: nextOffset)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||||
|
if let self {
|
||||||
|
if let status {
|
||||||
|
self._state = StarsContext.State(balance: status.balance, transactions: currentState.transactions + status.transactions)
|
||||||
|
self.nextOffset = status.nextOffset
|
||||||
|
} else {
|
||||||
|
self.nextOffset = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class StarsContext {
|
||||||
|
public struct State: Equatable {
|
||||||
|
public struct Transaction: Equatable {
|
||||||
|
public let id: String
|
||||||
|
public let count: Int64
|
||||||
|
public let date: Int32
|
||||||
|
public let peer: EnginePeer
|
||||||
|
|
||||||
|
init(id: String, count: Int64, date: Int32, peer: EnginePeer) {
|
||||||
|
self.id = id
|
||||||
|
self.count = count
|
||||||
|
self.date = date
|
||||||
|
self.peer = peer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public let balance: Int64
|
||||||
|
public let transactions: [Transaction]
|
||||||
|
|
||||||
|
init(balance: Int64, transactions: [Transaction]) {
|
||||||
|
self.balance = balance
|
||||||
|
self.transactions = transactions
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: State, rhs: State) -> Bool {
|
||||||
|
if lhs.balance != rhs.balance {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.transactions != rhs.transactions {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let impl: QueueLocalObject<StarsContextImpl>
|
||||||
|
|
||||||
|
public var state: Signal<StarsContext.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(account: Account, peerId: EnginePeer.Id) {
|
||||||
|
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||||
|
return StarsContextImpl(account: account, peerId: peerId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -65,5 +65,13 @@ public extension TelegramEngine {
|
|||||||
public func launchPrepaidGiveaway(peerId: EnginePeer.Id, id: Int64, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32) -> Signal<Never, LaunchPrepaidGiveawayError> {
|
public func launchPrepaidGiveaway(peerId: EnginePeer.Id, id: Int64, additionalPeerIds: [EnginePeer.Id], countries: [String], onlyNewSubscribers: Bool, showWinners: Bool, prizeDescription: String?, randomId: Int64, untilDate: Int32) -> Signal<Never, LaunchPrepaidGiveawayError> {
|
||||||
return _internal_launchPrepaidGiveaway(account: self.account, peerId: peerId, id: id, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate)
|
return _internal_launchPrepaidGiveaway(account: self.account, peerId: peerId, id: id, additionalPeerIds: additionalPeerIds, countries: countries, onlyNewSubscribers: onlyNewSubscribers, showWinners: showWinners, prizeDescription: prizeDescription, randomId: randomId, untilDate: untilDate)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public func starsTopUpOptions() -> Signal<[StarsTopUpOption], NoError> {
|
||||||
|
return _internal_starsTopUpOptions(account: self.account)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func peerStarsContext(peerId: EnginePeer.Id) -> StarsContext {
|
||||||
|
return StarsContext(account: self.account, peerId: peerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ public final class ChatBotInfoItemNode: ListViewItemNode {
|
|||||||
break
|
break
|
||||||
case .ignore:
|
case .ignore:
|
||||||
return .fail
|
return .fail
|
||||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji:
|
case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji:
|
||||||
return .waitForSingleTap
|
return .waitForSingleTap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@ public struct ChatMessageBubbleContentTapAction {
|
|||||||
public enum Content {
|
public enum Content {
|
||||||
case none
|
case none
|
||||||
case url(Url)
|
case url(Url)
|
||||||
|
case phone(String)
|
||||||
case textMention(String)
|
case textMention(String)
|
||||||
case peerMention(peerId: PeerId, mention: String, openProfile: Bool)
|
case peerMention(peerId: PeerId, mention: String, openProfile: Bool)
|
||||||
case botCommand(String)
|
case botCommand(String)
|
||||||
|
@ -770,24 +770,24 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.mainContextSourceNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtractedToContextPreview, _ in
|
self.mainContextSourceNode.willUpdateIsExtractedToContextPreview = { [weak self] isExtractedToContextPreview, _ in
|
||||||
guard let strongSelf = self, let _ = strongSelf.item else {
|
guard let self, let _ = self.item else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for contentNode in strongSelf.contentNodes {
|
for contentNode in self.contentNodes {
|
||||||
contentNode.willUpdateIsExtractedToContextPreview(isExtractedToContextPreview)
|
contentNode.willUpdateIsExtractedToContextPreview(isExtractedToContextPreview)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mainContextSourceNode.isExtractedToContextPreviewUpdated = { [weak self] isExtractedToContextPreview in
|
self.mainContextSourceNode.isExtractedToContextPreviewUpdated = { [weak self] isExtractedToContextPreview in
|
||||||
guard let strongSelf = self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.backgroundWallpaperNode.setMaskMode(strongSelf.backgroundMaskMode)
|
self.backgroundWallpaperNode.setMaskMode(self.backgroundMaskMode)
|
||||||
strongSelf.backgroundNode.setMaskMode(strongSelf.backgroundMaskMode)
|
self.backgroundNode.setMaskMode(self.backgroundMaskMode)
|
||||||
if !isExtractedToContextPreview, let (rect, size) = strongSelf.absoluteRect {
|
if !isExtractedToContextPreview, let (rect, size) = self.absoluteRect {
|
||||||
strongSelf.updateAbsoluteRect(rect, within: size)
|
self.updateAbsoluteRect(rect, within: size)
|
||||||
}
|
}
|
||||||
|
|
||||||
for contentNode in strongSelf.contentNodes {
|
for contentNode in self.contentNodes {
|
||||||
contentNode.updateIsExtractedToContextPreview(isExtractedToContextPreview)
|
contentNode.updateIsExtractedToContextPreview(isExtractedToContextPreview)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1150,15 +1150,15 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
let contentNodePoint = strongSelf.view.convert(point, to: contentNode.view)
|
let contentNodePoint = strongSelf.view.convert(point, to: contentNode.view)
|
||||||
let tapAction = contentNode.tapActionAtPoint(contentNodePoint, gesture: .tap, isEstimating: true)
|
let tapAction = contentNode.tapActionAtPoint(contentNodePoint, gesture: .tap, isEstimating: true)
|
||||||
switch tapAction.content {
|
switch tapAction.content {
|
||||||
case .none:
|
case .none:
|
||||||
if let _ = strongSelf.item?.controllerInteraction.tapMessage {
|
if let _ = strongSelf.item?.controllerInteraction.tapMessage {
|
||||||
return .waitForSingleTap
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case .ignore:
|
|
||||||
return .fail
|
|
||||||
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji:
|
|
||||||
return .waitForSingleTap
|
return .waitForSingleTap
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case .ignore:
|
||||||
|
return .fail
|
||||||
|
case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji:
|
||||||
|
return .waitForSingleTap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4600,6 +4600,16 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
item.controllerInteraction.openUrl(ChatControllerInteraction.OpenUrl(url: url.url, concealed: url.concealed, message: item.content.firstMessage, allowInlineWebpageResolution: url.allowInlineWebpageResolution, progress: tapAction.activate?()))
|
item.controllerInteraction.openUrl(ChatControllerInteraction.OpenUrl(url: url.url, concealed: url.concealed, message: item.content.firstMessage, allowInlineWebpageResolution: url.allowInlineWebpageResolution, progress: tapAction.activate?()))
|
||||||
}, contextMenuOnLongPress: !tapAction.hasLongTapAction))
|
}, contextMenuOnLongPress: !tapAction.hasLongTapAction))
|
||||||
}
|
}
|
||||||
|
case let .phone(number):
|
||||||
|
return .action(InternalBubbleTapAction.Action({ [weak self] in
|
||||||
|
guard let self, let item = self.item, let contentNode = self.contextContentNodeForPhoneNumber(number) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addSubnode(contentNode)
|
||||||
|
|
||||||
|
item.controllerInteraction.openPhoneContextMenu(ChatControllerInteraction.OpenPhone(number: number, message: item.content.firstMessage, contentNode: contentNode, messageNode: self, progress: tapAction.activate?()))
|
||||||
|
}, contextMenuOnLongPress: !tapAction.hasLongTapAction))
|
||||||
case let .peerMention(peerId, _, openProfile):
|
case let .peerMention(peerId, _, openProfile):
|
||||||
return .action(InternalBubbleTapAction.Action { [weak self] in
|
return .action(InternalBubbleTapAction.Action { [weak self] in
|
||||||
if let item = self?.item {
|
if let item = self?.item {
|
||||||
@ -4762,6 +4772,16 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
} else {
|
} else {
|
||||||
disableDefaultPressAnimation = true
|
disableDefaultPressAnimation = true
|
||||||
}
|
}
|
||||||
|
case let .phone(number):
|
||||||
|
return .action(InternalBubbleTapAction.Action({ [weak self] in
|
||||||
|
guard let self, let item = self.item, let contentNode = self.contextContentNodeForPhoneNumber(number) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addSubnode(contentNode)
|
||||||
|
|
||||||
|
item.controllerInteraction.openPhoneContextMenu(ChatControllerInteraction.OpenPhone(number: number, message: item.content.firstMessage, contentNode: contentNode, messageNode: self, progress: tapAction.activate?()))
|
||||||
|
}, contextMenuOnLongPress: !tapAction.hasLongTapAction))
|
||||||
case let .peerMention(peerId, mention, _):
|
case let .peerMention(peerId, mention, _):
|
||||||
return .action(InternalBubbleTapAction.Action {
|
return .action(InternalBubbleTapAction.Action {
|
||||||
item.controllerInteraction.longTap(.peerMention(peerId, mention), message)
|
item.controllerInteraction.longTap(.peerMention(peerId, mention), message)
|
||||||
@ -4829,6 +4849,39 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func contextContentNodeForPhoneNumber(_ number: String) -> ContextExtractedContentContainingNode? {
|
||||||
|
guard let item = self.item else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let containingNode = ContextExtractedContentContainingNode()
|
||||||
|
|
||||||
|
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
|
||||||
|
|
||||||
|
let textNode = ImmediateTextNode()
|
||||||
|
textNode.attributedText = NSAttributedString(string: number, font: Font.regular(item.presentationData.fontSize.baseDisplaySize), textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.linkTextColor : item.presentationData.theme.theme.chat.message.outgoing.linkTextColor)
|
||||||
|
let textSize = textNode.updateLayout(CGSize(width: 1000.0, height: 100.0))
|
||||||
|
|
||||||
|
let backgroundNode = ASDisplayNode()
|
||||||
|
backgroundNode.backgroundColor = (incoming ? item.presentationData.theme.theme.chat.message.incoming.bubble.withoutWallpaper.fill : item.presentationData.theme.theme.chat.message.outgoing.bubble.withoutWallpaper.fill).first ?? .black
|
||||||
|
backgroundNode.clipsToBounds = true
|
||||||
|
backgroundNode.cornerRadius = 10.0
|
||||||
|
|
||||||
|
let insets = UIEdgeInsets(top: 5.0, left: 8.0, bottom: 5.0, right: 8.0)
|
||||||
|
let backgroundSize = CGSize(width: textSize.width + insets.left + insets.right, height: textSize.height + insets.top + insets.bottom)
|
||||||
|
backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: backgroundSize)
|
||||||
|
textNode.frame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: textSize)
|
||||||
|
backgroundNode.addSubnode(textNode)
|
||||||
|
|
||||||
|
containingNode.frame = CGRect(origin: CGPoint(x: self.backgroundNode.frame.minX + 3.0, y: 1.0), size: CGSize(width: backgroundSize.width, height: backgroundSize.height + 20.0))
|
||||||
|
containingNode.contentNode.frame = CGRect(origin: .zero, size: backgroundSize)
|
||||||
|
containingNode.contentRect = CGRect(origin: .zero, size: backgroundSize)
|
||||||
|
containingNode.contentNode.addSubnode(backgroundNode)
|
||||||
|
|
||||||
|
containingNode.contentNode.alpha = 0.0
|
||||||
|
|
||||||
|
return containingNode
|
||||||
|
}
|
||||||
|
|
||||||
private func traceSelectionNodes(parent: ASDisplayNode, point: CGPoint) -> ASDisplayNode? {
|
private func traceSelectionNodes(parent: ASDisplayNode, point: CGPoint) -> ASDisplayNode? {
|
||||||
if let parent = parent as? FileMessageSelectionNode, parent.bounds.contains(point) {
|
if let parent = parent as? FileMessageSelectionNode, parent.bounds.contains(point) {
|
||||||
return parent
|
return parent
|
||||||
|
@ -857,7 +857,15 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
urlRange = urlRangeValue
|
urlRange = urlRangeValue
|
||||||
concealed = !doesUrlMatchText(url: url, text: attributeText, fullText: fullText)
|
concealed = !doesUrlMatchText(url: url, text: attributeText, fullText: fullText)
|
||||||
}
|
}
|
||||||
return ChatMessageBubbleContentTapAction(content: .url(ChatMessageBubbleContentTapAction.Url(url: url, concealed: concealed)), activate: { [weak self] in
|
|
||||||
|
var content: ChatMessageBubbleContentTapAction.Content
|
||||||
|
if url.hasPrefix("tel:") {
|
||||||
|
content = .phone(url.replacingOccurrences(of: "tel:", with: ""))
|
||||||
|
} else {
|
||||||
|
content = .url(ChatMessageBubbleContentTapAction.Url(url: url, concealed: concealed))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ChatMessageBubbleContentTapAction(content: content, activate: { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -614,6 +614,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
}, openRecommendedChannelContextMenu: { _, _, _ in
|
}, openRecommendedChannelContextMenu: { _, _, _ in
|
||||||
}, openGroupBoostInfo: { _, _ in
|
}, openGroupBoostInfo: { _, _ in
|
||||||
}, openStickerEditor: {
|
}, openStickerEditor: {
|
||||||
|
}, openPhoneContextMenu: { _ in
|
||||||
|
}, openAgeRestrictedMessageMedia: { _, _ in
|
||||||
}, playMessageEffect: { _ in
|
}, playMessageEffect: { _ in
|
||||||
}, requestMessageUpdate: { _, _ in
|
}, requestMessageUpdate: { _, _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
|
@ -148,6 +148,22 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct OpenPhone {
|
||||||
|
public var number: String
|
||||||
|
public var message: Message
|
||||||
|
public var contentNode: ContextExtractedContentContainingNode
|
||||||
|
public var messageNode: ASDisplayNode
|
||||||
|
public var progress: Promise<Bool>?
|
||||||
|
|
||||||
|
public init(number: String, message: Message, contentNode: ContextExtractedContentContainingNode, messageNode: ASDisplayNode, progress: Promise<Bool>? = nil) {
|
||||||
|
self.number = number
|
||||||
|
self.message = message
|
||||||
|
self.contentNode = contentNode
|
||||||
|
self.messageNode = messageNode
|
||||||
|
self.progress = progress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public let openMessage: (Message, OpenMessageParams) -> Bool
|
public let openMessage: (Message, OpenMessageParams) -> Bool
|
||||||
public let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void
|
public let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void
|
||||||
public let openPeerMention: (String, Promise<Bool>?) -> Void
|
public let openPeerMention: (String, Promise<Bool>?) -> Void
|
||||||
@ -242,6 +258,8 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||||||
public let openRecommendedChannelContextMenu: (EnginePeer, UIView, ContextGesture?) -> Void
|
public let openRecommendedChannelContextMenu: (EnginePeer, UIView, ContextGesture?) -> Void
|
||||||
public let openGroupBoostInfo: (EnginePeer.Id?, Int) -> Void
|
public let openGroupBoostInfo: (EnginePeer.Id?, Int) -> Void
|
||||||
public let openStickerEditor: () -> Void
|
public let openStickerEditor: () -> Void
|
||||||
|
public let openPhoneContextMenu: (OpenPhone) -> Void
|
||||||
|
public let openAgeRestrictedMessageMedia: (Message, @escaping () -> Void) -> Void
|
||||||
public let playMessageEffect: (Message) -> Void
|
public let playMessageEffect: (Message) -> Void
|
||||||
|
|
||||||
public let requestMessageUpdate: (MessageId, Bool) -> Void
|
public let requestMessageUpdate: (MessageId, Bool) -> Void
|
||||||
@ -368,6 +386,8 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||||||
openRecommendedChannelContextMenu: @escaping (EnginePeer, UIView, ContextGesture?) -> Void,
|
openRecommendedChannelContextMenu: @escaping (EnginePeer, UIView, ContextGesture?) -> Void,
|
||||||
openGroupBoostInfo: @escaping (EnginePeer.Id?, Int) -> Void,
|
openGroupBoostInfo: @escaping (EnginePeer.Id?, Int) -> Void,
|
||||||
openStickerEditor: @escaping () -> Void,
|
openStickerEditor: @escaping () -> Void,
|
||||||
|
openPhoneContextMenu: @escaping (OpenPhone) -> Void,
|
||||||
|
openAgeRestrictedMessageMedia: @escaping (Message, @escaping () -> Void) -> Void,
|
||||||
playMessageEffect: @escaping (Message) -> Void,
|
playMessageEffect: @escaping (Message) -> Void,
|
||||||
requestMessageUpdate: @escaping (MessageId, Bool) -> Void,
|
requestMessageUpdate: @escaping (MessageId, Bool) -> Void,
|
||||||
cancelInteractiveKeyboardGestures: @escaping () -> Void,
|
cancelInteractiveKeyboardGestures: @escaping () -> Void,
|
||||||
@ -474,6 +494,8 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
|
|||||||
self.openRecommendedChannelContextMenu = openRecommendedChannelContextMenu
|
self.openRecommendedChannelContextMenu = openRecommendedChannelContextMenu
|
||||||
self.openGroupBoostInfo = openGroupBoostInfo
|
self.openGroupBoostInfo = openGroupBoostInfo
|
||||||
self.openStickerEditor = openStickerEditor
|
self.openStickerEditor = openStickerEditor
|
||||||
|
self.openPhoneContextMenu = openPhoneContextMenu
|
||||||
|
self.openAgeRestrictedMessageMedia = openAgeRestrictedMessageMedia
|
||||||
self.playMessageEffect = playMessageEffect
|
self.playMessageEffect = playMessageEffect
|
||||||
|
|
||||||
self.requestMessageUpdate = requestMessageUpdate
|
self.requestMessageUpdate = requestMessageUpdate
|
||||||
|
@ -3326,6 +3326,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}, openRecommendedChannelContextMenu: { _, _, _ in
|
}, openRecommendedChannelContextMenu: { _, _, _ in
|
||||||
}, openGroupBoostInfo: { _, _ in
|
}, openGroupBoostInfo: { _, _ in
|
||||||
}, openStickerEditor: {
|
}, openStickerEditor: {
|
||||||
|
}, openPhoneContextMenu: { _ in
|
||||||
|
}, openAgeRestrictedMessageMedia: { _, _ in
|
||||||
}, playMessageEffect: { _ in
|
}, playMessageEffect: { _ in
|
||||||
}, requestMessageUpdate: { _, _ in
|
}, requestMessageUpdate: { _, _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
|
@ -493,19 +493,13 @@ public class ShareRootControllerImpl {
|
|||||||
|
|
||||||
let displayShare: () -> Void = {
|
let displayShare: () -> Void = {
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
let _ = cancelImpl
|
|
||||||
|
|
||||||
let beginShare: () -> Void = {
|
let beginShare: () -> Void = {
|
||||||
let requestUserInteraction: ([UnpreparedShareItemContent]) -> Signal<[PreparedShareItemContent], NoError> = { content in
|
let requestUserInteraction: ([UnpreparedShareItemContent]) -> Signal<[PreparedShareItemContent], NoError> = { content in
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
switch content[0] {
|
switch content[0] {
|
||||||
case let .contact(data):
|
case let .contact(data):
|
||||||
#if !DEBUG
|
let controller = deviceContactInfoController(context: context, environment: environment, subject: .filter(peer: nil, contactId: nil, contactData: data, completion: { peer, contactData in
|
||||||
//qwefqwfqwefw
|
|
||||||
#endif
|
|
||||||
let _ = data
|
|
||||||
let _ = self
|
|
||||||
/*let controller = deviceContactInfoController(context: context, subject: .filter(peer: nil, contactId: nil, contactData: data, completion: { peer, contactData in
|
|
||||||
let phone = contactData.basicData.phoneNumbers[0].value
|
let phone = contactData.basicData.phoneNumbers[0].value
|
||||||
if let vCardData = contactData.serializedVCard() {
|
if let vCardData = contactData.serializedVCard() {
|
||||||
subscriber.putNext([.media(.media(.standalone(media: TelegramMediaContact(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumber: phone, peerId: nil, vCardData: vCardData))))])
|
subscriber.putNext([.media(.media(.standalone(media: TelegramMediaContact(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumber: phone, peerId: nil, vCardData: vCardData))))])
|
||||||
@ -518,7 +512,7 @@ public class ShareRootControllerImpl {
|
|||||||
if let strongSelf = self, let window = strongSelf.mainWindow {
|
if let strongSelf = self, let window = strongSelf.mainWindow {
|
||||||
controller.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
|
controller.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
|
||||||
window.present(controller, on: .root)
|
window.present(controller, on: .root)
|
||||||
}*/
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return EmptyDisposable
|
return EmptyDisposable
|
||||||
|
@ -1762,7 +1762,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
|
|
||||||
self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
|
self.sendMessages(view: view, peer: targetPeer, messages: enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime)
|
||||||
} else {
|
} else {
|
||||||
let contactController = component.context.sharedContext.makeDeviceContactInfoController(context: component.context, subject: .filter(peer: peerAndContactData.0?._asPeer(), contactId: nil, contactData: contactData, completion: { [weak self, weak view] peer, contactData in
|
let contactController = component.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: component.context), environment: ShareControllerAppEnvironment(sharedContext: component.context.sharedContext), subject: .filter(peer: peerAndContactData.0?._asPeer(), contactId: nil, contactData: contactData, completion: { [weak self, weak view] peer, contactData in
|
||||||
guard let self, let view else {
|
guard let self, let view else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"filename" : "ic_lt_adduser.pdf",
|
||||||
"filename" : "ic_lt_adduser.pdf"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeMark.imageset/18on_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeMark.imageset/18on_24.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeMark.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeMark.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "18on_24.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeUnmark.imageset/18off_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeUnmark.imageset/18off_24.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeUnmark.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AgeUnmark.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "18off_24.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Telegram.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Telegram.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "tlogo_24.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Telegram.imageset/tlogo_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Context Menu/Telegram.imageset/tlogo_24.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Chat/Message/AgeRestricted.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Message/AgeRestricted.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "eyeoff_30.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
143
submodules/TelegramUI/Images.xcassets/Chat/Message/AgeRestricted.imageset/eyeoff_30.pdf
vendored
Normal file
143
submodules/TelegramUI/Images.xcassets/Chat/Message/AgeRestricted.imageset/eyeoff_30.pdf
vendored
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<< /Filter /FlateDecode
|
||||||
|
/Type /XObject
|
||||||
|
/Length 2 0 R
|
||||||
|
/Group << /Type /Group
|
||||||
|
/S /Transparency
|
||||||
|
>>
|
||||||
|
/Subtype /Form
|
||||||
|
/Resources << >>
|
||||||
|
/BBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
xm•Í®E…÷ý½F¢R¶Ë.×<16>X<03>0
|
||||||
|
é&ŠÄóçs§§§ós7S÷Œ<C592><7F>=ï~{ÿÿ¿<C3BF>÷þþËþë_Û»×<C397>OÛ›´~üíýùøùz]ßY±Ôrmtµ1öLJí2ûþñéñ‘À™ÃÄwm¹¨ôý`äên»x“c*Ilê˜d»A2§ö¼¹>H·RÖˆ§û“|/hز ÙÍUÇ<55>®¸Vä/h‚o‰°j•ªà,ïñYm\®Ä‹ÖçòYñžyoÐYÝÝõêBŒ¬kЧî)g)ÝWˆÀ¯›çht–Ùwokyï« ìêš{´%@^ñf“è±rŸÄ›šP4"ø:yøÐQ®3,`¶˜´v¸Òk'žôJ†å.ÚVg¸NŠ‹[<5B>äËzl“QÛ ·H¸‰'®ÚÒdRSµ3R±Ò¦«Ï.¸þ@oÛ?›·¹¬;#;ŠŽD/ÙÌ^PĘALyFæš`<60>‡UŸg…Ù–¥Èâq"ëKuFÞF|"9zsff1@L‘J!+3"?ƒ•Â
|
||||||
|
À<EFBFBD><EFBFBD>µ„èrÄ/ä±–Bˆƒg
|
||||||
|
fD¡jR\Ðl^VEîÄ(R<>U&£cøS‚9÷b×X·€\QúÀUÚ¢(-ƒ]ƒ}Ÿ64jF"¬r¦ˆæ¡s¢¯º—r<E28094>¤ë:éðZÑ'ÄW¶²¼ð‚J$c9R¸<52>dc(p
|
||||||
|
F7¨þÁàè<>}[,m<>þ”l<E2809D>œW/š- U±±±jQYEéE7‹Òä´ôtZ{lƒÆQb
ƒur¼<72>‘Ö¼Ñ;wm™T5t ¬Æ…Ü8¹0ÎJLgGYV˜¶:”‡ÜJ"'R‚ t¥œCƒ£QWA<57>õ
·¥ÌÏèì<C3A8>"C ËÁ5Xôæ“ÕwªÇéÚr@4;´äVsyÒ}–Áî>‘*¿Ž
T\<ù“†4i¨.«z&‘n§¦~Ö2pqžš‚ÒÕjáÎSƒç7c«aB<61>-zÀ5{@:ÃDµsvw0‚)tDƒaÉ'_u-<2D>K†¤b#9›µ<E280BA>\}áHS:Òu(–û\…X¤Ï¨Š!U—…\”͉”BµsëÊžXUŠUí…NJ¾<4A>›nXDvÄVˆÕ]§›A…|Ýs1ñ÷OÛÇí<C387>í3Ü|¨
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
868
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
<< /Type /XObject
|
||||||
|
/Length 4 0 R
|
||||||
|
/Group << /Type /Group
|
||||||
|
/S /Transparency
|
||||||
|
>>
|
||||||
|
/Subtype /Form
|
||||||
|
/Resources << >>
|
||||||
|
/BBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
/DeviceRGB CS
|
||||||
|
/DeviceRGB cs
|
||||||
|
q
|
||||||
|
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
|
||||||
|
0.000000 0.000000 0.000000 scn
|
||||||
|
0.000000 12.800001 m
|
||||||
|
0.000000 16.720367 0.000000 18.680552 0.762954 20.177933 c
|
||||||
|
1.434068 21.495068 2.504932 22.565931 3.822066 23.237045 c
|
||||||
|
5.319448 24.000000 7.279633 24.000000 11.200000 24.000000 c
|
||||||
|
12.800001 24.000000 l
|
||||||
|
16.720367 24.000000 18.680552 24.000000 20.177933 23.237045 c
|
||||||
|
21.495068 22.565931 22.565931 21.495068 23.237045 20.177933 c
|
||||||
|
24.000000 18.680552 24.000000 16.720367 24.000000 12.800000 c
|
||||||
|
24.000000 11.199999 l
|
||||||
|
24.000000 7.279633 24.000000 5.319448 23.237045 3.822067 c
|
||||||
|
22.565931 2.504932 21.495068 1.434069 20.177933 0.762955 c
|
||||||
|
18.680552 0.000000 16.720367 0.000000 12.800000 0.000000 c
|
||||||
|
11.199999 0.000000 l
|
||||||
|
7.279632 0.000000 5.319448 0.000000 3.822066 0.762955 c
|
||||||
|
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
|
||||||
|
0.000000 5.319448 0.000000 7.279633 0.000000 11.200000 c
|
||||||
|
0.000000 12.800001 l
|
||||||
|
h
|
||||||
|
f
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
944
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<< /XObject << /X1 1 0 R >>
|
||||||
|
/ExtGState << /E1 << /SMask << /Type /Mask
|
||||||
|
/G 3 0 R
|
||||||
|
/S /Alpha
|
||||||
|
>>
|
||||||
|
/Type /ExtGState
|
||||||
|
>> >>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<< /Length 7 0 R >>
|
||||||
|
stream
|
||||||
|
/DeviceRGB CS
|
||||||
|
/DeviceRGB cs
|
||||||
|
q
|
||||||
|
/E1 gs
|
||||||
|
/X1 Do
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
7 0 obj
|
||||||
|
46
|
||||||
|
endobj
|
||||||
|
|
||||||
|
8 0 obj
|
||||||
|
<< /Annots []
|
||||||
|
/Type /Page
|
||||||
|
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||||
|
/Resources 5 0 R
|
||||||
|
/Contents 6 0 R
|
||||||
|
/Parent 9 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
9 0 obj
|
||||||
|
<< /Kids [ 8 0 R ]
|
||||||
|
/Count 1
|
||||||
|
/Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
10 0 obj
|
||||||
|
<< /Pages 9 0 R
|
||||||
|
/Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 11
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000010 00000 n
|
||||||
|
0000001152 00000 n
|
||||||
|
0000001174 00000 n
|
||||||
|
0000002366 00000 n
|
||||||
|
0000002388 00000 n
|
||||||
|
0000002686 00000 n
|
||||||
|
0000002788 00000 n
|
||||||
|
0000002809 00000 n
|
||||||
|
0000002982 00000 n
|
||||||
|
0000003056 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID [ (some) (id) ]
|
||||||
|
/Root 10 0 R
|
||||||
|
/Size 11
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
3116
|
||||||
|
%%EOF
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
},
|
},
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"provides-namespace" : true
|
"provides-namespace" : true
|
||||||
|
12
submodules/TelegramUI/Images.xcassets/Components/Search Bar/Hashtag.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Components/Search Bar/Hashtag.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "tagsearch_24.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Components/Search Bar/Hashtag.imageset/tagsearch_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Components/Search Bar/Hashtag.imageset/tagsearch_24.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Premium/Mock.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/Mock.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "mock.png",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Premium/Mock.imageset/mock.png
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Premium/Mock.imageset/mock.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
12
submodules/TelegramUI/Images.xcassets/Premium/Mock2.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Premium/Mock2.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Mock2.png",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Premium/Mock2.imageset/Mock2.png
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Premium/Mock2.imageset/Mock2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
@ -0,0 +1,241 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import Display
|
||||||
|
import TelegramNotices
|
||||||
|
import ContextUI
|
||||||
|
import AccountContext
|
||||||
|
import ChatMessageItemView
|
||||||
|
import ChatMessageItemCommon
|
||||||
|
import AvatarNode
|
||||||
|
import UndoUI
|
||||||
|
import MessageUI
|
||||||
|
import PeerInfoUI
|
||||||
|
|
||||||
|
extension ChatControllerImpl: MFMessageComposeViewControllerDelegate {
|
||||||
|
func openPhoneContextMenu(number: String, peer: EnginePeer?, message: Message, contentNode: ContextExtractedContentContainingNode, messageNode: ASDisplayNode, frame: CGRect, anyRecognizer: UIGestureRecognizer?, location: CGPoint?) -> Void {
|
||||||
|
if self.presentationInterfaceState.interfaceState.selectionState != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dismissAllTooltips()
|
||||||
|
|
||||||
|
let recognizer: TapLongTapOrDoubleTapGestureRecognizer? = anyRecognizer as? TapLongTapOrDoubleTapGestureRecognizer
|
||||||
|
let gesture: ContextGesture? = anyRecognizer as? ContextGesture
|
||||||
|
|
||||||
|
if let messages = self.chatDisplayNode.historyNode.messageGroupInCurrentHistoryView(message.id) {
|
||||||
|
(self.view.window as? WindowHost)?.cancelInteractiveKeyboardGestures()
|
||||||
|
self.chatDisplayNode.cancelInteractiveKeyboardGestures()
|
||||||
|
var updatedMessages = messages
|
||||||
|
for i in 0 ..< updatedMessages.count {
|
||||||
|
if updatedMessages[i].id == message.id {
|
||||||
|
let message = updatedMessages.remove(at: i)
|
||||||
|
updatedMessages.insert(message, at: 0)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()
|
||||||
|
|
||||||
|
let source: ContextContentSource
|
||||||
|
if let location = location {
|
||||||
|
source = .location(ChatMessageContextLocationContentSource(controller: self, location: messageNode.view.convert(messageNode.bounds, to: nil).origin.offsetBy(dx: location.x, dy: location.y)))
|
||||||
|
} else {
|
||||||
|
source = .extracted(ChatMessagePhoneContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode))
|
||||||
|
// source = .extracted(ChatMessageContextExtractedContentSource(chatController: self, chatNode: self.chatDisplayNode, engine: self.context.engine, message: message, selectAll: false))
|
||||||
|
}
|
||||||
|
|
||||||
|
var items: [ContextMenuItem] = []
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_AddToContacts, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddUser"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in
|
||||||
|
guard let self, let c else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let basicData = DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [
|
||||||
|
DeviceContactPhoneNumberData(label: "", value: number)
|
||||||
|
])
|
||||||
|
let contactData = DeviceContactExtendedData(basicData: basicData, middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||||
|
|
||||||
|
pushContactContextOptionsController(context: self.context, contextController: c, presentationData: self.presentationData, peer: nil, contactData: contactData, parentController: self, push: { [weak self] c in
|
||||||
|
self?.push(c)
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
items.append(.separator)
|
||||||
|
if let peer {
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_SendMessage, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MessageBubble"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_TelegramVoiceCall, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Call"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.controllerInteraction?.callPeer(peer.id, false)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_TelegramVideoCall, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/VideoCall"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.controllerInteraction?.callPeer(peer.id, true)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_InviteToTelegram, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Telegram"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.inviteToTelegram(numbers: [number])
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if number.hasPrefix("+888") {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_CallViaCarrier, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/PhoneCall"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.openUrl("tel:\(number)", concealed: false)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_CopyNumber, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
UIPasteboard.general.string = number
|
||||||
|
|
||||||
|
self.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: presentationData.strings.Conversation_PhoneCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
|
items.append(.separator)
|
||||||
|
if let peer {
|
||||||
|
let avatarSize = CGSize(width: 28.0, height: 28.0)
|
||||||
|
let avatarSignal = peerAvatarCompleteImage(account: self.context.account, peer: peer, size: avatarSize)
|
||||||
|
|
||||||
|
let subtitle = NSMutableAttributedString(string: self.presentationData.strings.Chat_Context_Phone_ViewProfile + " >")
|
||||||
|
if let range = subtitle.string.range(of: ">"), let arrowImage = UIImage(bundleImageName: "Item List/InlineTextRightArrow") {
|
||||||
|
subtitle.addAttribute(.attachment, value: arrowImage, range: NSRange(range, in: subtitle.string))
|
||||||
|
subtitle.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: subtitle.string))
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: peer.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder), textLayout: .secondLineWithAttributedValue(subtitle), icon: { theme in return nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: avatarSignal), iconPosition: .left, action: { [weak self] _, f in
|
||||||
|
f(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.openPeer(peer: peer, navigation: .info(nil), fromMessage: nil)
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let emptyAction: ((ContextMenuActionItem.Action) -> Void)? = nil
|
||||||
|
items.append(
|
||||||
|
.action(ContextMenuActionItem(text: self.presentationData.strings.Chat_Context_Phone_NotOnTelegram, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: emptyAction))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.canReadHistory.set(false)
|
||||||
|
|
||||||
|
let controller = ContextController(presentationData: self.presentationData, source: source, items: .single(ContextController.Items(content: .list(items))), recognizer: recognizer, gesture: gesture, disableScreenshots: false)
|
||||||
|
controller.dismissed = { [weak self] in
|
||||||
|
self?.canReadHistory.set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window?.presentInGlobalOverlay(controller)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func inviteToTelegram(numbers: [String]) {
|
||||||
|
if MFMessageComposeViewController.canSendText() {
|
||||||
|
let composer = MFMessageComposeViewController()
|
||||||
|
composer.messageComposeDelegate = self
|
||||||
|
composer.recipients = Array(Set(numbers))
|
||||||
|
let url = self.presentationData.strings.InviteText_URL
|
||||||
|
let body = self.presentationData.strings.InviteText_SingleContact(url).string
|
||||||
|
composer.body = body
|
||||||
|
self.messageComposeController = composer
|
||||||
|
if let window = self.view.window {
|
||||||
|
window.rootViewController?.present(composer, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
|
||||||
|
self.messageComposeController = nil
|
||||||
|
|
||||||
|
controller.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ChatMessagePhoneContextExtractedContentSource: ContextExtractedContentSource {
|
||||||
|
let keepInPlace: Bool = false
|
||||||
|
let ignoreContentTouches: Bool = true
|
||||||
|
let blurBackground: Bool = true
|
||||||
|
let adjustContentHorizontally = true
|
||||||
|
|
||||||
|
private weak var chatNode: ChatControllerNode?
|
||||||
|
private let contentNode: ContextExtractedContentContainingNode
|
||||||
|
|
||||||
|
var shouldBeDismissed: Signal<Bool, NoError> {
|
||||||
|
return .single(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(chatNode: ChatControllerNode, contentNode: ContextExtractedContentContainingNode) {
|
||||||
|
self.chatNode = chatNode
|
||||||
|
self.contentNode = contentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func takeView() -> ContextControllerTakeViewInfo? {
|
||||||
|
guard let chatNode = self.chatNode else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
|
||||||
|
transition.updateAlpha(node: self.contentNode.contentNode, alpha: 1.0)
|
||||||
|
|
||||||
|
return ContextControllerTakeViewInfo(containingItem: .node(self.contentNode), contentAreaInScreenSpace: chatNode.convert(chatNode.frameForVisibleArea(), to: nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func putBack() -> ContextControllerPutBackViewInfo? {
|
||||||
|
guard let chatNode = self.chatNode else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
|
||||||
|
transition.updateAlpha(node: self.contentNode.contentNode, alpha: 0.0, completion: { _ in
|
||||||
|
self.contentNode.removeFromSupernode()
|
||||||
|
})
|
||||||
|
|
||||||
|
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: chatNode.convert(chatNode.frameForVisibleArea(), to: nil))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,303 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import Display
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
import TelegramUIPreferences
|
||||||
|
import AccountContext
|
||||||
|
import AppBundle
|
||||||
|
import AvatarNode
|
||||||
|
import CheckNode
|
||||||
|
import Markdown
|
||||||
|
|
||||||
|
private let textFont = Font.regular(13.0)
|
||||||
|
private let boldTextFont = Font.semibold(13.0)
|
||||||
|
|
||||||
|
private func formattedText(_ text: String, color: UIColor, textAlignment: NSTextAlignment = .natural) -> NSAttributedString {
|
||||||
|
return parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: color), bold: MarkdownAttributeSet(font: boldTextFont, textColor: color), link: MarkdownAttributeSet(font: textFont, textColor: color), linkAttribute: { _ in return nil}), textAlignment: textAlignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ChatAgeRestrictionAlertContentNode: AlertContentNode {
|
||||||
|
private let strings: PresentationStrings
|
||||||
|
private let title: String
|
||||||
|
private let text: String
|
||||||
|
|
||||||
|
private let titleNode: ImmediateTextNode
|
||||||
|
private let textNode: ASTextNode
|
||||||
|
|
||||||
|
private let alwaysCheckNode: InteractiveCheckNode
|
||||||
|
private let alwaysLabelNode: ASTextNode
|
||||||
|
|
||||||
|
private let actionNodesSeparator: ASDisplayNode
|
||||||
|
private let actionNodes: [TextAlertContentActionNode]
|
||||||
|
private let actionVerticalSeparators: [ASDisplayNode]
|
||||||
|
|
||||||
|
private var validLayout: CGSize?
|
||||||
|
|
||||||
|
override var dismissOnOutsideTap: Bool {
|
||||||
|
return self.isUserInteractionEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
var alwaysShow: Bool = false {
|
||||||
|
didSet {
|
||||||
|
self.alwaysCheckNode.setSelected(self.alwaysShow, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(context: AccountContext, theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, title: String, text: String, actions: [TextAlertAction]) {
|
||||||
|
self.strings = strings
|
||||||
|
self.title = title
|
||||||
|
self.text = text
|
||||||
|
|
||||||
|
self.titleNode = ImmediateTextNode()
|
||||||
|
self.titleNode.displaysAsynchronously = false
|
||||||
|
self.titleNode.maximumNumberOfLines = 1
|
||||||
|
self.titleNode.textAlignment = .center
|
||||||
|
|
||||||
|
self.textNode = ASTextNode()
|
||||||
|
self.textNode.displaysAsynchronously = false
|
||||||
|
self.textNode.maximumNumberOfLines = 0
|
||||||
|
self.textNode.lineSpacing = 0.1
|
||||||
|
|
||||||
|
self.alwaysCheckNode = InteractiveCheckNode(theme: CheckNodeTheme(backgroundColor: theme.accentColor, strokeColor: theme.contrastColor, borderColor: theme.controlBorderColor, overlayBorder: false, hasInset: false, hasShadow: false))
|
||||||
|
self.alwaysLabelNode = ASTextNode()
|
||||||
|
self.alwaysLabelNode.maximumNumberOfLines = 2
|
||||||
|
self.alwaysLabelNode.isUserInteractionEnabled = 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.alwaysCheckNode)
|
||||||
|
self.addSubnode(self.alwaysLabelNode)
|
||||||
|
|
||||||
|
|
||||||
|
self.addSubnode(self.actionNodesSeparator)
|
||||||
|
|
||||||
|
for actionNode in self.actionNodes {
|
||||||
|
self.addSubnode(actionNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
for separatorNode in self.actionVerticalSeparators {
|
||||||
|
self.addSubnode(separatorNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.alwaysCheckNode.valueChanged = { [weak self] value in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.alwaysShow = !strongSelf.alwaysShow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateTheme(theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
self.alwaysLabelNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.alwaysTap(_:))))
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func alwaysTap(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||||
|
if self.alwaysCheckNode.isUserInteractionEnabled {
|
||||||
|
self.alwaysShow = !self.alwaysShow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.alwaysLabelNode.attributedText = formattedText("Always show 18+ media", color: theme.primaryColor)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.validLayout = size
|
||||||
|
|
||||||
|
var origin: CGPoint = CGPoint(x: 0.0, y: 17.0)
|
||||||
|
|
||||||
|
let titleSize = self.titleNode.updateLayout(CGSize(width: size.width - 32.0, height: size.height))
|
||||||
|
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 + 6.0
|
||||||
|
|
||||||
|
var entriesHeight: CGFloat = 0.0
|
||||||
|
|
||||||
|
let textSize = self.textNode.measure(CGSize(width: size.width - 32.0, height: size.height))
|
||||||
|
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
|
||||||
|
|
||||||
|
if self.alwaysLabelNode.supernode != nil {
|
||||||
|
origin.y += 21.0
|
||||||
|
entriesHeight += 21.0
|
||||||
|
|
||||||
|
let checkSize = CGSize(width: 22.0, height: 22.0)
|
||||||
|
let condensedSize = CGSize(width: size.width - 76.0, height: size.height)
|
||||||
|
|
||||||
|
let alwaysSize = self.alwaysLabelNode.measure(condensedSize)
|
||||||
|
let totalWidth = checkSize.width + alwaysSize.width + 12.0
|
||||||
|
let originX = floorToScreenPixels((size.width - totalWidth) / 2.0)
|
||||||
|
transition.updateFrame(node: self.alwaysLabelNode, frame: CGRect(origin: CGPoint(x: originX + checkSize.width + 12.0, y: origin.y), size: alwaysSize))
|
||||||
|
transition.updateFrame(node: self.alwaysCheckNode, frame: CGRect(origin: CGPoint(x: originX, y: origin.y - 2.0), size: checkSize))
|
||||||
|
origin.y += alwaysSize.height
|
||||||
|
entriesHeight += alwaysSize.height
|
||||||
|
}
|
||||||
|
|
||||||
|
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.vertical
|
||||||
|
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: 18.0, right: 18.0)
|
||||||
|
|
||||||
|
let contentWidth = max(size.width, minActionsWidth)
|
||||||
|
|
||||||
|
var actionsHeight: CGFloat = 0.0
|
||||||
|
switch effectiveActionLayout {
|
||||||
|
case .horizontal:
|
||||||
|
actionsHeight = actionButtonHeight
|
||||||
|
case .vertical:
|
||||||
|
actionsHeight = actionButtonHeight * CGFloat(self.actionNodes.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
let resultSize = CGSize(width: contentWidth, height: titleSize.height + textSize.height + entriesHeight + actionsHeight + 8.0 + 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 chatAgeRestrictionAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, completion: @escaping (Bool) -> Void) -> AlertController {
|
||||||
|
let theme = defaultDarkColorPresentationTheme
|
||||||
|
let presentationData: PresentationData
|
||||||
|
if let updatedPresentationData {
|
||||||
|
presentationData = updatedPresentationData.initial
|
||||||
|
} else {
|
||||||
|
presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
}
|
||||||
|
let strings = presentationData.strings
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
|
var getContentNodeImpl: (() -> ChatAgeRestrictionAlertContentNode?)?
|
||||||
|
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: "View Anyway", action: {
|
||||||
|
if let alwaysShow = getContentNodeImpl?()?.alwaysShow {
|
||||||
|
completion(alwaysShow)
|
||||||
|
} else {
|
||||||
|
completion(false)
|
||||||
|
}
|
||||||
|
dismissImpl?(true)
|
||||||
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
dismissImpl?(true)
|
||||||
|
})]
|
||||||
|
|
||||||
|
let title = "18+ Content"
|
||||||
|
let text = "This media may contain sensitive content suitable only for adults.\nDo you still want to view it?"
|
||||||
|
|
||||||
|
let contentNode = ChatAgeRestrictionAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, actions: actions)
|
||||||
|
getContentNodeImpl = { [weak contentNode] in
|
||||||
|
return contentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||||
|
dismissImpl = { [weak controller] animated in
|
||||||
|
if animated {
|
||||||
|
controller?.dismissAnimated()
|
||||||
|
} else {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
@ -123,6 +123,7 @@ import PeerNameColorScreen
|
|||||||
import ChatEmptyNode
|
import ChatEmptyNode
|
||||||
import ChatMediaInputStickerGridItem
|
import ChatMediaInputStickerGridItem
|
||||||
import AdsInfoScreen
|
import AdsInfoScreen
|
||||||
|
import MessageUI
|
||||||
|
|
||||||
public enum ChatControllerPeekActions {
|
public enum ChatControllerPeekActions {
|
||||||
case standard
|
case standard
|
||||||
@ -224,6 +225,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
var validLayout: ContainerViewLayout?
|
var validLayout: ContainerViewLayout?
|
||||||
|
|
||||||
public weak var parentController: ViewController?
|
public weak var parentController: ViewController?
|
||||||
|
public weak var customNavigationController: NavigationController?
|
||||||
|
|
||||||
let currentChatListFilter: Int32?
|
let currentChatListFilter: Int32?
|
||||||
let chatNavigationStack: [ChatNavigationStackItem]
|
let chatNavigationStack: [ChatNavigationStackItem]
|
||||||
@ -593,6 +595,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
var networkSpeedEventsDisposable: Disposable?
|
var networkSpeedEventsDisposable: Disposable?
|
||||||
|
|
||||||
|
var messageComposeController: MFMessageComposeViewController?
|
||||||
|
|
||||||
public var alwaysShowSearchResultsAsList: Bool = false {
|
public var alwaysShowSearchResultsAsList: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
self.presentationInterfaceState = self.presentationInterfaceState.updatedDisplayHistoryFilterAsList(self.alwaysShowSearchResultsAsList)
|
self.presentationInterfaceState = self.presentationInterfaceState.updatedDisplayHistoryFilterAsList(self.alwaysShowSearchResultsAsList)
|
||||||
@ -2295,27 +2299,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, openUrl: { [weak self] urlData in
|
}, openUrl: { [weak self] urlData in
|
||||||
if let strongSelf = self {
|
guard let strongSelf = self else {
|
||||||
let url = urlData.url
|
return
|
||||||
let concealed = urlData.concealed
|
}
|
||||||
let message = urlData.message
|
let url = urlData.url
|
||||||
let progress = urlData.progress
|
let concealed = urlData.concealed
|
||||||
let forceExternal = urlData.external ?? false
|
let message = urlData.message
|
||||||
|
let progress = urlData.progress
|
||||||
|
let forceExternal = urlData.external ?? false
|
||||||
|
|
||||||
var skipConcealedAlert = false
|
var skipConcealedAlert = false
|
||||||
if let author = message?.author, author.isVerified {
|
if let author = message?.author, author.isVerified {
|
||||||
skipConcealedAlert = true
|
skipConcealedAlert = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if let message, let adAttribute = message.attributes.first(where: { $0 is AdMessageAttribute }) as? AdMessageAttribute {
|
if let message, let adAttribute = message.attributes.first(where: { $0 is AdMessageAttribute }) as? AdMessageAttribute {
|
||||||
strongSelf.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId)
|
strongSelf.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let performOpenURL = strongSelf.performOpenURL {
|
if let performOpenURL = strongSelf.performOpenURL {
|
||||||
performOpenURL(message, url, progress)
|
performOpenURL(message, url, progress)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.openUrl(url, concealed: concealed, forceExternal: forceExternal, skipConcealedAlert: skipConcealedAlert, message: message, allowInlineWebpageResolution: urlData.allowInlineWebpageResolution, progress: progress)
|
strongSelf.openUrl(url, concealed: concealed, forceExternal: forceExternal, skipConcealedAlert: skipConcealedAlert, message: message, allowInlineWebpageResolution: urlData.allowInlineWebpageResolution, progress: progress)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, shareCurrentLocation: { [weak self] in
|
}, shareCurrentLocation: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
@ -4629,6 +4634,34 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.openStickerEditor()
|
self.openStickerEditor()
|
||||||
|
}, openPhoneContextMenu: { [weak self] phoneData in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
phoneData.progress?.set(.single(true))
|
||||||
|
let _ = (self.context.engine.peers.resolvePeerByPhone(phone: phoneData.number)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
phoneData.progress?.set(.single(false))
|
||||||
|
|
||||||
|
self.openPhoneContextMenu(number: phoneData.number, peer: peer, message: phoneData.message, contentNode: phoneData.contentNode, messageNode: phoneData.messageNode, frame: phoneData.messageNode.bounds, anyRecognizer: nil, location: nil)
|
||||||
|
})
|
||||||
|
}, openAgeRestrictedMessageMedia: { [weak self] message, reveal in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let controller = chatAgeRestrictionAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, completion: { [weak self] alwaysShow in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if alwaysShow {
|
||||||
|
self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: "You can update the visibility of sensitive media in [Data and Storage > Show 18+ Content]().", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .top, action: { _ in return false }), in: .current)
|
||||||
|
}
|
||||||
|
reveal()
|
||||||
|
})
|
||||||
|
self.present(controller, in: .window(.root))
|
||||||
}, playMessageEffect: { [weak self] message in
|
}, playMessageEffect: { [weak self] message in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -9525,7 +9558,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
func addPeerContact() {
|
func addPeerContact() {
|
||||||
if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramUser, let peerStatusSettings = self.presentationInterfaceState.contactStatus?.peerStatusSettings, let contactData = DeviceContactExtendedData(peer: EnginePeer(peer)) {
|
if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramUser, let peerStatusSettings = self.presentationInterfaceState.contactStatus?.peerStatusSettings, let contactData = DeviceContactExtendedData(peer: EnginePeer(peer)) {
|
||||||
self.present(context.sharedContext.makeDeviceContactInfoController(context: context, subject: .create(peer: peer, contactData: contactData, isSharing: true, shareViaException: peerStatusSettings.contains(.addExceptionWhenAddingContact), completion: { [weak self] peer, stableId, contactData in
|
self.present(context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: self.context), environment: ShareControllerAppEnvironment(sharedContext: self.context.sharedContext), subject: .create(peer: peer, contactData: contactData, isSharing: true, shareViaException: peerStatusSettings.contains(.addExceptionWhenAddingContact), completion: { [weak self] peer, stableId, contactData in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -10570,6 +10603,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
} else if case let .overlay(navigationController) = self.presentationInterfaceState.mode {
|
} else if case let .overlay(navigationController) = self.presentationInterfaceState.mode {
|
||||||
return navigationController
|
return navigationController
|
||||||
} else {
|
} else {
|
||||||
|
if let navigationController = self.customNavigationController {
|
||||||
|
return navigationController
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import TelegramCallsUI
|
|||||||
import AutomaticBusinessMessageSetupScreen
|
import AutomaticBusinessMessageSetupScreen
|
||||||
import MediaEditorScreen
|
import MediaEditorScreen
|
||||||
import CameraScreen
|
import CameraScreen
|
||||||
|
import ShareController
|
||||||
|
|
||||||
extension ChatControllerImpl {
|
extension ChatControllerImpl {
|
||||||
enum AttachMenuSubject {
|
enum AttachMenuSubject {
|
||||||
@ -520,7 +521,7 @@ extension ChatControllerImpl {
|
|||||||
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: strongSelf.chatLocation.threadId, replyToMessageId: replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
enqueueMessages.append(.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: strongSelf.chatLocation.threadId, replyToMessageId: replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: []))
|
||||||
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime))
|
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(enqueueMessages, silentPosting: silent, scheduleTime: scheduleTime))
|
||||||
} else {
|
} else {
|
||||||
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
|
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
|
||||||
guard let strongSelf = self, !contactData.basicData.phoneNumbers.isEmpty else {
|
guard let strongSelf = self, !contactData.basicData.phoneNumbers.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1590,7 +1591,7 @@ extension ChatControllerImpl {
|
|||||||
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: strongSelf.chatLocation.threadId, replyToMessageId: replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
let message = EnqueueMessage.message(text: "", attributes: [], inlineStickers: [:], mediaReference: .standalone(media: media), threadId: strongSelf.chatLocation.threadId, replyToMessageId: replyMessageSubject?.subjectModel, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])
|
||||||
strongSelf.sendMessages([message])
|
strongSelf.sendMessages([message])
|
||||||
} else {
|
} else {
|
||||||
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
|
let contactController = strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .filter(peer: peerAndContactData.0, contactId: nil, contactData: contactData, completion: { peer, contactData in
|
||||||
guard let strongSelf = self, !contactData.basicData.phoneNumbers.isEmpty else {
|
guard let strongSelf = self, !contactData.basicData.phoneNumbers.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,8 @@ extension ChatControllerImpl {
|
|||||||
}), in: .current)
|
}), in: .current)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push(calendarScreen)
|
self.effectiveNavigationController?.pushViewController(calendarScreen)
|
||||||
|
|
||||||
dismissCalendarScreen = { [weak calendarScreen] in
|
dismissCalendarScreen = { [weak calendarScreen] in
|
||||||
calendarScreen?.dismiss(completion: nil)
|
calendarScreen?.dismiss(completion: nil)
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import SearchUI
|
|||||||
import TelegramPermissionsUI
|
import TelegramPermissionsUI
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import DeviceAccess
|
import DeviceAccess
|
||||||
|
import ShareController
|
||||||
|
|
||||||
public class ComposeControllerImpl: ViewController, ComposeController {
|
public class ComposeControllerImpl: ViewController, ComposeController {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
@ -200,7 +201,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
|||||||
switch status {
|
switch status {
|
||||||
case .allowed:
|
case .allowed:
|
||||||
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: "+")]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||||
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
(strongSelf.navigationController as? NavigationController)?.pushViewController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -211,7 +212,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(strongSelf.navigationController as? NavigationController)?.replaceAllButRootController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: strongSelf.context, subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil), animated: true)
|
(strongSelf.navigationController as? NavigationController)?.replaceAllButRootController(strongSelf.context.sharedContext.makeDeviceContactInfoController(context: ShareControllerAppAccountContext(context: strongSelf.context), environment: ShareControllerAppEnvironment(sharedContext: strongSelf.context.sharedContext), subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil), animated: true)
|
||||||
}
|
}
|
||||||
}), completed: nil, cancelled: nil))
|
}), completed: nil, cancelled: nil))
|
||||||
case .notDetermined:
|
case .notDetermined:
|
||||||
|
@ -7,6 +7,7 @@ import AccountContext
|
|||||||
import AlertUI
|
import AlertUI
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import PeerInfoUI
|
import PeerInfoUI
|
||||||
|
import ShareController
|
||||||
|
|
||||||
func openAddContactImpl(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!<Mobile>!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) {
|
func openAddContactImpl(context: AccountContext, firstName: String = "", lastName: String = "", phoneNumber: String, label: String = "_$!<Mobile>!$_", present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void = {}) {
|
||||||
let _ = (DeviceAccess.authorizationStatus(subject: .contacts)
|
let _ = (DeviceAccess.authorizationStatus(subject: .contacts)
|
||||||
@ -15,13 +16,13 @@ func openAddContactImpl(context: AccountContext, firstName: String = "", lastNam
|
|||||||
switch value {
|
switch value {
|
||||||
case .allowed:
|
case .allowed:
|
||||||
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
let contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: firstName, lastName: lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: label, value: phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||||
present(deviceContactInfoController(context: context, subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
present(deviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), subject: .create(peer: nil, contactData: contactData, isSharing: false, shareViaException: false, completion: { peer, stableId, contactData in
|
||||||
if let peer = peer {
|
if let peer = peer {
|
||||||
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
pushController(infoController)
|
pushController(infoController)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pushController(deviceContactInfoController(context: context, subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil))
|
pushController(deviceContactInfoController(context: ShareControllerAppAccountContext(context: context), environment: ShareControllerAppEnvironment(sharedContext: context.sharedContext), subject: .vcard(nil, stableId, contactData), completed: nil, cancelled: nil))
|
||||||
}
|
}
|
||||||
}), completed: completed, cancelled: nil), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
}), completed: completed, cancelled: nil), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
case .notDetermined:
|
case .notDetermined:
|
||||||
|
@ -330,7 +330,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
} else {
|
} else {
|
||||||
contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contact.firstName, lastName: contact.lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: contact.phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
contactData = DeviceContactExtendedData(basicData: DeviceContactBasicData(firstName: contact.firstName, lastName: contact.lastName, phoneNumbers: [DeviceContactPhoneNumberData(label: "_$!<Mobile>!$_", value: contact.phoneNumber)]), middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "")
|
||||||
}
|
}
|
||||||
let controller = deviceContactInfoController(context: params.context, updatedPresentationData: params.updatedPresentationData, subject: .vcard(peer?._asPeer(), nil, contactData), completed: nil, cancelled: nil)
|
let controller = deviceContactInfoController(context: ShareControllerAppAccountContext(context: params.context), environment: ShareControllerAppEnvironment(sharedContext: params.context.sharedContext), updatedPresentationData: params.updatedPresentationData, subject: .vcard(peer?._asPeer(), nil, contactData), completed: nil, cancelled: nil)
|
||||||
params.navigationController?.pushViewController(controller)
|
params.navigationController?.pushViewController(controller)
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
|
@ -175,6 +175,8 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
|||||||
}, openRecommendedChannelContextMenu: { _, _, _ in
|
}, openRecommendedChannelContextMenu: { _, _, _ in
|
||||||
}, openGroupBoostInfo: { _, _ in
|
}, openGroupBoostInfo: { _, _ in
|
||||||
}, openStickerEditor: {
|
}, openStickerEditor: {
|
||||||
|
}, openPhoneContextMenu: { _ in
|
||||||
|
}, openAgeRestrictedMessageMedia: { _, _ in
|
||||||
}, playMessageEffect: { _ in
|
}, playMessageEffect: { _ in
|
||||||
}, requestMessageUpdate: { _, _ in
|
}, requestMessageUpdate: { _, _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
|
@ -1600,8 +1600,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
openResolvedUrlImpl(resolvedUrl, context: context, urlContext: urlContext, navigationController: navigationController, forceExternal: forceExternal, openPeer: openPeer, sendFile: sendFile, sendSticker: sendSticker, sendEmoji: sendEmoji, requestMessageActionUrlAuth: requestMessageActionUrlAuth, joinVoiceChat: joinVoiceChat, present: present, dismissInput: dismissInput, contentContext: contentContext, progress: progress, completion: completion)
|
openResolvedUrlImpl(resolvedUrl, context: context, urlContext: urlContext, navigationController: navigationController, forceExternal: forceExternal, openPeer: openPeer, sendFile: sendFile, sendSticker: sendSticker, sendEmoji: sendEmoji, requestMessageActionUrlAuth: requestMessageActionUrlAuth, joinVoiceChat: joinVoiceChat, present: present, dismissInput: dismissInput, contentContext: contentContext, progress: progress, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makeDeviceContactInfoController(context: AccountContext, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController {
|
public func makeDeviceContactInfoController(context: ShareControllerAccountContext, environment: ShareControllerEnvironment, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController {
|
||||||
return deviceContactInfoController(context: context, subject: subject, completed: completed, cancelled: cancelled)
|
return deviceContactInfoController(context: context, environment: environment, subject: subject, completed: completed, cancelled: cancelled)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makePeersNearbyController(context: AccountContext) -> ViewController {
|
public func makePeersNearbyController(context: AccountContext) -> ViewController {
|
||||||
@ -1771,6 +1771,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
}, openRecommendedChannelContextMenu: { _, _, _ in
|
}, openRecommendedChannelContextMenu: { _, _, _ in
|
||||||
}, openGroupBoostInfo: { _, _ in
|
}, openGroupBoostInfo: { _, _ in
|
||||||
}, openStickerEditor: {
|
}, openStickerEditor: {
|
||||||
|
}, openPhoneContextMenu: { _ in
|
||||||
|
}, openAgeRestrictedMessageMedia: { _, _ in
|
||||||
}, playMessageEffect: { _ in
|
}, playMessageEffect: { _ in
|
||||||
}, requestMessageUpdate: { _, _ in
|
}, requestMessageUpdate: { _, _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
|
@ -234,24 +234,22 @@ public struct WebAppParameters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func generateWebAppThemeParams(_ presentationTheme: PresentationTheme) -> [String: Any] {
|
public func generateWebAppThemeParams(_ theme: PresentationTheme) -> [String: Any] {
|
||||||
let backgroundColor = presentationTheme.list.plainBackgroundColor.rgb
|
|
||||||
let secondaryBackgroundColor = presentationTheme.list.blocksBackgroundColor.rgb
|
|
||||||
return [
|
return [
|
||||||
"bg_color": Int32(bitPattern: backgroundColor),
|
"bg_color": Int32(bitPattern: theme.list.plainBackgroundColor.rgb),
|
||||||
"secondary_bg_color": Int32(bitPattern: secondaryBackgroundColor),
|
"secondary_bg_color": Int32(bitPattern: theme.list.blocksBackgroundColor.rgb),
|
||||||
"text_color": Int32(bitPattern: presentationTheme.list.itemPrimaryTextColor.rgb),
|
"text_color": Int32(bitPattern: theme.list.itemPrimaryTextColor.rgb),
|
||||||
"hint_color": Int32(bitPattern: presentationTheme.list.itemSecondaryTextColor.rgb),
|
"hint_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||||
"link_color": Int32(bitPattern: presentationTheme.list.itemAccentColor.rgb),
|
"link_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||||
"button_color": Int32(bitPattern: presentationTheme.list.itemCheckColors.fillColor.rgb),
|
"button_color": Int32(bitPattern: theme.list.itemCheckColors.fillColor.rgb),
|
||||||
"button_text_color": Int32(bitPattern: presentationTheme.list.itemCheckColors.foregroundColor.rgb),
|
"button_text_color": Int32(bitPattern: theme.list.itemCheckColors.foregroundColor.rgb),
|
||||||
"header_bg_color": Int32(bitPattern: presentationTheme.rootController.navigationBar.opaqueBackgroundColor.rgb),
|
"header_bg_color": Int32(bitPattern: theme.rootController.navigationBar.opaqueBackgroundColor.rgb),
|
||||||
"accent_text_color": Int32(bitPattern: presentationTheme.list.itemAccentColor.rgb),
|
"accent_text_color": Int32(bitPattern: theme.list.itemAccentColor.rgb),
|
||||||
"section_bg_color": Int32(bitPattern: presentationTheme.list.itemBlocksBackgroundColor.rgb),
|
"section_bg_color": Int32(bitPattern: theme.list.itemBlocksBackgroundColor.rgb),
|
||||||
"section_header_text_color": Int32(bitPattern: presentationTheme.list.freeTextColor.rgb),
|
"section_header_text_color": Int32(bitPattern: theme.list.freeTextColor.rgb),
|
||||||
"subtitle_text_color": Int32(bitPattern: presentationTheme.list.itemSecondaryTextColor.rgb),
|
"subtitle_text_color": Int32(bitPattern: theme.list.itemSecondaryTextColor.rgb),
|
||||||
"destructive_text_color": Int32(bitPattern: presentationTheme.list.itemDestructiveColor.rgb),
|
"destructive_text_color": Int32(bitPattern: theme.list.itemDestructiveColor.rgb),
|
||||||
"section_separator_color": Int32(bitPattern: presentationTheme.list.itemBlocksSeparatorColor.rgb)
|
"section_separator_color": Int32(bitPattern: theme.list.itemBlocksSeparatorColor.rgb)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user