[WIP] Business

This commit is contained in:
Isaac 2024-02-20 14:45:25 +04:00
parent 31260e710b
commit f259829c8a
68 changed files with 3331 additions and 762 deletions

View File

@ -847,6 +847,9 @@ public protocol TelegramRootControllerInterface: NavigationController {
func openSettings()
}
public protocol QuickReplySetupScreenInitialData: AnyObject {
}
public protocol SharedAccountContext: AnyObject {
var sharedContainerPath: String { get }
var basePath: String { get }
@ -934,10 +937,11 @@ public protocol SharedAccountContext: AnyObject {
func makeArchiveSettingsController(context: AccountContext) -> ViewController
func makeBusinessSetupScreen(context: AccountContext) -> ViewController
func makeChatbotSetupScreen(context: AccountContext) -> ViewController
func makeBusinessLocationSetupScreen(context: AccountContext) -> ViewController
func makeBusinessHoursSetupScreen(context: AccountContext) -> ViewController
func makeGreetingMessageSetupScreen(context: AccountContext, isAwayMode: Bool) -> ViewController
func makeQuickReplySetupScreen(context: AccountContext) -> ViewController
func makeBusinessLocationSetupScreen(context: AccountContext, initialValue: TelegramBusinessLocation?, completion: @escaping (TelegramBusinessLocation?) -> Void) -> ViewController
func makeBusinessHoursSetupScreen(context: AccountContext, initialValue: TelegramBusinessHours?, completion: @escaping (TelegramBusinessHours?) -> Void) -> ViewController
func makeAutomaticBusinessMessageSetupScreen(context: AccountContext, isAwayMode: Bool) -> ViewController
func makeQuickReplySetupScreen(context: AccountContext, initialData: QuickReplySetupScreenInitialData) -> ViewController
func makeQuickReplySetupScreenInitialData(context: AccountContext) -> Signal<QuickReplySetupScreenInitialData, NoError>
func navigateToChatController(_ params: NavigateToChatControllerParams)
func navigateToForumChannel(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController)
func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, messageId: EngineMessage.Id?, navigationController: NavigationController, activateInput: ChatControllerActivateInput?, keepStack: NavigateToChatKeepStack) -> Signal<Never, NoError>

View File

@ -803,11 +803,30 @@ public enum ChatControllerPresentationMode: Equatable {
case inline(NavigationController?)
}
public enum ChatInputTextCommand: Equatable {
case command(PeerCommand)
case shortcut(QuickReplyMessageShortcut)
}
public struct ChatInputQueryCommandsResult: Equatable {
public var commands: [ChatInputTextCommand]
public var accountPeer: EnginePeer?
public var hasShortcuts: Bool
public var query: String
public init(commands: [ChatInputTextCommand], accountPeer: EnginePeer?, hasShortcuts: Bool, query: String) {
self.commands = commands
self.accountPeer = accountPeer
self.hasShortcuts = hasShortcuts
self.query = query
}
}
public enum ChatPresentationInputQueryResult: Equatable {
case stickers([FoundStickerItem])
case hashtags([String])
case mentions([EnginePeer])
case commands([PeerCommand])
case commands(ChatInputQueryCommandsResult)
case emojis([(String, TelegramMediaFile?, String)], NSRange)
case contextRequestResult(EnginePeer?, ChatContextResultCollection?)

View File

@ -821,6 +821,8 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
}, sendContextResult: { _, _, _, _ in
return false
}, sendBotCommand: { _, _ in
}, sendShortcut: { _ in
}, openEditShortcuts: {
}, sendBotStart: { _ in
}, botSwitchChatWithPayload: { _, _ in
}, beginMediaRecording: { _ in

View File

@ -1327,6 +1327,7 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
statusBarHeight: layout.statusBarHeight ?? 0.0,
sideInset: layout.safeInsets.left,
isSearchActive: self.isSearchDisplayControllerActive,
isSearchEnabled: true,
primaryContent: headerContent?.primaryContent,
secondaryContent: headerContent?.secondaryContent,
secondaryTransition: self.inlineStackContainerTransitionFraction,

View File

@ -92,10 +92,12 @@ public enum ChatListItemContent {
public struct CustomMessageListData: Equatable {
public var commandPrefix: String?
public var searchQuery: String?
public var messageCount: Int?
public init(commandPrefix: String?, messageCount: Int?) {
public init(commandPrefix: String?, searchQuery: String?, messageCount: Int?) {
self.commandPrefix = commandPrefix
self.searchQuery = searchQuery
self.messageCount = messageCount
}
}
@ -1625,7 +1627,19 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
isForumAvatar = true
}
}
var avatarDiameter = min(60.0, floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0))
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil {
avatarDiameter = 40.0
}
if avatarDiameter != 60.0 {
let avatarFontSize = floor(avatarDiameter * 26.0 / 60.0)
if self.avatarNode.font.pointSize != avatarFontSize {
self.avatarNode.font = avatarPlaceholderFont(size: avatarFontSize)
}
}
self.avatarNode.setPeer(context: item.context, theme: item.presentationData.theme, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor, clipStyle: isForumAvatar ? .roundedRect : .round, synchronousLoad: synchronousLoads, displayDimensions: CGSize(width: 60.0, height: 60.0))
if peer.isPremium && peer.id != item.context.account.peerId {
@ -2011,33 +2025,48 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
let editingOffset: CGFloat
var reorderInset: CGFloat = 0.0
if item.editing {
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, item.selected, true)
let selectionControlStyle: ItemListSelectableControlNode.Style
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil {
selectionControlStyle = .small
} else {
selectionControlStyle = .compact
}
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, item.selected, selectionControlStyle)
if promoInfo == nil && !isPeerGroup {
selectableControlSizeAndApply = sizeAndApply
}
editingOffset = sizeAndApply.0
var canReorder = false
if case let .chatList(index) = item.index, index.pinningIndex != nil, promoInfo == nil, !isPeerGroup {
let sizeAndApply = reorderControlLayout(item.presentationData.theme)
reorderControlSizeAndApply = sizeAndApply
reorderInset = sizeAndApply.0
canReorder = true
} else if case let .forum(pinnedIndex, _, _, _, _) = item.index, case .index = pinnedIndex {
if case let .chat(itemPeer) = contentPeer, case let .channel(channel) = itemPeer.peer {
let canPin = channel.flags.contains(.isCreator) || channel.hasPermission(.pinMessages)
if canPin {
let sizeAndApply = reorderControlLayout(item.presentationData.theme)
reorderControlSizeAndApply = sizeAndApply
reorderInset = sizeAndApply.0
canReorder = true
}
}
}
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil {
canReorder = true
}
if canReorder {
let sizeAndApply = reorderControlLayout(item.presentationData.theme)
reorderControlSizeAndApply = sizeAndApply
reorderInset = sizeAndApply.0
}
} else {
editingOffset = 0.0
}
let enableChatListPhotos = true
// if changed, adjust setupItem accordingly
var avatarDiameter = min(60.0, floor(item.presentationData.fontSize.baseDisplaySize * 60.0 / 17.0))
let avatarLeftInset: CGFloat
@ -2427,6 +2456,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
let mutableAttributedText = NSMutableAttributedString(attributedString: attributedText)
let boldTextFont = Font.semibold(floor(item.presentationData.fontSize.itemListBaseFontSize * 15.0 / 17.0))
mutableAttributedText.insert(NSAttributedString(string: commandPrefix + " ", font: boldTextFont, textColor: theme.titleColor), at: 0)
if let searchQuery = customMessageListData.searchQuery {
let range = (mutableAttributedText.string as NSString).range(of: searchQuery)
if range.location == 0 {
mutableAttributedText.addAttribute(.foregroundColor, value: item.presentationData.theme.list.itemAccentColor, range: range)
}
}
attributedText = mutableAttributedText
}
@ -3127,7 +3162,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
itemHeight -= 21.0
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil {
itemHeight += measureLayout.size.height * 2.0
itemHeight += 22.0
itemHeight += 20.0
} else {
itemHeight += titleLayout.size.height
itemHeight += measureLayout.size.height * 3.0

View File

@ -104,6 +104,8 @@ public final class ChatPanelInterfaceInteraction {
public let togglePeerNotifications: () -> Void
public let sendContextResult: (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool
public let sendBotCommand: (Peer, String) -> Void
public let sendShortcut: (QuickReplyMessageShortcut) -> Void
public let openEditShortcuts: () -> Void
public let sendBotStart: (String?) -> Void
public let botSwitchChatWithPayload: (PeerId, String) -> Void
public let beginMediaRecording: (Bool) -> Void
@ -217,6 +219,8 @@ public final class ChatPanelInterfaceInteraction {
togglePeerNotifications: @escaping () -> Void,
sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool,
sendBotCommand: @escaping (Peer, String) -> Void,
sendShortcut: @escaping (QuickReplyMessageShortcut) -> Void,
openEditShortcuts: @escaping () -> Void,
sendBotStart: @escaping (String?) -> Void,
botSwitchChatWithPayload: @escaping (PeerId, String) -> Void,
beginMediaRecording: @escaping (Bool) -> Void,
@ -329,6 +333,8 @@ public final class ChatPanelInterfaceInteraction {
self.togglePeerNotifications = togglePeerNotifications
self.sendContextResult = sendContextResult
self.sendBotCommand = sendBotCommand
self.sendShortcut = sendShortcut
self.openEditShortcuts = openEditShortcuts
self.sendBotStart = sendBotStart
self.botSwitchChatWithPayload = botSwitchChatWithPayload
self.beginMediaRecording = beginMediaRecording
@ -448,6 +454,8 @@ public final class ChatPanelInterfaceInteraction {
}, sendContextResult: { _, _, _, _ in
return false
}, sendBotCommand: { _, _ in
}, sendShortcut: { _ in
}, openEditShortcuts: {
}, sendBotStart: { _ in
}, botSwitchChatWithPayload: { _, _ in
}, beginMediaRecording: { _ in

View File

@ -362,6 +362,7 @@ final class ContactsControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
statusBarHeight: layout.statusBarHeight ?? 0.0,
sideInset: layout.safeInsets.left,
isSearchActive: self.isSearchDisplayControllerActive,
isSearchEnabled: true,
primaryContent: primaryContent,
secondaryContent: nil,
secondaryTransition: 0.0,

View File

@ -188,7 +188,7 @@ public class ItemListAddressItemNode: ListViewItemNode {
var leftOffset: CGFloat = 0.0
var selectionNodeWidthAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
if let selected = item.selected {
let (selectionWidth, selectionApply) = selectionNodeLayout(item.theme.list.itemCheckColors.strokeColor, item.theme.list.itemCheckColors.fillColor, item.theme.list.itemCheckColors.foregroundColor, selected, false)
let (selectionWidth, selectionApply) = selectionNodeLayout(item.theme.list.itemCheckColors.strokeColor, item.theme.list.itemCheckColors.fillColor, item.theme.list.itemCheckColors.foregroundColor, selected, .regular)
selectionNodeWidthAndApply = (selectionWidth, selectionApply)
leftOffset += selectionWidth - 8.0
}

View File

@ -440,7 +440,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
if case let .check(checked) = item.control {
selected = checked
}
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, selected, true)
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, selected, .compact)
selectableControlSizeAndApply = sizeAndApply
editingOffset = sizeAndApply.0
} else {

View File

@ -5,6 +5,12 @@ import Display
import CheckNode
public final class ItemListSelectableControlNode: ASDisplayNode {
public enum Style {
case regular
case compact
case small
}
private let checkNode: CheckNode
public init(strokeColor: UIColor, fillColor: UIColor, foregroundColor: UIColor) {
@ -16,8 +22,8 @@ public final class ItemListSelectableControlNode: ASDisplayNode {
self.addSubnode(self.checkNode)
}
public static func asyncLayout(_ node: ItemListSelectableControlNode?) -> (_ strokeColor: UIColor, _ fillColor: UIColor, _ foregroundColor: UIColor, _ selected: Bool, _ compact: Bool) -> (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode) {
return { strokeColor, fillColor, foregroundColor, selected, compact in
public static func asyncLayout(_ node: ItemListSelectableControlNode?) -> (_ strokeColor: UIColor, _ fillColor: UIColor, _ foregroundColor: UIColor, _ selected: Bool, _ style: Style) -> (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode) {
return { strokeColor, fillColor, foregroundColor, selected, style in
let resultNode: ItemListSelectableControlNode
if let node = node {
resultNode = node
@ -25,9 +31,28 @@ public final class ItemListSelectableControlNode: ASDisplayNode {
resultNode = ItemListSelectableControlNode(strokeColor: strokeColor, fillColor: fillColor, foregroundColor: foregroundColor)
}
return (compact ? 38.0 : 45.0, { size, animated in
let checkSize = CGSize(width: 26.0, height: 26.0)
resultNode.checkNode.frame = CGRect(origin: CGPoint(x: compact ? 11.0 : 13.0, y: floorToScreenPixels((size.height - checkSize.height) / 2.0)), size: checkSize)
let offsetSize: CGFloat
switch style {
case .regular:
offsetSize = 45.0
case .compact:
offsetSize = 38.0
case .small:
offsetSize = 44.0
}
return (offsetSize, { size, animated in
let checkSize: CGSize
let checkOffset: CGFloat
switch style {
case .regular, .compact:
checkSize = CGSize(width: 26.0, height: 26.0)
checkOffset = style == .compact ? 11.0 : 13.0
case .small:
checkSize = CGSize(width: 22.0, height: 22.0)
checkOffset = 16.0
}
resultNode.checkNode.frame = CGRect(origin: CGPoint(x: checkOffset, y: floorToScreenPixels((size.height - checkSize.height) / 2.0)), size: checkSize)
resultNode.checkNode.setSelected(selected, animated: animated)
return resultNode
})

View File

@ -189,7 +189,7 @@ public class ItemListTextWithLabelItemNode: ListViewItemNode {
var leftOffset: CGFloat = 0.0
var selectionNodeWidthAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
if let selected = item.selected {
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, selected, false)
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, selected, .regular)
selectionNodeWidthAndApply = (selectionWidth, selectionApply)
leftOffset += selectionWidth - 8.0
}

View File

@ -595,7 +595,7 @@ public final class ListMessageFileItemNode: ListMessageNode {
var leftOffset: CGFloat = 0.0
var selectionNodeWidthAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
if case let .selectable(selected) = item.selection {
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.theme.list.itemCheckColors.fillColor, item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, selected, false)
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.theme.list.itemCheckColors.fillColor, item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, selected, .regular)
selectionNodeWidthAndApply = (selectionWidth, selectionApply)
leftOffset += selectionWidth
}

View File

@ -259,7 +259,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
var leftOffset: CGFloat = 0.0
var selectionNodeWidthAndApply: (CGFloat, (CGSize, Bool) -> ItemListSelectableControlNode)?
if case let .selectable(selected) = item.selection {
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.theme.list.itemCheckColors.fillColor, item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, selected, false)
let (selectionWidth, selectionApply) = selectionNodeLayout(item.presentationData.theme.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.theme.list.itemCheckColors.fillColor, item.presentationData.theme.theme.list.itemCheckColors.foregroundColor, selected, .regular)
selectionNodeWidthAndApply = (selectionWidth, selectionApply)
leftOffset += selectionWidth
}

View File

@ -736,6 +736,14 @@ public final class Message {
self.associatedStories = associatedStories
}
public func withUpdatedStableId(stableId: UInt32) -> Message {
return Message(stableId: stableId, stableVersion: self.stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, customTags: self.customTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo, associatedStories: self.associatedStories)
}
public func withUpdatedId(id: MessageId) -> Message {
return Message(stableId: self.stableId, stableVersion: self.stableVersion, id: id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, customTags: self.customTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo, associatedStories: self.associatedStories)
}
public func withUpdatedStableVersion(stableVersion: UInt32) -> Message {
return Message(stableId: self.stableId, stableVersion: stableVersion, id: self.id, globallyUniqueId: self.globallyUniqueId, groupingKey: self.groupingKey, groupInfo: self.groupInfo, threadId: self.threadId, timestamp: self.timestamp, flags: self.flags, tags: self.tags, globalTags: self.globalTags, localTags: self.localTags, customTags: self.customTags, forwardInfo: self.forwardInfo, author: self.author, text: self.text, attributes: self.attributes, media: self.media, peers: self.peers, associatedMessages: self.associatedMessages, associatedMessageIds: self.associatedMessageIds, associatedMedia: self.associatedMedia, associatedThreadInfo: self.associatedThreadInfo, associatedStories: self.associatedStories)
}

View File

@ -296,7 +296,7 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode {
var editingOffset: CGFloat = 0.0
if let isSelected = item.isSelected {
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, isSelected, false)
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, isSelected, .regular)
selectableControlSizeAndApply = sizeAndApply
editingOffset = sizeAndApply.0
}

View File

@ -12,6 +12,7 @@ public enum Api {
public enum phone {}
public enum photos {}
public enum premium {}
public enum smsjobs {}
public enum stats {}
public enum stickers {}
public enum storage {}
@ -34,6 +35,7 @@ public enum Api {
public enum phone {}
public enum photos {}
public enum premium {}
public enum smsjobs {}
public enum stats {}
public enum stickers {}
public enum stories {}
@ -99,6 +101,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-944407322] = { return Api.BotMenuButton.parse_botMenuButton($0) }
dict[1113113093] = { return Api.BotMenuButton.parse_botMenuButtonCommands($0) }
dict[1966318984] = { return Api.BotMenuButton.parse_botMenuButtonDefault($0) }
dict[-1104414653] = { return Api.BusinessLocation.parse_businessLocation($0) }
dict[302717625] = { return Api.BusinessWeeklyOpen.parse_businessWeeklyOpen($0) }
dict[-1936543592] = { return Api.BusinessWorkHours.parse_businessWorkHours($0) }
dict[1462101002] = { return Api.CdnConfig.parse_cdnConfig($0) }
dict[-914167110] = { return Api.CdnPublicKey.parse_cdnPublicKey($0) }
dict[531458253] = { return Api.ChannelAdminLogEvent.parse_channelAdminLogEvent($0) }
@ -473,7 +478,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[340088945] = { return Api.MediaArea.parse_mediaAreaSuggestedReaction($0) }
dict[-1098720356] = { return Api.MediaArea.parse_mediaAreaVenue($0) }
dict[64088654] = { return Api.MediaAreaCoordinates.parse_mediaAreaCoordinates($0) }
dict[508332649] = { return Api.Message.parse_message($0) }
dict[-1502839044] = { return Api.Message.parse_message($0) }
dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) }
dict[721967202] = { return Api.Message.parse_messageService($0) }
dict[-872240531] = { return Api.MessageAction.parse_messageActionBoostApply($0) }
@ -812,6 +817,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-651419003] = { return Api.SendMessageAction.parse_speakingInGroupCallAction($0) }
dict[-1239335713] = { return Api.ShippingOption.parse_shippingOption($0) }
dict[-2010155333] = { return Api.SimpleWebViewResult.parse_simpleWebViewResultUrl($0) }
dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) }
dict[-313293833] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
dict[1035529315] = { return Api.SponsoredWebPage.parse_sponsoredWebPage($0) }
dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
@ -846,6 +852,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1964978502] = { return Api.TextWithEntities.parse_textWithEntities($0) }
dict[-1609668650] = { return Api.Theme.parse_theme($0) }
dict[-94849324] = { return Api.ThemeSettings.parse_themeSettings($0) }
dict[-7173643] = { return Api.Timezone.parse_timezone($0) }
dict[-305282981] = { return Api.TopPeer.parse_topPeer($0) }
dict[344356834] = { return Api.TopPeerCategory.parse_topPeerCategoryBotsInline($0) }
dict[-1419371685] = { return Api.TopPeerCategory.parse_topPeerCategoryBotsPM($0) }
@ -897,6 +904,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1906403213] = { return Api.Update.parse_updateDcOptions($0) }
dict[-1020437742] = { return Api.Update.parse_updateDeleteChannelMessages($0) }
dict[-1576161051] = { return Api.Update.parse_updateDeleteMessages($0) }
dict[1407644140] = { return Api.Update.parse_updateDeleteQuickReply($0) }
dict[1450174413] = { return Api.Update.parse_updateDeleteQuickReplyMessages($0) }
dict[-1870238482] = { return Api.Update.parse_updateDeleteScheduledMessages($0) }
dict[654302845] = { return Api.Update.parse_updateDialogFilter($0) }
dict[-1512627963] = { return Api.Update.parse_updateDialogFilterOrder($0) }
@ -930,6 +939,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1656358105] = { return Api.Update.parse_updateNewChannelMessage($0) }
dict[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($0) }
dict[522914557] = { return Api.Update.parse_updateNewMessage($0) }
dict[-1386034803] = { return Api.Update.parse_updateNewQuickReply($0) }
dict[967122427] = { return Api.Update.parse_updateNewScheduledMessage($0) }
dict[1753886890] = { return Api.Update.parse_updateNewStickerSet($0) }
dict[-1094555409] = { return Api.Update.parse_updateNotifySettings($0) }
@ -947,6 +957,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1751942566] = { return Api.Update.parse_updatePinnedSavedDialogs($0) }
dict[-298113238] = { return Api.Update.parse_updatePrivacy($0) }
dict[861169551] = { return Api.Update.parse_updatePtsChanged($0) }
dict[230929261] = { return Api.Update.parse_updateQuickReplies($0) }
dict[1040518415] = { return Api.Update.parse_updateQuickReplyMessage($0) }
dict[-693004986] = { return Api.Update.parse_updateReadChannelDiscussionInbox($0) }
dict[1767677564] = { return Api.Update.parse_updateReadChannelDiscussionOutbox($0) }
dict[-1842450928] = { return Api.Update.parse_updateReadChannelInbox($0) }
@ -966,6 +978,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1960361625] = { return Api.Update.parse_updateSavedRingtones($0) }
dict[2103604867] = { return Api.Update.parse_updateSentStoryReaction($0) }
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
dict[-245208620] = { return Api.Update.parse_updateSmsJob($0) }
dict[834816008] = { return Api.Update.parse_updateStickerSets($0) }
dict[196268545] = { return Api.Update.parse_updateStickerSetsOrder($0) }
dict[738741697] = { return Api.Update.parse_updateStoriesStealthMode($0) }
@ -993,7 +1006,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1831650802] = { return Api.UrlAuthResult.parse_urlAuthResultRequest($0) }
dict[559694904] = { return Api.User.parse_user($0) }
dict[-742634630] = { return Api.User.parse_userEmpty($0) }
dict[-1179571092] = { return Api.UserFull.parse_userFull($0) }
dict[-501688336] = { return Api.UserFull.parse_userFull($0) }
dict[-2100168954] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
dict[1326562017] = { return Api.UserProfilePhoto.parse_userProfilePhotoEmpty($0) }
dict[164646985] = { return Api.UserStatus.parse_userStatusEmpty($0) }
@ -1120,6 +1133,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[2013922064] = { return Api.help.TermsOfService.parse_termsOfService($0) }
dict[686618977] = { return Api.help.TermsOfServiceUpdate.parse_termsOfServiceUpdate($0) }
dict[-483352705] = { return Api.help.TermsOfServiceUpdate.parse_termsOfServiceUpdateEmpty($0) }
dict[2071260529] = { return Api.help.TimezonesList.parse_timezonesList($0) }
dict[-1761146676] = { return Api.help.TimezonesList.parse_timezonesListNotModified($0) }
dict[32192344] = { return Api.help.UserInfo.parse_userInfo($0) }
dict[-206688531] = { return Api.help.UserInfo.parse_userInfoEmpty($0) }
dict[-275956116] = { return Api.messages.AffectedFoundMessages.parse_affectedFoundMessages($0) }
@ -1170,6 +1185,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[978610270] = { return Api.messages.Messages.parse_messagesSlice($0) }
dict[863093588] = { return Api.messages.PeerDialogs.parse_peerDialogs($0) }
dict[1753266509] = { return Api.messages.PeerSettings.parse_peerSettings($0) }
dict[2094438528] = { return Api.messages.QuickReplies.parse_quickReplies($0) }
dict[1603398491] = { return Api.messages.QuickReplies.parse_quickRepliesNotModified($0) }
dict[-1810973582] = { return Api.messages.QuickReply.parse_quickReply($0) }
dict[-352454890] = { return Api.messages.Reactions.parse_reactions($0) }
dict[-1334846497] = { return Api.messages.Reactions.parse_reactionsNotModified($0) }
dict[-1999405994] = { return Api.messages.RecentStickers.parse_recentStickers($0) }
@ -1222,6 +1240,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-2030542532] = { return Api.premium.BoostsList.parse_boostsList($0) }
dict[1230586490] = { return Api.premium.BoostsStatus.parse_boostsStatus($0) }
dict[-1696454430] = { return Api.premium.MyBoosts.parse_myBoosts($0) }
dict[-594852657] = { return Api.smsjobs.EligibilityToJoin.parse_eligibleToJoin($0) }
dict[720277905] = { return Api.smsjobs.Status.parse_status($0) }
dict[963421692] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) }
dict[-276825834] = { return Api.stats.MegagroupStats.parse_megagroupStats($0) }
dict[2145983508] = { return Api.stats.MessageStats.parse_messageStats($0) }
@ -1276,7 +1296,7 @@ public extension Api {
return parser(reader)
}
else {
telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found")
telegramApiLog("Type constructor \(String(UInt32(bitPattern: signature), radix: 16, uppercase: false)) not found")
return nil
}
}
@ -1366,6 +1386,12 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.BotMenuButton:
_1.serialize(buffer, boxed)
case let _1 as Api.BusinessLocation:
_1.serialize(buffer, boxed)
case let _1 as Api.BusinessWeeklyOpen:
_1.serialize(buffer, boxed)
case let _1 as Api.BusinessWorkHours:
_1.serialize(buffer, boxed)
case let _1 as Api.CdnConfig:
_1.serialize(buffer, boxed)
case let _1 as Api.CdnPublicKey:
@ -1798,6 +1824,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.SimpleWebViewResult:
_1.serialize(buffer, boxed)
case let _1 as Api.SmsJob:
_1.serialize(buffer, boxed)
case let _1 as Api.SponsoredMessage:
_1.serialize(buffer, boxed)
case let _1 as Api.SponsoredWebPage:
@ -1844,6 +1872,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.ThemeSettings:
_1.serialize(buffer, boxed)
case let _1 as Api.Timezone:
_1.serialize(buffer, boxed)
case let _1 as Api.TopPeer:
_1.serialize(buffer, boxed)
case let _1 as Api.TopPeerCategory:
@ -2006,6 +2036,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.help.TermsOfServiceUpdate:
_1.serialize(buffer, boxed)
case let _1 as Api.help.TimezonesList:
_1.serialize(buffer, boxed)
case let _1 as Api.help.UserInfo:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.AffectedFoundMessages:
@ -2076,6 +2108,10 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.messages.PeerSettings:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.QuickReplies:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.QuickReply:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.Reactions:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.RecentStickers:
@ -2152,6 +2188,10 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.premium.MyBoosts:
_1.serialize(buffer, boxed)
case let _1 as Api.smsjobs.EligibilityToJoin:
_1.serialize(buffer, boxed)
case let _1 as Api.smsjobs.Status:
_1.serialize(buffer, boxed)
case let _1 as Api.stats.BroadcastStats:
_1.serialize(buffer, boxed)
case let _1 as Api.stats.MegagroupStats:

View File

@ -424,15 +424,15 @@ public extension Api {
}
public extension Api {
indirect enum Message: TypeConstructorDescription {
case message(flags: Int32, id: Int32, fromId: Api.Peer?, fromBoostsApplied: Int32?, peerId: Api.Peer, savedPeerId: Api.Peer?, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?)
case message(flags: Int32, id: Int32, fromId: Api.Peer?, fromBoostsApplied: Int32?, peerId: Api.Peer, savedPeerId: Api.Peer?, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?, quickReplyShortcutId: Int32?)
case messageEmpty(flags: Int32, id: Int32, peerId: Api.Peer?)
case messageService(flags: Int32, id: Int32, fromId: Api.Peer?, peerId: Api.Peer, replyTo: Api.MessageReplyHeader?, date: Int32, action: Api.MessageAction, ttlPeriod: Int32?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .message(let flags, let id, let fromId, let fromBoostsApplied, let peerId, let savedPeerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason, let ttlPeriod):
case .message(let flags, let id, let fromId, let fromBoostsApplied, let peerId, let savedPeerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason, let ttlPeriod, let quickReplyShortcutId):
if boxed {
buffer.appendInt32(508332649)
buffer.appendInt32(-1502839044)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
@ -465,6 +465,7 @@ public extension Api {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 25) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 30) != 0 {serializeInt32(quickReplyShortcutId!, buffer: buffer, boxed: false)}
break
case .messageEmpty(let flags, let id, let peerId):
if boxed {
@ -492,8 +493,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .message(let flags, let id, let fromId, let fromBoostsApplied, let peerId, let savedPeerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason, let ttlPeriod):
return ("message", [("flags", flags as Any), ("id", id as Any), ("fromId", fromId as Any), ("fromBoostsApplied", fromBoostsApplied as Any), ("peerId", peerId as Any), ("savedPeerId", savedPeerId as Any), ("fwdFrom", fwdFrom as Any), ("viaBotId", viaBotId as Any), ("replyTo", replyTo as Any), ("date", date as Any), ("message", message as Any), ("media", media as Any), ("replyMarkup", replyMarkup as Any), ("entities", entities as Any), ("views", views as Any), ("forwards", forwards as Any), ("replies", replies as Any), ("editDate", editDate as Any), ("postAuthor", postAuthor as Any), ("groupedId", groupedId as Any), ("reactions", reactions as Any), ("restrictionReason", restrictionReason as Any), ("ttlPeriod", ttlPeriod as Any)])
case .message(let flags, let id, let fromId, let fromBoostsApplied, let peerId, let savedPeerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason, let ttlPeriod, let quickReplyShortcutId):
return ("message", [("flags", flags as Any), ("id", id as Any), ("fromId", fromId as Any), ("fromBoostsApplied", fromBoostsApplied as Any), ("peerId", peerId as Any), ("savedPeerId", savedPeerId as Any), ("fwdFrom", fwdFrom as Any), ("viaBotId", viaBotId as Any), ("replyTo", replyTo as Any), ("date", date as Any), ("message", message as Any), ("media", media as Any), ("replyMarkup", replyMarkup as Any), ("entities", entities as Any), ("views", views as Any), ("forwards", forwards as Any), ("replies", replies as Any), ("editDate", editDate as Any), ("postAuthor", postAuthor as Any), ("groupedId", groupedId as Any), ("reactions", reactions as Any), ("restrictionReason", restrictionReason as Any), ("ttlPeriod", ttlPeriod as Any), ("quickReplyShortcutId", quickReplyShortcutId as Any)])
case .messageEmpty(let flags, let id, let peerId):
return ("messageEmpty", [("flags", flags as Any), ("id", id as Any), ("peerId", peerId as Any)])
case .messageService(let flags, let id, let fromId, let peerId, let replyTo, let date, let action, let ttlPeriod):
@ -570,6 +571,8 @@ public extension Api {
} }
var _23: Int32?
if Int(_1!) & Int(1 << 25) != 0 {_23 = reader.readInt32() }
var _24: Int32?
if Int(_1!) & Int(1 << 30) != 0 {_24 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 8) == 0) || _3 != nil
@ -593,8 +596,9 @@ public extension Api {
let _c21 = (Int(_1!) & Int(1 << 20) == 0) || _21 != nil
let _c22 = (Int(_1!) & Int(1 << 22) == 0) || _22 != nil
let _c23 = (Int(_1!) & Int(1 << 25) == 0) || _23 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 {
return Api.Message.message(flags: _1!, id: _2!, fromId: _3, fromBoostsApplied: _4, peerId: _5!, savedPeerId: _6, fwdFrom: _7, viaBotId: _8, replyTo: _9, date: _10!, message: _11!, media: _12, replyMarkup: _13, entities: _14, views: _15, forwards: _16, replies: _17, editDate: _18, postAuthor: _19, groupedId: _20, reactions: _21, restrictionReason: _22, ttlPeriod: _23)
let _c24 = (Int(_1!) & Int(1 << 30) == 0) || _24 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 {
return Api.Message.message(flags: _1!, id: _2!, fromId: _3, fromBoostsApplied: _4, peerId: _5!, savedPeerId: _6, fwdFrom: _7, viaBotId: _8, replyTo: _9, date: _10!, message: _11!, media: _12, replyMarkup: _13, entities: _14, views: _15, forwards: _16, replies: _17, editDate: _18, postAuthor: _19, groupedId: _20, reactions: _21, restrictionReason: _22, ttlPeriod: _23, quickReplyShortcutId: _24)
}
else {
return nil

View File

@ -588,6 +588,138 @@ public extension Api {
}
}
public extension Api {
enum BusinessLocation: TypeConstructorDescription {
case businessLocation(geoPoint: Api.GeoPoint, address: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .businessLocation(let geoPoint, let address):
if boxed {
buffer.appendInt32(-1104414653)
}
geoPoint.serialize(buffer, true)
serializeString(address, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .businessLocation(let geoPoint, let address):
return ("businessLocation", [("geoPoint", geoPoint as Any), ("address", address as Any)])
}
}
public static func parse_businessLocation(_ reader: BufferReader) -> BusinessLocation? {
var _1: Api.GeoPoint?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.GeoPoint
}
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.BusinessLocation.businessLocation(geoPoint: _1!, address: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum BusinessWeeklyOpen: TypeConstructorDescription {
case businessWeeklyOpen(startMinute: Int32, endMinute: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .businessWeeklyOpen(let startMinute, let endMinute):
if boxed {
buffer.appendInt32(302717625)
}
serializeInt32(startMinute, buffer: buffer, boxed: false)
serializeInt32(endMinute, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .businessWeeklyOpen(let startMinute, let endMinute):
return ("businessWeeklyOpen", [("startMinute", startMinute as Any), ("endMinute", endMinute as Any)])
}
}
public static func parse_businessWeeklyOpen(_ reader: BufferReader) -> BusinessWeeklyOpen? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.BusinessWeeklyOpen.businessWeeklyOpen(startMinute: _1!, endMinute: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum BusinessWorkHours: TypeConstructorDescription {
case businessWorkHours(flags: Int32, timezoneId: String, weeklyOpen: [Api.BusinessWeeklyOpen])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .businessWorkHours(let flags, let timezoneId, let weeklyOpen):
if boxed {
buffer.appendInt32(-1936543592)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(timezoneId, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(weeklyOpen.count))
for item in weeklyOpen {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .businessWorkHours(let flags, let timezoneId, let weeklyOpen):
return ("businessWorkHours", [("flags", flags as Any), ("timezoneId", timezoneId as Any), ("weeklyOpen", weeklyOpen as Any)])
}
}
public static func parse_businessWorkHours(_ reader: BufferReader) -> BusinessWorkHours? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: [Api.BusinessWeeklyOpen]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BusinessWeeklyOpen.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.BusinessWorkHours.businessWorkHours(flags: _1!, timezoneId: _2!, weeklyOpen: _3!)
}
else {
return nil
}
}
}
}
public extension Api {
enum CdnConfig: TypeConstructorDescription {
case cdnConfig(publicKeys: [Api.CdnPublicKey])

View File

@ -84,6 +84,50 @@ public extension Api {
}
}
public extension Api {
enum SmsJob: TypeConstructorDescription {
case smsJob(jobId: String, phoneNumber: String, text: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .smsJob(let jobId, let phoneNumber, let text):
if boxed {
buffer.appendInt32(-425595208)
}
serializeString(jobId, buffer: buffer, boxed: false)
serializeString(phoneNumber, buffer: buffer, boxed: false)
serializeString(text, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .smsJob(let jobId, let phoneNumber, let text):
return ("smsJob", [("jobId", jobId as Any), ("phoneNumber", phoneNumber as Any), ("text", text as Any)])
}
}
public static func parse_smsJob(_ reader: BufferReader) -> SmsJob? {
var _1: String?
_1 = parseString(reader)
var _2: String?
_2 = parseString(reader)
var _3: String?
_3 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.SmsJob.smsJob(jobId: _1!, phoneNumber: _2!, text: _3!)
}
else {
return nil
}
}
}
}
public extension Api {
indirect enum SponsoredMessage: TypeConstructorDescription {
case sponsoredMessage(flags: Int32, randomId: Buffer, fromId: Api.Peer?, chatInvite: Api.ChatInvite?, chatInviteHash: String?, channelPost: Int32?, startParam: String?, webpage: Api.SponsoredWebPage?, app: Api.BotApp?, message: String, entities: [Api.MessageEntity]?, buttonText: String?, sponsorInfo: String?, additionalInfo: String?)

View File

@ -254,6 +254,50 @@ public extension Api {
}
}
public extension Api {
enum Timezone: TypeConstructorDescription {
case timezone(id: String, name: String, utcOffset: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .timezone(let id, let name, let utcOffset):
if boxed {
buffer.appendInt32(-7173643)
}
serializeString(id, buffer: buffer, boxed: false)
serializeString(name, buffer: buffer, boxed: false)
serializeInt32(utcOffset, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .timezone(let id, let name, let utcOffset):
return ("timezone", [("id", id as Any), ("name", name as Any), ("utcOffset", utcOffset as Any)])
}
}
public static func parse_timezone(_ reader: BufferReader) -> Timezone? {
var _1: String?
_1 = parseString(reader)
var _2: String?
_2 = parseString(reader)
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Timezone.timezone(id: _1!, name: _2!, utcOffset: _3!)
}
else {
return nil
}
}
}
}
public extension Api {
enum TopPeer: TypeConstructorDescription {
case topPeer(peer: Api.Peer, rating: Double)
@ -503,6 +547,8 @@ public extension Api {
case updateDcOptions(dcOptions: [Api.DcOption])
case updateDeleteChannelMessages(channelId: Int64, messages: [Int32], pts: Int32, ptsCount: Int32)
case updateDeleteMessages(messages: [Int32], pts: Int32, ptsCount: Int32)
case updateDeleteQuickReply(shortcutId: Int32)
case updateDeleteQuickReplyMessages(shortcutId: Int32, messages: [Int32])
case updateDeleteScheduledMessages(peer: Api.Peer, messages: [Int32])
case updateDialogFilter(flags: Int32, id: Int32, filter: Api.DialogFilter?)
case updateDialogFilterOrder(order: [Int32])
@ -536,6 +582,7 @@ public extension Api {
case updateNewChannelMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateNewEncryptedMessage(message: Api.EncryptedMessage, qts: Int32)
case updateNewMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateNewQuickReply(quickReply: Api.messages.QuickReply)
case updateNewScheduledMessage(message: Api.Message)
case updateNewStickerSet(stickerset: Api.messages.StickerSet)
case updateNotifySettings(peer: Api.NotifyPeer, notifySettings: Api.PeerNotifySettings)
@ -553,6 +600,8 @@ public extension Api {
case updatePinnedSavedDialogs(flags: Int32, order: [Api.DialogPeer]?)
case updatePrivacy(key: Api.PrivacyKey, rules: [Api.PrivacyRule])
case updatePtsChanged
case updateQuickReplies(quickReplies: [Api.messages.QuickReply])
case updateQuickReplyMessage(message: Api.Message)
case updateReadChannelDiscussionInbox(flags: Int32, channelId: Int64, topMsgId: Int32, readMaxId: Int32, broadcastId: Int64?, broadcastPost: Int32?)
case updateReadChannelDiscussionOutbox(channelId: Int64, topMsgId: Int32, readMaxId: Int32)
case updateReadChannelInbox(flags: Int32, folderId: Int32?, channelId: Int64, maxId: Int32, stillUnreadCount: Int32, pts: Int32)
@ -572,6 +621,7 @@ public extension Api {
case updateSavedRingtones
case updateSentStoryReaction(peer: Api.Peer, storyId: Int32, reaction: Api.Reaction)
case updateServiceNotification(flags: Int32, inboxDate: Int32?, type: String, message: String, media: Api.MessageMedia, entities: [Api.MessageEntity])
case updateSmsJob(jobId: String)
case updateStickerSets(flags: Int32)
case updateStickerSetsOrder(flags: Int32, order: [Int64])
case updateStoriesStealthMode(stealthMode: Api.StoriesStealthMode)
@ -981,6 +1031,23 @@ public extension Api {
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
break
case .updateDeleteQuickReply(let shortcutId):
if boxed {
buffer.appendInt32(1407644140)
}
serializeInt32(shortcutId, buffer: buffer, boxed: false)
break
case .updateDeleteQuickReplyMessages(let shortcutId, let messages):
if boxed {
buffer.appendInt32(1450174413)
}
serializeInt32(shortcutId, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
serializeInt32(item, buffer: buffer, boxed: false)
}
break
case .updateDeleteScheduledMessages(let peer, let messages):
if boxed {
buffer.appendInt32(-1870238482)
@ -1251,6 +1318,12 @@ public extension Api {
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
break
case .updateNewQuickReply(let quickReply):
if boxed {
buffer.appendInt32(-1386034803)
}
quickReply.serialize(buffer, true)
break
case .updateNewScheduledMessage(let message):
if boxed {
buffer.appendInt32(967122427)
@ -1402,6 +1475,22 @@ public extension Api {
buffer.appendInt32(861169551)
}
break
case .updateQuickReplies(let quickReplies):
if boxed {
buffer.appendInt32(230929261)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(quickReplies.count))
for item in quickReplies {
item.serialize(buffer, true)
}
break
case .updateQuickReplyMessage(let message):
if boxed {
buffer.appendInt32(1040518415)
}
message.serialize(buffer, true)
break
case .updateReadChannelDiscussionInbox(let flags, let channelId, let topMsgId, let readMaxId, let broadcastId, let broadcastPost):
if boxed {
@ -1560,6 +1649,12 @@ public extension Api {
item.serialize(buffer, true)
}
break
case .updateSmsJob(let jobId):
if boxed {
buffer.appendInt32(-245208620)
}
serializeString(jobId, buffer: buffer, boxed: false)
break
case .updateStickerSets(let flags):
if boxed {
buffer.appendInt32(834816008)
@ -1761,6 +1856,10 @@ public extension Api {
return ("updateDeleteChannelMessages", [("channelId", channelId as Any), ("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)])
case .updateDeleteMessages(let messages, let pts, let ptsCount):
return ("updateDeleteMessages", [("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)])
case .updateDeleteQuickReply(let shortcutId):
return ("updateDeleteQuickReply", [("shortcutId", shortcutId as Any)])
case .updateDeleteQuickReplyMessages(let shortcutId, let messages):
return ("updateDeleteQuickReplyMessages", [("shortcutId", shortcutId as Any), ("messages", messages as Any)])
case .updateDeleteScheduledMessages(let peer, let messages):
return ("updateDeleteScheduledMessages", [("peer", peer as Any), ("messages", messages as Any)])
case .updateDialogFilter(let flags, let id, let filter):
@ -1827,6 +1926,8 @@ public extension Api {
return ("updateNewEncryptedMessage", [("message", message as Any), ("qts", qts as Any)])
case .updateNewMessage(let message, let pts, let ptsCount):
return ("updateNewMessage", [("message", message as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)])
case .updateNewQuickReply(let quickReply):
return ("updateNewQuickReply", [("quickReply", quickReply as Any)])
case .updateNewScheduledMessage(let message):
return ("updateNewScheduledMessage", [("message", message as Any)])
case .updateNewStickerSet(let stickerset):
@ -1861,6 +1962,10 @@ public extension Api {
return ("updatePrivacy", [("key", key as Any), ("rules", rules as Any)])
case .updatePtsChanged:
return ("updatePtsChanged", [])
case .updateQuickReplies(let quickReplies):
return ("updateQuickReplies", [("quickReplies", quickReplies as Any)])
case .updateQuickReplyMessage(let message):
return ("updateQuickReplyMessage", [("message", message as Any)])
case .updateReadChannelDiscussionInbox(let flags, let channelId, let topMsgId, let readMaxId, let broadcastId, let broadcastPost):
return ("updateReadChannelDiscussionInbox", [("flags", flags as Any), ("channelId", channelId as Any), ("topMsgId", topMsgId as Any), ("readMaxId", readMaxId as Any), ("broadcastId", broadcastId as Any), ("broadcastPost", broadcastPost as Any)])
case .updateReadChannelDiscussionOutbox(let channelId, let topMsgId, let readMaxId):
@ -1899,6 +2004,8 @@ public extension Api {
return ("updateSentStoryReaction", [("peer", peer as Any), ("storyId", storyId as Any), ("reaction", reaction as Any)])
case .updateServiceNotification(let flags, let inboxDate, let type, let message, let media, let entities):
return ("updateServiceNotification", [("flags", flags as Any), ("inboxDate", inboxDate as Any), ("type", type as Any), ("message", message as Any), ("media", media as Any), ("entities", entities as Any)])
case .updateSmsJob(let jobId):
return ("updateSmsJob", [("jobId", jobId as Any)])
case .updateStickerSets(let flags):
return ("updateStickerSets", [("flags", flags as Any)])
case .updateStickerSetsOrder(let flags, let order):
@ -2766,6 +2873,33 @@ public extension Api {
return nil
}
}
public static func parse_updateDeleteQuickReply(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateDeleteQuickReply(shortcutId: _1!)
}
else {
return nil
}
}
public static func parse_updateDeleteQuickReplyMessages(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Int32]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.Update.updateDeleteQuickReplyMessages(shortcutId: _1!, messages: _2!)
}
else {
return nil
}
}
public static func parse_updateDeleteScheduledMessages(_ reader: BufferReader) -> Update? {
var _1: Api.Peer?
if let signature = reader.readInt32() {
@ -3321,6 +3455,19 @@ public extension Api {
return nil
}
}
public static func parse_updateNewQuickReply(_ reader: BufferReader) -> Update? {
var _1: Api.messages.QuickReply?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.messages.QuickReply
}
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateNewQuickReply(quickReply: _1!)
}
else {
return nil
}
}
public static func parse_updateNewScheduledMessage(_ reader: BufferReader) -> Update? {
var _1: Api.Message?
if let signature = reader.readInt32() {
@ -3608,6 +3755,32 @@ public extension Api {
public static func parse_updatePtsChanged(_ reader: BufferReader) -> Update? {
return Api.Update.updatePtsChanged
}
public static func parse_updateQuickReplies(_ reader: BufferReader) -> Update? {
var _1: [Api.messages.QuickReply]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.messages.QuickReply.self)
}
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateQuickReplies(quickReplies: _1!)
}
else {
return nil
}
}
public static func parse_updateQuickReplyMessage(_ reader: BufferReader) -> Update? {
var _1: Api.Message?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Message
}
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateQuickReplyMessage(message: _1!)
}
else {
return nil
}
}
public static func parse_updateReadChannelDiscussionInbox(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
@ -3876,6 +4049,17 @@ public extension Api {
return nil
}
}
public static func parse_updateSmsJob(_ reader: BufferReader) -> Update? {
var _1: String?
_1 = parseString(reader)
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateSmsJob(jobId: _1!)
}
else {
return nil
}
}
public static func parse_updateStickerSets(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()

View File

@ -602,15 +602,16 @@ public extension Api {
}
public extension Api {
enum UserFull: TypeConstructorDescription {
case userFull(flags: Int32, id: Int64, about: String?, settings: Api.PeerSettings, personalPhoto: Api.Photo?, profilePhoto: Api.Photo?, fallbackPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?, botGroupAdminRights: Api.ChatAdminRights?, botBroadcastAdminRights: Api.ChatAdminRights?, premiumGifts: [Api.PremiumGiftOption]?, wallpaper: Api.WallPaper?, stories: Api.PeerStories?)
case userFull(flags: Int32, flags2: Int32, id: Int64, about: String?, settings: Api.PeerSettings, personalPhoto: Api.Photo?, profilePhoto: Api.Photo?, fallbackPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?, botGroupAdminRights: Api.ChatAdminRights?, botBroadcastAdminRights: Api.ChatAdminRights?, premiumGifts: [Api.PremiumGiftOption]?, wallpaper: Api.WallPaper?, stories: Api.PeerStories?, businessWorkHours: Api.BusinessWorkHours?, businessLocation: Api.BusinessLocation?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .userFull(let flags, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories):
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation):
if boxed {
buffer.appendInt32(-1179571092)
buffer.appendInt32(-501688336)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(flags2, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeString(about!, buffer: buffer, boxed: false)}
settings.serialize(buffer, true)
@ -634,102 +635,117 @@ public extension Api {
}}
if Int(flags) & Int(1 << 24) != 0 {wallpaper!.serialize(buffer, true)}
if Int(flags) & Int(1 << 25) != 0 {stories!.serialize(buffer, true)}
if Int(flags2) & Int(1 << 0) != 0 {businessWorkHours!.serialize(buffer, true)}
if Int(flags2) & Int(1 << 1) != 0 {businessLocation!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .userFull(let flags, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories):
return ("userFull", [("flags", flags as Any), ("id", id as Any), ("about", about as Any), ("settings", settings as Any), ("personalPhoto", personalPhoto as Any), ("profilePhoto", profilePhoto as Any), ("fallbackPhoto", fallbackPhoto as Any), ("notifySettings", notifySettings as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("commonChatsCount", commonChatsCount as Any), ("folderId", folderId as Any), ("ttlPeriod", ttlPeriod as Any), ("themeEmoticon", themeEmoticon as Any), ("privateForwardName", privateForwardName as Any), ("botGroupAdminRights", botGroupAdminRights as Any), ("botBroadcastAdminRights", botBroadcastAdminRights as Any), ("premiumGifts", premiumGifts as Any), ("wallpaper", wallpaper as Any), ("stories", stories as Any)])
case .userFull(let flags, let flags2, let id, let about, let settings, let personalPhoto, let profilePhoto, let fallbackPhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights, let premiumGifts, let wallpaper, let stories, let businessWorkHours, let businessLocation):
return ("userFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("settings", settings as Any), ("personalPhoto", personalPhoto as Any), ("profilePhoto", profilePhoto as Any), ("fallbackPhoto", fallbackPhoto as Any), ("notifySettings", notifySettings as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("commonChatsCount", commonChatsCount as Any), ("folderId", folderId as Any), ("ttlPeriod", ttlPeriod as Any), ("themeEmoticon", themeEmoticon as Any), ("privateForwardName", privateForwardName as Any), ("botGroupAdminRights", botGroupAdminRights as Any), ("botBroadcastAdminRights", botBroadcastAdminRights as Any), ("premiumGifts", premiumGifts as Any), ("wallpaper", wallpaper as Any), ("stories", stories as Any), ("businessWorkHours", businessWorkHours as Any), ("businessLocation", businessLocation as Any)])
}
}
public static func parse_userFull(_ reader: BufferReader) -> UserFull? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: String?
if Int(_1!) & Int(1 << 1) != 0 {_3 = parseString(reader) }
var _4: Api.PeerSettings?
var _2: Int32?
_2 = reader.readInt32()
var _3: Int64?
_3 = reader.readInt64()
var _4: String?
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
var _5: Api.PeerSettings?
if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.PeerSettings
_5 = Api.parse(reader, signature: signature) as? Api.PeerSettings
}
var _5: Api.Photo?
if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _6: Api.Photo?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
_6 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _7: Api.Photo?
if Int(_1!) & Int(1 << 22) != 0 {if let signature = reader.readInt32() {
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _8: Api.PeerNotifySettings?
var _8: Api.Photo?
if Int(_1!) & Int(1 << 22) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.Photo
} }
var _9: Api.PeerNotifySettings?
if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
_9 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
}
var _9: Api.BotInfo?
var _10: Api.BotInfo?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.BotInfo
_10 = Api.parse(reader, signature: signature) as? Api.BotInfo
} }
var _10: Int32?
if Int(_1!) & Int(1 << 6) != 0 {_10 = reader.readInt32() }
var _11: Int32?
_11 = reader.readInt32()
if Int(_1!) & Int(1 << 6) != 0 {_11 = reader.readInt32() }
var _12: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_12 = reader.readInt32() }
_12 = reader.readInt32()
var _13: Int32?
if Int(_1!) & Int(1 << 14) != 0 {_13 = reader.readInt32() }
var _14: String?
if Int(_1!) & Int(1 << 15) != 0 {_14 = parseString(reader) }
if Int(_1!) & Int(1 << 11) != 0 {_13 = reader.readInt32() }
var _14: Int32?
if Int(_1!) & Int(1 << 14) != 0 {_14 = reader.readInt32() }
var _15: String?
if Int(_1!) & Int(1 << 16) != 0 {_15 = parseString(reader) }
var _16: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 17) != 0 {if let signature = reader.readInt32() {
_16 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
if Int(_1!) & Int(1 << 15) != 0 {_15 = parseString(reader) }
var _16: String?
if Int(_1!) & Int(1 << 16) != 0 {_16 = parseString(reader) }
var _17: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
if Int(_1!) & Int(1 << 17) != 0 {if let signature = reader.readInt32() {
_17 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
var _18: [Api.PremiumGiftOption]?
var _18: Api.ChatAdminRights?
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
_18 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
} }
var _19: [Api.PremiumGiftOption]?
if Int(_1!) & Int(1 << 19) != 0 {if let _ = reader.readInt32() {
_18 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PremiumGiftOption.self)
_19 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PremiumGiftOption.self)
} }
var _19: Api.WallPaper?
var _20: Api.WallPaper?
if Int(_1!) & Int(1 << 24) != 0 {if let signature = reader.readInt32() {
_19 = Api.parse(reader, signature: signature) as? Api.WallPaper
_20 = Api.parse(reader, signature: signature) as? Api.WallPaper
} }
var _20: Api.PeerStories?
var _21: Api.PeerStories?
if Int(_1!) & Int(1 << 25) != 0 {if let signature = reader.readInt32() {
_20 = Api.parse(reader, signature: signature) as? Api.PeerStories
_21 = Api.parse(reader, signature: signature) as? Api.PeerStories
} }
var _22: Api.BusinessWorkHours?
if Int(_2!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_22 = Api.parse(reader, signature: signature) as? Api.BusinessWorkHours
} }
var _23: Api.BusinessLocation?
if Int(_2!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_23 = Api.parse(reader, signature: signature) as? Api.BusinessLocation
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
let _c4 = _4 != nil
let _c5 = (Int(_1!) & Int(1 << 21) == 0) || _5 != nil
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 22) == 0) || _7 != nil
let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 3) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 6) == 0) || _10 != nil
let _c11 = _11 != nil
let _c12 = (Int(_1!) & Int(1 << 11) == 0) || _12 != nil
let _c13 = (Int(_1!) & Int(1 << 14) == 0) || _13 != nil
let _c14 = (Int(_1!) & Int(1 << 15) == 0) || _14 != nil
let _c15 = (Int(_1!) & Int(1 << 16) == 0) || _15 != nil
let _c16 = (Int(_1!) & Int(1 << 17) == 0) || _16 != nil
let _c17 = (Int(_1!) & Int(1 << 18) == 0) || _17 != nil
let _c18 = (Int(_1!) & Int(1 << 19) == 0) || _18 != nil
let _c19 = (Int(_1!) & Int(1 << 24) == 0) || _19 != nil
let _c20 = (Int(_1!) & Int(1 << 25) == 0) || _20 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 {
return Api.UserFull.userFull(flags: _1!, id: _2!, about: _3, settings: _4!, personalPhoto: _5, profilePhoto: _6, fallbackPhoto: _7, notifySettings: _8!, botInfo: _9, pinnedMsgId: _10, commonChatsCount: _11!, folderId: _12, ttlPeriod: _13, themeEmoticon: _14, privateForwardName: _15, botGroupAdminRights: _16, botBroadcastAdminRights: _17, premiumGifts: _18, wallpaper: _19, stories: _20)
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
let _c5 = _5 != nil
let _c6 = (Int(_1!) & Int(1 << 21) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil
let _c8 = (Int(_1!) & Int(1 << 22) == 0) || _8 != nil
let _c9 = _9 != nil
let _c10 = (Int(_1!) & Int(1 << 3) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 6) == 0) || _11 != nil
let _c12 = _12 != nil
let _c13 = (Int(_1!) & Int(1 << 11) == 0) || _13 != nil
let _c14 = (Int(_1!) & Int(1 << 14) == 0) || _14 != nil
let _c15 = (Int(_1!) & Int(1 << 15) == 0) || _15 != nil
let _c16 = (Int(_1!) & Int(1 << 16) == 0) || _16 != nil
let _c17 = (Int(_1!) & Int(1 << 17) == 0) || _17 != nil
let _c18 = (Int(_1!) & Int(1 << 18) == 0) || _18 != nil
let _c19 = (Int(_1!) & Int(1 << 19) == 0) || _19 != nil
let _c20 = (Int(_1!) & Int(1 << 24) == 0) || _20 != nil
let _c21 = (Int(_1!) & Int(1 << 25) == 0) || _21 != nil
let _c22 = (Int(_2!) & Int(1 << 0) == 0) || _22 != nil
let _c23 = (Int(_2!) & Int(1 << 1) == 0) || _23 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 {
return Api.UserFull.userFull(flags: _1!, flags2: _2!, id: _3!, about: _4, settings: _5!, personalPhoto: _6, profilePhoto: _7, fallbackPhoto: _8, notifySettings: _9!, botInfo: _10, pinnedMsgId: _11, commonChatsCount: _12!, folderId: _13, ttlPeriod: _14, themeEmoticon: _15, privateForwardName: _16, botGroupAdminRights: _17, botBroadcastAdminRights: _18, premiumGifts: _19, wallpaper: _20, stories: _21, businessWorkHours: _22, businessLocation: _23)
}
else {
return nil

View File

@ -354,6 +354,64 @@ public extension Api.help {
}
}
public extension Api.help {
enum TimezonesList: TypeConstructorDescription {
case timezonesList(timezones: [Api.Timezone], hash: Int32)
case timezonesListNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .timezonesList(let timezones, let hash):
if boxed {
buffer.appendInt32(2071260529)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(timezones.count))
for item in timezones {
item.serialize(buffer, true)
}
serializeInt32(hash, buffer: buffer, boxed: false)
break
case .timezonesListNotModified:
if boxed {
buffer.appendInt32(-1761146676)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .timezonesList(let timezones, let hash):
return ("timezonesList", [("timezones", timezones as Any), ("hash", hash as Any)])
case .timezonesListNotModified:
return ("timezonesListNotModified", [])
}
}
public static func parse_timezonesList(_ reader: BufferReader) -> TimezonesList? {
var _1: [Api.Timezone]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Timezone.self)
}
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.help.TimezonesList.timezonesList(timezones: _1!, hash: _2!)
}
else {
return nil
}
}
public static func parse_timezonesListNotModified(_ reader: BufferReader) -> TimezonesList? {
return Api.help.TimezonesList.timezonesListNotModified
}
}
}
public extension Api.help {
enum UserInfo: TypeConstructorDescription {
case userInfo(message: String, entities: [Api.MessageEntity], author: String, date: Int32)

View File

@ -1288,6 +1288,138 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum QuickReplies: TypeConstructorDescription {
case quickReplies(quickReplies: [Api.messages.QuickReply], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case quickRepliesNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .quickReplies(let quickReplies, let messages, let chats, let users):
if boxed {
buffer.appendInt32(2094438528)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(quickReplies.count))
for item in quickReplies {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
case .quickRepliesNotModified:
if boxed {
buffer.appendInt32(1603398491)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .quickReplies(let quickReplies, let messages, let chats, let users):
return ("quickReplies", [("quickReplies", quickReplies as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
case .quickRepliesNotModified:
return ("quickRepliesNotModified", [])
}
}
public static func parse_quickReplies(_ reader: BufferReader) -> QuickReplies? {
var _1: [Api.messages.QuickReply]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.messages.QuickReply.self)
}
var _2: [Api.Message]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _3: [Api.Chat]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _4: [Api.User]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.messages.QuickReplies.quickReplies(quickReplies: _1!, messages: _2!, chats: _3!, users: _4!)
}
else {
return nil
}
}
public static func parse_quickRepliesNotModified(_ reader: BufferReader) -> QuickReplies? {
return Api.messages.QuickReplies.quickRepliesNotModified
}
}
}
public extension Api.messages {
enum QuickReply: TypeConstructorDescription {
case quickReply(shortcutId: Int32, shortcut: String, topMessage: Int32, count: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .quickReply(let shortcutId, let shortcut, let topMessage, let count):
if boxed {
buffer.appendInt32(-1810973582)
}
serializeInt32(shortcutId, buffer: buffer, boxed: false)
serializeString(shortcut, buffer: buffer, boxed: false)
serializeInt32(topMessage, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .quickReply(let shortcutId, let shortcut, let topMessage, let count):
return ("quickReply", [("shortcutId", shortcutId as Any), ("shortcut", shortcut as Any), ("topMessage", topMessage as Any), ("count", count as Any)])
}
}
public static func parse_quickReply(_ reader: BufferReader) -> QuickReply? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.messages.QuickReply.quickReply(shortcutId: _1!, shortcut: _2!, topMessage: _3!, count: _4!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum Reactions: TypeConstructorDescription {
case reactions(hash: Int64, reactions: [Api.Reaction])
@ -1424,155 +1556,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum SavedDialogs: TypeConstructorDescription {
case savedDialogs(dialogs: [Api.SavedDialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case savedDialogsNotModified(count: Int32)
case savedDialogsSlice(count: Int32, dialogs: [Api.SavedDialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .savedDialogs(let dialogs, let messages, let chats, let users):
if boxed {
buffer.appendInt32(-130358751)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dialogs.count))
for item in dialogs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
case .savedDialogsNotModified(let count):
if boxed {
buffer.appendInt32(-1071681560)
}
serializeInt32(count, buffer: buffer, boxed: false)
break
case .savedDialogsSlice(let count, let dialogs, let messages, let chats, let users):
if boxed {
buffer.appendInt32(1153080793)
}
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dialogs.count))
for item in dialogs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .savedDialogs(let dialogs, let messages, let chats, let users):
return ("savedDialogs", [("dialogs", dialogs as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
case .savedDialogsNotModified(let count):
return ("savedDialogsNotModified", [("count", count as Any)])
case .savedDialogsSlice(let count, let dialogs, let messages, let chats, let users):
return ("savedDialogsSlice", [("count", count as Any), ("dialogs", dialogs as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_savedDialogs(_ reader: BufferReader) -> SavedDialogs? {
var _1: [Api.SavedDialog]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedDialog.self)
}
var _2: [Api.Message]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _3: [Api.Chat]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _4: [Api.User]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.messages.SavedDialogs.savedDialogs(dialogs: _1!, messages: _2!, chats: _3!, users: _4!)
}
else {
return nil
}
}
public static func parse_savedDialogsNotModified(_ reader: BufferReader) -> SavedDialogs? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.messages.SavedDialogs.savedDialogsNotModified(count: _1!)
}
else {
return nil
}
}
public static func parse_savedDialogsSlice(_ reader: BufferReader) -> SavedDialogs? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.SavedDialog]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedDialog.self)
}
var _3: [Api.Message]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _4: [Api.Chat]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _5: [Api.User]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.messages.SavedDialogs.savedDialogsSlice(count: _1!, dialogs: _2!, messages: _3!, chats: _4!, users: _5!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,155 @@
public extension Api.messages {
enum SavedDialogs: TypeConstructorDescription {
case savedDialogs(dialogs: [Api.SavedDialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case savedDialogsNotModified(count: Int32)
case savedDialogsSlice(count: Int32, dialogs: [Api.SavedDialog], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .savedDialogs(let dialogs, let messages, let chats, let users):
if boxed {
buffer.appendInt32(-130358751)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dialogs.count))
for item in dialogs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
case .savedDialogsNotModified(let count):
if boxed {
buffer.appendInt32(-1071681560)
}
serializeInt32(count, buffer: buffer, boxed: false)
break
case .savedDialogsSlice(let count, let dialogs, let messages, let chats, let users):
if boxed {
buffer.appendInt32(1153080793)
}
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dialogs.count))
for item in dialogs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .savedDialogs(let dialogs, let messages, let chats, let users):
return ("savedDialogs", [("dialogs", dialogs as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
case .savedDialogsNotModified(let count):
return ("savedDialogsNotModified", [("count", count as Any)])
case .savedDialogsSlice(let count, let dialogs, let messages, let chats, let users):
return ("savedDialogsSlice", [("count", count as Any), ("dialogs", dialogs as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_savedDialogs(_ reader: BufferReader) -> SavedDialogs? {
var _1: [Api.SavedDialog]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedDialog.self)
}
var _2: [Api.Message]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _3: [Api.Chat]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _4: [Api.User]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.messages.SavedDialogs.savedDialogs(dialogs: _1!, messages: _2!, chats: _3!, users: _4!)
}
else {
return nil
}
}
public static func parse_savedDialogsNotModified(_ reader: BufferReader) -> SavedDialogs? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.messages.SavedDialogs.savedDialogsNotModified(count: _1!)
}
else {
return nil
}
}
public static func parse_savedDialogsSlice(_ reader: BufferReader) -> SavedDialogs? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.SavedDialog]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SavedDialog.self)
}
var _3: [Api.Message]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _4: [Api.Chat]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _5: [Api.User]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.messages.SavedDialogs.savedDialogsSlice(count: _1!, dialogs: _2!, messages: _3!, chats: _4!, users: _5!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum SavedGifs: TypeConstructorDescription {
case savedGifs(hash: Int64, gifs: [Api.Document])
@ -1398,95 +1550,3 @@ public extension Api.payments {
}
}
public extension Api.payments {
enum SavedInfo: TypeConstructorDescription {
case savedInfo(flags: Int32, savedInfo: Api.PaymentRequestedInfo?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .savedInfo(let flags, let savedInfo):
if boxed {
buffer.appendInt32(-74456004)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .savedInfo(let flags, let savedInfo):
return ("savedInfo", [("flags", flags as Any), ("savedInfo", savedInfo as Any)])
}
}
public static func parse_savedInfo(_ reader: BufferReader) -> SavedInfo? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.PaymentRequestedInfo?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
if _c1 && _c2 {
return Api.payments.SavedInfo.savedInfo(flags: _1!, savedInfo: _2)
}
else {
return nil
}
}
}
}
public extension Api.payments {
enum ValidatedRequestedInfo: TypeConstructorDescription {
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
if boxed {
buffer.appendInt32(-784000893)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(id!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(shippingOptions!.count))
for item in shippingOptions! {
item.serialize(buffer, true)
}}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
return ("validatedRequestedInfo", [("flags", flags as Any), ("id", id as Any), ("shippingOptions", shippingOptions as Any)])
}
}
public static func parse_validatedRequestedInfo(_ reader: BufferReader) -> ValidatedRequestedInfo? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
var _3: [Api.ShippingOption]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ShippingOption.self)
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.payments.ValidatedRequestedInfo.validatedRequestedInfo(flags: _1!, id: _2, shippingOptions: _3)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,95 @@
public extension Api.payments {
enum SavedInfo: TypeConstructorDescription {
case savedInfo(flags: Int32, savedInfo: Api.PaymentRequestedInfo?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .savedInfo(let flags, let savedInfo):
if boxed {
buffer.appendInt32(-74456004)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {savedInfo!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .savedInfo(let flags, let savedInfo):
return ("savedInfo", [("flags", flags as Any), ("savedInfo", savedInfo as Any)])
}
}
public static func parse_savedInfo(_ reader: BufferReader) -> SavedInfo? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.PaymentRequestedInfo?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.PaymentRequestedInfo
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
if _c1 && _c2 {
return Api.payments.SavedInfo.savedInfo(flags: _1!, savedInfo: _2)
}
else {
return nil
}
}
}
}
public extension Api.payments {
enum ValidatedRequestedInfo: TypeConstructorDescription {
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
if boxed {
buffer.appendInt32(-784000893)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(id!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(shippingOptions!.count))
for item in shippingOptions! {
item.serialize(buffer, true)
}}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .validatedRequestedInfo(let flags, let id, let shippingOptions):
return ("validatedRequestedInfo", [("flags", flags as Any), ("id", id as Any), ("shippingOptions", shippingOptions as Any)])
}
}
public static func parse_validatedRequestedInfo(_ reader: BufferReader) -> ValidatedRequestedInfo? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
var _3: [Api.ShippingOption]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ShippingOption.self)
} }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.payments.ValidatedRequestedInfo.validatedRequestedInfo(flags: _1!, id: _2, shippingOptions: _3)
}
else {
return nil
}
}
}
}
public extension Api.phone {
enum ExportedGroupCallInvite: TypeConstructorDescription {
case exportedGroupCallInvite(link: String)
@ -724,6 +816,110 @@ public extension Api.premium {
}
}
public extension Api.smsjobs {
enum EligibilityToJoin: TypeConstructorDescription {
case eligibleToJoin(termsUrl: String, monthlySentSms: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .eligibleToJoin(let termsUrl, let monthlySentSms):
if boxed {
buffer.appendInt32(-594852657)
}
serializeString(termsUrl, buffer: buffer, boxed: false)
serializeInt32(monthlySentSms, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .eligibleToJoin(let termsUrl, let monthlySentSms):
return ("eligibleToJoin", [("termsUrl", termsUrl as Any), ("monthlySentSms", monthlySentSms as Any)])
}
}
public static func parse_eligibleToJoin(_ reader: BufferReader) -> EligibilityToJoin? {
var _1: String?
_1 = parseString(reader)
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.smsjobs.EligibilityToJoin.eligibleToJoin(termsUrl: _1!, monthlySentSms: _2!)
}
else {
return nil
}
}
}
}
public extension Api.smsjobs {
enum Status: TypeConstructorDescription {
case status(flags: Int32, recentSent: Int32, recentSince: Int32, recentRemains: Int32, totalSent: Int32, totalSince: Int32, lastGiftSlug: String?, termsUrl: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .status(let flags, let recentSent, let recentSince, let recentRemains, let totalSent, let totalSince, let lastGiftSlug, let termsUrl):
if boxed {
buffer.appendInt32(720277905)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(recentSent, buffer: buffer, boxed: false)
serializeInt32(recentSince, buffer: buffer, boxed: false)
serializeInt32(recentRemains, buffer: buffer, boxed: false)
serializeInt32(totalSent, buffer: buffer, boxed: false)
serializeInt32(totalSince, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {serializeString(lastGiftSlug!, buffer: buffer, boxed: false)}
serializeString(termsUrl, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .status(let flags, let recentSent, let recentSince, let recentRemains, let totalSent, let totalSince, let lastGiftSlug, let termsUrl):
return ("status", [("flags", flags as Any), ("recentSent", recentSent as Any), ("recentSince", recentSince as Any), ("recentRemains", recentRemains as Any), ("totalSent", totalSent as Any), ("totalSince", totalSince as Any), ("lastGiftSlug", lastGiftSlug as Any), ("termsUrl", termsUrl as Any)])
}
}
public static func parse_status(_ reader: BufferReader) -> Status? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
var _7: String?
if Int(_1!) & Int(1 << 1) != 0 {_7 = parseString(reader) }
var _8: String?
_8 = 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
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
let _c8 = _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.smsjobs.Status.status(flags: _1!, recentSent: _2!, recentSince: _3!, recentRemains: _4!, totalSent: _5!, totalSince: _6!, lastGiftSlug: _7, termsUrl: _8!)
}
else {
return nil
}
}
}
}
public extension Api.stats {
enum BroadcastStats: TypeConstructorDescription {
case broadcastStats(period: Api.StatsDateRangeDays, followers: Api.StatsAbsValueAndPrev, viewsPerPost: Api.StatsAbsValueAndPrev, sharesPerPost: Api.StatsAbsValueAndPrev, reactionsPerPost: Api.StatsAbsValueAndPrev, viewsPerStory: Api.StatsAbsValueAndPrev, sharesPerStory: Api.StatsAbsValueAndPrev, reactionsPerStory: Api.StatsAbsValueAndPrev, enabledNotifications: Api.StatsPercentValue, growthGraph: Api.StatsGraph, followersGraph: Api.StatsGraph, muteGraph: Api.StatsGraph, topHoursGraph: Api.StatsGraph, interactionsGraph: Api.StatsGraph, ivInteractionsGraph: Api.StatsGraph, viewsBySourceGraph: Api.StatsGraph, newFollowersBySourceGraph: Api.StatsGraph, languagesGraph: Api.StatsGraph, reactionsByEmotionGraph: Api.StatsGraph, storyInteractionsGraph: Api.StatsGraph, storyReactionsByEmotionGraph: Api.StatsGraph, recentPostsInteractions: [Api.PostInteractionCounters])
@ -1376,171 +1572,3 @@ public extension Api.storage {
}
}
public extension Api.stories {
enum AllStories: TypeConstructorDescription {
case allStories(flags: Int32, count: Int32, state: String, peerStories: [Api.PeerStories], chats: [Api.Chat], users: [Api.User], stealthMode: Api.StoriesStealthMode)
case allStoriesNotModified(flags: Int32, state: String, stealthMode: Api.StoriesStealthMode)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
if boxed {
buffer.appendInt32(1862033025)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
serializeString(state, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(peerStories.count))
for item in peerStories {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
stealthMode.serialize(buffer, true)
break
case .allStoriesNotModified(let flags, let state, let stealthMode):
if boxed {
buffer.appendInt32(291044926)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(state, buffer: buffer, boxed: false)
stealthMode.serialize(buffer, true)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
return ("allStories", [("flags", flags as Any), ("count", count as Any), ("state", state as Any), ("peerStories", peerStories as Any), ("chats", chats as Any), ("users", users as Any), ("stealthMode", stealthMode as Any)])
case .allStoriesNotModified(let flags, let state, let stealthMode):
return ("allStoriesNotModified", [("flags", flags as Any), ("state", state as Any), ("stealthMode", stealthMode as Any)])
}
}
public static func parse_allStories(_ reader: BufferReader) -> AllStories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: String?
_3 = parseString(reader)
var _4: [Api.PeerStories]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PeerStories.self)
}
var _5: [Api.Chat]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _6: [Api.User]?
if let _ = reader.readInt32() {
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
var _7: Api.StoriesStealthMode?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.stories.AllStories.allStories(flags: _1!, count: _2!, state: _3!, peerStories: _4!, chats: _5!, users: _6!, stealthMode: _7!)
}
else {
return nil
}
}
public static func parse_allStoriesNotModified(_ reader: BufferReader) -> AllStories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: Api.StoriesStealthMode?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.stories.AllStories.allStoriesNotModified(flags: _1!, state: _2!, stealthMode: _3!)
}
else {
return nil
}
}
}
}
public extension Api.stories {
enum PeerStories: TypeConstructorDescription {
case peerStories(stories: Api.PeerStories, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .peerStories(let stories, let chats, let users):
if boxed {
buffer.appendInt32(-890861720)
}
stories.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .peerStories(let stories, let chats, let users):
return ("peerStories", [("stories", stories as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_peerStories(_ reader: BufferReader) -> PeerStories? {
var _1: Api.PeerStories?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.PeerStories
}
var _2: [Api.Chat]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _3: [Api.User]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.stories.PeerStories.peerStories(stories: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,171 @@
public extension Api.stories {
enum AllStories: TypeConstructorDescription {
case allStories(flags: Int32, count: Int32, state: String, peerStories: [Api.PeerStories], chats: [Api.Chat], users: [Api.User], stealthMode: Api.StoriesStealthMode)
case allStoriesNotModified(flags: Int32, state: String, stealthMode: Api.StoriesStealthMode)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
if boxed {
buffer.appendInt32(1862033025)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
serializeString(state, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(peerStories.count))
for item in peerStories {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
stealthMode.serialize(buffer, true)
break
case .allStoriesNotModified(let flags, let state, let stealthMode):
if boxed {
buffer.appendInt32(291044926)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(state, buffer: buffer, boxed: false)
stealthMode.serialize(buffer, true)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .allStories(let flags, let count, let state, let peerStories, let chats, let users, let stealthMode):
return ("allStories", [("flags", flags as Any), ("count", count as Any), ("state", state as Any), ("peerStories", peerStories as Any), ("chats", chats as Any), ("users", users as Any), ("stealthMode", stealthMode as Any)])
case .allStoriesNotModified(let flags, let state, let stealthMode):
return ("allStoriesNotModified", [("flags", flags as Any), ("state", state as Any), ("stealthMode", stealthMode as Any)])
}
}
public static func parse_allStories(_ reader: BufferReader) -> AllStories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: String?
_3 = parseString(reader)
var _4: [Api.PeerStories]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PeerStories.self)
}
var _5: [Api.Chat]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _6: [Api.User]?
if let _ = reader.readInt32() {
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
var _7: Api.StoriesStealthMode?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.stories.AllStories.allStories(flags: _1!, count: _2!, state: _3!, peerStories: _4!, chats: _5!, users: _6!, stealthMode: _7!)
}
else {
return nil
}
}
public static func parse_allStoriesNotModified(_ reader: BufferReader) -> AllStories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: Api.StoriesStealthMode?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.StoriesStealthMode
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.stories.AllStories.allStoriesNotModified(flags: _1!, state: _2!, stealthMode: _3!)
}
else {
return nil
}
}
}
}
public extension Api.stories {
enum PeerStories: TypeConstructorDescription {
case peerStories(stories: Api.PeerStories, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .peerStories(let stories, let chats, let users):
if boxed {
buffer.appendInt32(-890861720)
}
stories.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .peerStories(let stories, let chats, let users):
return ("peerStories", [("stories", stories as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_peerStories(_ reader: BufferReader) -> PeerStories? {
var _1: Api.PeerStories?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.PeerStories
}
var _2: [Api.Chat]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _3: [Api.User]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.stories.PeerStories.peerStories(stories: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}
public extension Api.stories {
enum Stories: TypeConstructorDescription {
case stories(count: Int32, stories: [Api.StoryItem], chats: [Api.Chat], users: [Api.User])

View File

@ -1261,6 +1261,39 @@ public extension Api.functions.account {
})
}
}
public extension Api.functions.account {
static func updateBusinessLocation(flags: Int32, geoPoint: Api.InputGeoPoint?, address: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1040005974)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {geoPoint!.serialize(buffer, true)}
if Int(flags) & Int(1 << 0) != 0 {serializeString(address!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "account.updateBusinessLocation", parameters: [("flags", String(describing: flags)), ("geoPoint", String(describing: geoPoint)), ("address", String(describing: address))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.account {
static func updateBusinessWorkHours(flags: Int32, businessWorkHours: Api.BusinessWorkHours?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1258348646)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {businessWorkHours!.serialize(buffer, true)}
return (FunctionDescription(name: "account.updateBusinessWorkHours", parameters: [("flags", String(describing: flags)), ("businessWorkHours", String(describing: businessWorkHours))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.account {
static func updateColor(flags: Int32, color: Int32?, backgroundEmojiId: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -4130,6 +4163,21 @@ public extension Api.functions.help {
})
}
}
public extension Api.functions.help {
static func getTimezonesList(hash: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.help.TimezonesList>) {
let buffer = Buffer()
buffer.appendInt32(1236468288)
serializeInt32(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "help.getTimezonesList", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.help.TimezonesList? in
let reader = BufferReader(buffer)
var result: Api.help.TimezonesList?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.help.TimezonesList
}
return result
})
}
}
public extension Api.functions.help {
static func getUserInfo(userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.help.UserInfo>) {
let buffer = Buffer()
@ -4393,6 +4441,21 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func checkQuickReplyShortcut(shortcut: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-237962285)
serializeString(shortcut, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.checkQuickReplyShortcut", parameters: [("shortcut", String(describing: shortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.messages {
static func clearAllDrafts() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -4562,6 +4625,26 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func deleteQuickReplyMessages(shortcutId: Int32, id: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-519706352)
serializeInt32(shortcutId, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(id.count))
for item in id {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "messages.deleteQuickReplyMessages", parameters: [("shortcutId", String(describing: shortcutId)), ("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.messages {
static func deleteRevokedExportedChatInvites(peer: Api.InputPeer, adminId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -4760,9 +4843,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, media: Api.InputMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func editMessage(flags: Int32, peer: Api.InputPeer, id: Int32, message: String?, media: Api.InputMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?, quickReplyShortcutId: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(1224152952)
buffer.appendInt32(-539934715)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
@ -4775,7 +4858,8 @@ public extension Api.functions.messages {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 15) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.editMessage", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("id", String(describing: id)), ("message", String(describing: message)), ("media", String(describing: media)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeInt32(quickReplyShortcutId!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.editMessage", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("id", String(describing: id)), ("message", String(describing: message)), ("media", String(describing: media)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate)), ("quickReplyShortcutId", String(describing: quickReplyShortcutId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -4785,6 +4869,22 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func editQuickReplyShortcut(shortcutId: Int32, shortcut: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1543519471)
serializeInt32(shortcutId, buffer: buffer, boxed: false)
serializeString(shortcut, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.editQuickReplyShortcut", parameters: [("shortcutId", String(describing: shortcutId)), ("shortcut", String(describing: shortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.messages {
static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?, title: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
let buffer = Buffer()
@ -4821,9 +4921,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func forwardMessages(flags: Int32, fromPeer: Api.InputPeer, id: [Int32], randomId: [Int64], toPeer: Api.InputPeer, topMsgId: Int32?, scheduleDate: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func forwardMessages(flags: Int32, fromPeer: Api.InputPeer, id: [Int32], randomId: [Int64], toPeer: Api.InputPeer, topMsgId: Int32?, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-966673468)
buffer.appendInt32(-709978674)
serializeInt32(flags, buffer: buffer, boxed: false)
fromPeer.serialize(buffer, true)
buffer.appendInt32(481674261)
@ -4840,7 +4940,8 @@ public extension Api.functions.messages {
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.forwardMessages", parameters: [("flags", String(describing: flags)), ("fromPeer", String(describing: fromPeer)), ("id", String(describing: id)), ("randomId", String(describing: randomId)), ("toPeer", String(describing: toPeer)), ("topMsgId", String(describing: topMsgId)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeString(quickReplyShortcut!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.forwardMessages", parameters: [("flags", String(describing: flags)), ("fromPeer", String(describing: fromPeer)), ("id", String(describing: id)), ("randomId", String(describing: randomId)), ("toPeer", String(describing: toPeer)), ("topMsgId", String(describing: topMsgId)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -5804,6 +5905,43 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func getQuickReplies(hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.QuickReplies>) {
let buffer = Buffer()
buffer.appendInt32(-729550168)
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getQuickReplies", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.QuickReplies? in
let reader = BufferReader(buffer)
var result: Api.messages.QuickReplies?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.QuickReplies
}
return result
})
}
}
public extension Api.functions.messages {
static func getQuickReplyMessages(flags: Int32, shortcutId: Int32, id: [Int32]?, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Messages>) {
let buffer = Buffer()
buffer.appendInt32(-1801153085)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(shortcutId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(id!.count))
for item in id! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getQuickReplyMessages", parameters: [("flags", String(describing: flags)), ("shortcutId", String(describing: shortcutId)), ("id", String(describing: id)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in
let reader = BufferReader(buffer)
var result: Api.messages.Messages?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.messages.Messages
}
return result
})
}
}
public extension Api.functions.messages {
static func getRecentLocations(peer: Api.InputPeer, limit: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Messages>) {
let buffer = Buffer()
@ -6566,6 +6704,25 @@ public extension Api.functions.messages {
})
}
}
public extension Api.functions.messages {
static func reorderQuickReplies(order: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1613961479)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "messages.reorderQuickReplies", parameters: [("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.messages {
static func reorderStickerSets(flags: Int32, order: [Int64]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
@ -7029,9 +7186,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func sendInlineBotResult(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, randomId: Int64, queryId: Int64, id: String, scheduleDate: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendInlineBotResult(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, randomId: Int64, queryId: Int64, id: String, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-138647366)
buffer.appendInt32(-407001673)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {replyTo!.serialize(buffer, true)}
@ -7040,7 +7197,8 @@ public extension Api.functions.messages {
serializeString(id, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.sendInlineBotResult", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("randomId", String(describing: randomId)), ("queryId", String(describing: queryId)), ("id", String(describing: id)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeString(quickReplyShortcut!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.sendInlineBotResult", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("randomId", String(describing: randomId)), ("queryId", String(describing: queryId)), ("id", String(describing: id)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -7051,9 +7209,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func sendMedia(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, media: Api.InputMedia, message: String, randomId: Int64, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendMedia(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, media: Api.InputMedia, message: String, randomId: Int64, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(1926021693)
buffer.appendInt32(-10487971)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {replyTo!.serialize(buffer, true)}
@ -7068,7 +7226,8 @@ public extension Api.functions.messages {
}}
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.sendMedia", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("media", String(describing: media)), ("message", String(describing: message)), ("randomId", String(describing: randomId)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeString(quickReplyShortcut!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.sendMedia", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("media", String(describing: media)), ("message", String(describing: message)), ("randomId", String(describing: randomId)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -7079,9 +7238,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func sendMessage(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, message: String, randomId: Int64, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendMessage(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, message: String, randomId: Int64, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(671943023)
buffer.appendInt32(1750387040)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {replyTo!.serialize(buffer, true)}
@ -7095,7 +7254,8 @@ public extension Api.functions.messages {
}}
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.sendMessage", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("message", String(describing: message)), ("randomId", String(describing: randomId)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeString(quickReplyShortcut!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.sendMessage", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("message", String(describing: message)), ("randomId", String(describing: randomId)), ("replyMarkup", String(describing: replyMarkup)), ("entities", String(describing: entities)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -7106,9 +7266,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func sendMultiMedia(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, multiMedia: [Api.InputSingleMedia], scheduleDate: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendMultiMedia(flags: Int32, peer: Api.InputPeer, replyTo: Api.InputReplyTo?, multiMedia: [Api.InputSingleMedia], scheduleDate: Int32?, sendAs: Api.InputPeer?, quickReplyShortcut: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(1164872071)
buffer.appendInt32(-2027543192)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {replyTo!.serialize(buffer, true)}
@ -7119,7 +7279,24 @@ public extension Api.functions.messages {
}
if Int(flags) & Int(1 << 10) != 0 {serializeInt32(scheduleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.sendMultiMedia", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("multiMedia", String(describing: multiMedia)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
if Int(flags) & Int(1 << 17) != 0 {serializeString(quickReplyShortcut!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.sendMultiMedia", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("replyTo", String(describing: replyTo)), ("multiMedia", String(describing: multiMedia)), ("scheduleDate", String(describing: scheduleDate)), ("sendAs", String(describing: sendAs)), ("quickReplyShortcut", String(describing: quickReplyShortcut))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.messages {
static func sendQuickReplyMessages(peer: Api.InputPeer, shortcutId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(857029332)
peer.serialize(buffer, true)
serializeInt32(shortcutId, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.sendQuickReplyMessages", parameters: [("peer", String(describing: peer)), ("shortcutId", String(describing: shortcutId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
@ -8795,6 +8972,113 @@ public extension Api.functions.premium {
})
}
}
public extension Api.functions.smsjobs {
static func finishJob(flags: Int32, jobId: String, error: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1327415076)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(jobId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(error!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "smsjobs.finishJob", parameters: [("flags", String(describing: flags)), ("jobId", String(describing: jobId)), ("error", String(describing: error))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func getSmsJob(jobId: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.SmsJob>) {
let buffer = Buffer()
buffer.appendInt32(2005766191)
serializeString(jobId, buffer: buffer, boxed: false)
return (FunctionDescription(name: "smsjobs.getSmsJob", parameters: [("jobId", String(describing: jobId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.SmsJob? in
let reader = BufferReader(buffer)
var result: Api.SmsJob?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.SmsJob
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func getStatus() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.smsjobs.Status>) {
let buffer = Buffer()
buffer.appendInt32(279353576)
return (FunctionDescription(name: "smsjobs.getStatus", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.smsjobs.Status? in
let reader = BufferReader(buffer)
var result: Api.smsjobs.Status?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.smsjobs.Status
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func isEligibleToJoin() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.smsjobs.EligibilityToJoin>) {
let buffer = Buffer()
buffer.appendInt32(249313744)
return (FunctionDescription(name: "smsjobs.isEligibleToJoin", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.smsjobs.EligibilityToJoin? in
let reader = BufferReader(buffer)
var result: Api.smsjobs.EligibilityToJoin?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.smsjobs.EligibilityToJoin
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func join() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1488007635)
return (FunctionDescription(name: "smsjobs.join", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func leave() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1734824589)
return (FunctionDescription(name: "smsjobs.leave", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.smsjobs {
static func updateSettings(flags: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(155164863)
serializeInt32(flags, buffer: buffer, boxed: false)
return (FunctionDescription(name: "smsjobs.updateSettings", parameters: [("flags", String(describing: flags))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.stats {
static func getBroadcastStats(flags: Int32, channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.stats.BroadcastStats>) {
let buffer = Buffer()

View File

@ -126,7 +126,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? {
switch messsage {
case let .message(_, _, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
let chatPeerId = messagePeerId
return chatPeerId.peerId
case let .messageEmpty(_, _, peerId):
@ -142,7 +142,7 @@ func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? {
func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
switch message {
case let .message(_, _, fromId, _, chatPeerId, savedPeerId, fwdHeader, viaBotId, replyTo, _, _, media, _, entities, _, _, _, _, _, _, _, _, _):
case let .message(_, _, fromId, _, chatPeerId, savedPeerId, fwdHeader, viaBotId, replyTo, _, _, media, _, entities, _, _, _, _, _, _, _, _, _, _):
let peerId: PeerId = chatPeerId.peerId
var result = [peerId]
@ -263,7 +263,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: ReferencedReplyMessageIds, generalIds: [MessageId])? {
switch message {
case let .message(_, id, _, _, chatPeerId, _, _, _, replyTo, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, id, _, _, chatPeerId, _, _, _, replyTo, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
if let replyTo = replyTo {
let peerId: PeerId = chatPeerId.peerId
@ -597,7 +597,7 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
extension StoreMessage {
convenience init?(apiMessage: Api.Message, accountPeerId: PeerId, peerIsForum: Bool, namespace: MessageId.Namespace = Namespaces.Message.Cloud) {
switch apiMessage {
case let .message(flags, id, fromId, boosts, chatPeerId, savedPeerId, fwdFrom, viaBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod):
case let .message(flags, id, fromId, boosts, chatPeerId, savedPeerId, fwdFrom, viaBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, _):
let resolvedFromId = fromId?.peerId ?? chatPeerId.peerId
let peerId: PeerId

View File

@ -174,7 +174,7 @@ private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox,
}
}
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime))
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime, quickReplyShortcutId: nil))
|> map { result -> Api.Updates? in
return result
}
@ -304,7 +304,7 @@ func _internal_requestEditLiveLocation(postbox: Postbox, network: Network, state
inputMedia = .inputMediaGeoLive(flags: 1 << 0, geoPoint: .inputGeoPoint(flags: 0, lat: media.latitude, long: media.longitude, accuracyRadius: nil), heading: nil, period: nil, proximityNotificationRadius: nil)
}
return network.request(Api.functions.messages.editMessage(flags: 1 << 14, peer: inputPeer, id: messageId.id, message: nil, media: inputMedia, replyMarkup: nil, entities: nil, scheduleDate: nil))
return network.request(Api.functions.messages.editMessage(flags: 1 << 14, peer: inputPeer, id: messageId.id, message: nil, media: inputMedia, replyMarkup: nil, entities: nil, scheduleDate: nil, quickReplyShortcutId: nil))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil)

View File

@ -410,7 +410,7 @@ private func sendUploadedMessageContent(
}
}
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), info: .acknowledgement, tag: dependencyTag)
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), info: .acknowledgement, tag: dependencyTag)
case let .media(inputMedia, text):
if bubbleUpEmojiOrStickersets {
flags |= Int32(1 << 15)
@ -432,7 +432,7 @@ private func sendUploadedMessageContent(
}
}
sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), tag: dependencyTag)
|> map(NetworkRequestResult.result)
case let .forward(sourceInfo):
var topMsgId: Int32?
@ -442,7 +442,7 @@ private func sendUploadedMessageContent(
}
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), tag: dependencyTag)
|> map(NetworkRequestResult.result)
} else {
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
@ -468,7 +468,7 @@ private func sendUploadedMessageContent(
}
}
sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
|> map(NetworkRequestResult.result)
case .messageScreenshot:
let replyTo: Api.InputReplyTo
@ -633,7 +633,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
}
}
sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
|> `catch` { _ -> Signal<Api.Updates, NoError> in
return .complete()
}
@ -651,7 +651,7 @@ private func sendMessageContent(account: Account, peerId: PeerId, attributes: [M
}
}
sendMessageRequest = account.network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
sendMessageRequest = account.network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
|> `catch` { _ -> Signal<Api.Updates, NoError> in
return .complete()
}

View File

@ -1444,7 +1444,7 @@ public final class AccountViewTracker {
if i < slice.count {
let value = result[i]
transaction.updatePeerCachedData(peerIds: Set([slice[i].0]), update: { _, cachedData in
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, themeEmoticon: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, premiumGiftOptions: [], voiceMessagesAvailable: true, wallpaper: nil, flags: [])
var cachedData = cachedData as? CachedUserData ?? CachedUserData(about: nil, botInfo: nil, editableBotInfo: nil, peerStatusSettings: nil, pinnedMessageId: nil, isBlocked: false, commonGroupCount: 0, voiceCallsAvailable: true, videoCallsAvailable: true, callsPrivate: true, canPinMessages: true, hasScheduledMessages: true, autoremoveTimeout: .unknown, themeEmoticon: nil, photo: .unknown, personalPhoto: .unknown, fallbackPhoto: .unknown, premiumGiftOptions: [], voiceMessagesAvailable: true, wallpaper: nil, flags: [], businessHours: nil, businessLocation: nil)
var flags = cachedData.flags
if case .boolTrue = value {
flags.insert(.premiumRequired)

View File

@ -96,7 +96,7 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
var updatedTimestamp: Int32?
if let apiMessage = apiMessage {
switch apiMessage {
case let .message(_, _, _, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
updatedTimestamp = date
case .messageEmpty:
break

View File

@ -878,7 +878,7 @@ public final class PendingMessageManager {
} else if let inputSourcePeerId = forwardPeerIds.first, let inputSourcePeer = transaction.getPeer(inputSourcePeerId).flatMap(apiInputPeer) {
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messages[0].0.id)
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), tag: dependencyTag)
} else {
assertionFailure()
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid forward source"))
@ -993,7 +993,7 @@ public final class PendingMessageManager {
}
}
sendMessageRequest = network.request(Api.functions.messages.sendMultiMedia(flags: flags, peer: inputPeer, replyTo: replyTo, multiMedia: singleMedias, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
sendMessageRequest = network.request(Api.functions.messages.sendMultiMedia(flags: flags, peer: inputPeer, replyTo: replyTo, multiMedia: singleMedias, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
}
return sendMessageRequest
@ -1291,7 +1291,7 @@ public final class PendingMessageManager {
}
}
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), info: .acknowledgement, tag: dependencyTag)
sendMessageRequest = network.requestWithAdditionalInfo(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyTo: replyTo, message: message.text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), info: .acknowledgement, tag: dependencyTag)
case let .media(inputMedia, text):
if bubbleUpEmojiOrStickersets {
flags |= Int32(1 << 15)
@ -1356,7 +1356,7 @@ public final class PendingMessageManager {
}
}
sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
sendMessageRequest = network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyTo: replyTo, media: inputMedia, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), tag: dependencyTag)
|> map(NetworkRequestResult.result)
case let .forward(sourceInfo):
var topMsgId: Int32?
@ -1366,7 +1366,7 @@ public final class PendingMessageManager {
}
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer), tag: dependencyTag)
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil), tag: dependencyTag)
|> map(NetworkRequestResult.result)
} else {
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
@ -1429,7 +1429,7 @@ public final class PendingMessageManager {
}
}
sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer))
sendMessageRequest = network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyTo: replyTo, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
|> map(NetworkRequestResult.result)
case .messageScreenshot:
let replyTo: Api.InputReplyTo

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 174
return 176
}
public func parseMessage(_ data: Data!) -> Any! {

View File

@ -58,7 +58,7 @@ class UpdateMessageService: NSObject, MTMessageService {
self.putNext(groups)
}
case let .updateShortChatMessage(flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyHeader, entities, ttlPeriod):
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: .peerUser(userId: fromId), fromBoostsApplied: nil, peerId: Api.Peer.peerChat(chatId: chatId), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod)
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: .peerUser(userId: fromId), fromBoostsApplied: nil, peerId: Api.Peer.peerChat(chatId: chatId), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
if groups.count != 0 {
@ -74,7 +74,7 @@ class UpdateMessageService: NSObject, MTMessageService {
let generatedPeerId = Api.Peer.peerUser(userId: userId)
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, fromBoostsApplied: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod)
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, fromBoostsApplied: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
if groups.count != 0 {

View File

@ -104,7 +104,7 @@ extension Api.MessageMedia {
extension Api.Message {
var rawId: Int32 {
switch self {
case let .message(_, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
return id
case let .messageEmpty(_, id, _):
return id
@ -115,7 +115,7 @@ extension Api.Message {
func id(namespace: MessageId.Namespace = Namespaces.Message.Cloud) -> MessageId? {
switch self {
case let .message(_, id, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, id, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
let peerId: PeerId = messagePeerId.peerId
return MessageId(peerId: peerId, namespace: namespace, id: id)
case let .messageEmpty(_, id, peerId):
@ -132,7 +132,7 @@ extension Api.Message {
var peerId: PeerId? {
switch self {
case let .message(_, _, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
let peerId: PeerId = messagePeerId.peerId
return peerId
case let .messageEmpty(_, _, peerId):
@ -145,7 +145,7 @@ extension Api.Message {
var timestamp: Int32? {
switch self {
case let .message(_, _, _, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
return date
case let .messageService(_, _, _, _, _, date, _, _):
return date
@ -156,7 +156,7 @@ extension Api.Message {
var preCachedResources: [(MediaResource, Data)]? {
switch self {
case let .message(_, _, _, _, _, _, _, _, _, _, _, media, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, _, _, _, _, _, _, _, media, _, _, _, _, _, _, _, _, _, _, _, _):
return media?.preCachedResources
default:
return nil
@ -165,7 +165,7 @@ extension Api.Message {
var preCachedStories: [StoryId: Api.StoryItem]? {
switch self {
case let .message(_, _, _, _, _, _, _, _, _, _, _, media, _, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, _, _, _, _, _, _, _, media, _, _, _, _, _, _, _, _, _, _, _, _):
return media?.preCachedStories
default:
return nil

View File

@ -247,6 +247,183 @@ public final class EditableBotInfo: PostboxCoding, Equatable {
}
}
public final class TelegramBusinessHours: Equatable, Codable {
public struct WorkingTimeInterval: Equatable, Codable {
private enum CodingKeys: String, CodingKey {
case startMinute
case endMinute
}
public let startMinute: Int
public let endMinute: Int
public init(startMinute: Int, endMinute: Int) {
self.startMinute = startMinute
self.endMinute = endMinute
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.startMinute = Int(try container.decode(Int32.self, forKey: .startMinute))
self.endMinute = Int(try container.decode(Int32.self, forKey: .endMinute))
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(Int32(clamping: self.startMinute), forKey: .startMinute)
try container.encode(Int32(clamping: self.endMinute), forKey: .endMinute)
}
public static func ==(lhs: WorkingTimeInterval, rhs: WorkingTimeInterval) -> Bool {
if lhs.startMinute != rhs.startMinute {
return false
}
if lhs.endMinute != rhs.endMinute {
return false
}
return true
}
}
public let timezoneId: String
public let weeklyTimeIntervals: [WorkingTimeInterval]
public init(timezoneId: String, weeklyTimeIntervals: [WorkingTimeInterval]) {
self.timezoneId = timezoneId
self.weeklyTimeIntervals = weeklyTimeIntervals
}
public static func ==(lhs: TelegramBusinessHours, rhs: TelegramBusinessHours) -> Bool {
if lhs.timezoneId != rhs.timezoneId {
return false
}
if lhs.weeklyTimeIntervals != rhs.weeklyTimeIntervals {
return false
}
return true
}
public enum WeekDay {
case closed
case open
case intervals([WorkingTimeInterval])
}
public func splitIntoWeekDays() -> [WeekDay] {
var mappedDays: [[WorkingTimeInterval]] = Array(repeating: [], count: 7)
for interval in self.weeklyTimeIntervals {
let startDayIndex = interval.startMinute / (24 * 60)
if startDayIndex < 0 || startDayIndex >= 7 {
continue
}
let startTimeInsideDay = interval.startMinute - startDayIndex * (24 * 60)
let endTimeInsideDay = interval.endMinute - startDayIndex * (24 * 60)
mappedDays[startDayIndex].append(WorkingTimeInterval(
startMinute: startTimeInsideDay,
endMinute: endTimeInsideDay
))
}
return mappedDays.map { day -> WeekDay in
var minutes = IndexSet()
for interval in day {
minutes.insert(integersIn: interval.startMinute ..< interval.endMinute)
}
if minutes.isEmpty {
return .closed
} else if minutes == IndexSet(integersIn: 0 ..< 24 * 60) {
return .open
} else {
return .intervals(day)
}
}
}
}
public final class TelegramBusinessLocation: Equatable, Codable {
public struct Coordinates: Equatable, Codable {
public let latitude: Double
public let longitude: Double
public init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}
}
public let address: String
public let coordinates: Coordinates?
public init(address: String, coordinates: Coordinates?) {
self.address = address
self.coordinates = coordinates
}
public static func ==(lhs: TelegramBusinessLocation, rhs: TelegramBusinessLocation) -> Bool {
if lhs.address != rhs.address {
return false
}
if lhs.coordinates != rhs.coordinates {
return false
}
return true
}
}
extension TelegramBusinessHours.WorkingTimeInterval {
init(apiInterval: Api.BusinessWeeklyOpen) {
switch apiInterval {
case let .businessWeeklyOpen(startMinute, endMinute):
self.init(startMinute: Int(startMinute), endMinute: Int(endMinute))
}
}
var apiInterval: Api.BusinessWeeklyOpen {
return .businessWeeklyOpen(startMinute: Int32(clamping: self.startMinute), endMinute: Int32(clamping: self.endMinute))
}
}
extension TelegramBusinessHours {
convenience init(apiWorkingHours: Api.BusinessWorkHours) {
switch apiWorkingHours {
case let .businessWorkHours(_, timezoneId, weeklyOpen):
self.init(timezoneId: timezoneId, weeklyTimeIntervals: weeklyOpen.map(TelegramBusinessHours.WorkingTimeInterval.init(apiInterval:)))
}
}
var apiBusinessHours: Api.BusinessWorkHours {
return .businessWorkHours(flags: 0, timezoneId: self.timezoneId, weeklyOpen: self.weeklyTimeIntervals.map(\.apiInterval))
}
}
extension TelegramBusinessLocation.Coordinates {
init?(apiGeoPoint: Api.GeoPoint) {
switch apiGeoPoint {
case let .geoPoint(_, long, lat, _, _):
self.init(latitude: lat, longitude: long)
case .geoPointEmpty:
return nil
}
}
var apiInputGeoPoint: Api.InputGeoPoint {
return .inputGeoPoint(flags: 0, lat: self.latitude, long: self.longitude, accuracyRadius: nil)
}
}
extension TelegramBusinessLocation {
convenience init(apiLocation: Api.BusinessLocation) {
switch apiLocation {
case let .businessLocation(geoPoint, address):
self.init(address: address, coordinates: Coordinates(apiGeoPoint: geoPoint))
}
}
}
public final class CachedUserData: CachedPeerData {
public let about: String?
@ -270,7 +447,8 @@ public final class CachedUserData: CachedPeerData {
public let voiceMessagesAvailable: Bool
public let wallpaper: TelegramWallpaper?
public let flags: CachedUserFlags
public let businessHours: TelegramBusinessHours?
public let businessLocation: TelegramBusinessLocation?
public let peerIds: Set<PeerId>
public let messageIds: Set<MessageId>
public let associatedHistoryMessageId: MessageId? = nil
@ -297,11 +475,13 @@ public final class CachedUserData: CachedPeerData {
self.voiceMessagesAvailable = true
self.wallpaper = nil
self.flags = CachedUserFlags()
self.businessHours = nil
self.businessLocation = nil
self.peerIds = Set()
self.messageIds = Set()
}
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, premiumGiftOptions: [CachedPremiumGiftOption], voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags) {
public init(about: String?, botInfo: BotInfo?, editableBotInfo: EditableBotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout, themeEmoticon: String?, photo: CachedPeerProfilePhoto, personalPhoto: CachedPeerProfilePhoto, fallbackPhoto: CachedPeerProfilePhoto, premiumGiftOptions: [CachedPremiumGiftOption], voiceMessagesAvailable: Bool, wallpaper: TelegramWallpaper?, flags: CachedUserFlags, businessHours: TelegramBusinessHours?, businessLocation: TelegramBusinessLocation?) {
self.about = about
self.botInfo = botInfo
self.editableBotInfo = editableBotInfo
@ -323,6 +503,8 @@ public final class CachedUserData: CachedPeerData {
self.voiceMessagesAvailable = voiceMessagesAvailable
self.wallpaper = wallpaper
self.flags = flags
self.businessHours = businessHours
self.businessLocation = businessLocation
self.peerIds = Set<PeerId>()
@ -375,6 +557,9 @@ public final class CachedUserData: CachedPeerData {
messageIds.insert(pinnedMessageId)
}
self.messageIds = messageIds
self.businessHours = decoder.decodeCodable(TelegramBusinessHours.self, forKey: "bhrs")
self.businessLocation = decoder.decodeCodable(TelegramBusinessLocation.self, forKey: "bloc")
}
public func encode(_ encoder: PostboxEncoder) {
@ -435,6 +620,18 @@ public final class CachedUserData: CachedPeerData {
}
encoder.encodeInt32(self.flags.rawValue, forKey: "fl")
if let businessHours = self.businessHours {
encoder.encodeCodable(businessHours, forKey: "bhrs")
} else {
encoder.encodeNil(forKey: "bhrs")
}
if let businessLocation = self.businessLocation {
encoder.encodeCodable(businessLocation, forKey: "bloc")
} else {
encoder.encodeNil(forKey: "bloc")
}
}
public func isEqual(to: CachedPeerData) -> Bool {
@ -448,91 +645,105 @@ public final class CachedUserData: CachedPeerData {
if other.canPinMessages != self.canPinMessages {
return false
}
if other.businessHours != self.businessHours {
return false
}
if other.businessLocation != self.businessLocation {
return false
}
return other.about == self.about && other.botInfo == self.botInfo && other.editableBotInfo == self.editableBotInfo && self.peerStatusSettings == other.peerStatusSettings && self.isBlocked == other.isBlocked && self.commonGroupCount == other.commonGroupCount && self.voiceCallsAvailable == other.voiceCallsAvailable && self.videoCallsAvailable == other.videoCallsAvailable && self.callsPrivate == other.callsPrivate && self.hasScheduledMessages == other.hasScheduledMessages && self.autoremoveTimeout == other.autoremoveTimeout && self.themeEmoticon == other.themeEmoticon && self.photo == other.photo && self.personalPhoto == other.personalPhoto && self.fallbackPhoto == other.fallbackPhoto && self.premiumGiftOptions == other.premiumGiftOptions && self.voiceMessagesAvailable == other.voiceMessagesAvailable && self.flags == other.flags && self.wallpaper == other.wallpaper
}
public func withUpdatedAbout(_ about: String?) -> CachedUserData {
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedBotInfo(_ botInfo: BotInfo?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedEditableBotInfo(_ editableBotInfo: EditableBotInfo?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedIsBlocked(_ isBlocked: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedCommonGroupCount(_ commonGroupCount: Int32) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedVoiceCallsAvailable(_ voiceCallsAvailable: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedVideoCallsAvailable(_ videoCallsAvailable: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedCallsPrivate(_ callsPrivate: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedCanPinMessages(_ canPinMessages: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedThemeEmoticon(_ themeEmoticon: String?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedPhoto(_ photo: CachedPeerProfilePhoto) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedPersonalPhoto(_ personalPhoto: CachedPeerProfilePhoto) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedFallbackPhoto(_ fallbackPhoto: CachedPeerProfilePhoto) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedPremiumGiftOptions(_ premiumGiftOptions: [CachedPremiumGiftOption]) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedVoiceMessagesAvailable(_ voiceMessagesAvailable: Bool) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedWallpaper(_ wallpaper: TelegramWallpaper?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedFlags(_ flags: CachedUserFlags) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags)
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: flags, businessHours: self.businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedBusinessHours(_ businessHours: TelegramBusinessHours?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: businessHours, businessLocation: self.businessLocation)
}
public func withUpdatedBusinessLocation(_ businessLocation: TelegramBusinessLocation?) -> CachedUserData {
return CachedUserData(about: self.about, botInfo: self.botInfo, editableBotInfo: self.editableBotInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, themeEmoticon: self.themeEmoticon, photo: self.photo, personalPhoto: self.personalPhoto, fallbackPhoto: self.fallbackPhoto, premiumGiftOptions: self.premiumGiftOptions, voiceMessagesAvailable: self.voiceMessagesAvailable, wallpaper: self.wallpaper, flags: self.flags, businessHours: self.businessHours, businessLocation: businessLocation)
}
}

View File

@ -280,6 +280,7 @@ private enum PreferencesKeyValues: Int32 {
case audioTranscriptionTrialState = 33
case didCacheSavedMessageTagsPrefix = 34
case displaySavedChatsAsTopics = 35
case shortcutMessages = 36
}
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
@ -463,6 +464,12 @@ public struct PreferencesKeys {
key.setInt32(0, value: PreferencesKeyValues.displaySavedChatsAsTopics.rawValue)
return key
}
public static func shortcutMessages() -> ValueBoxKey {
let key = ValueBoxKey(length: 4)
key.setInt32(0, value: PreferencesKeyValues.shortcutMessages.rawValue)
return key
}
}
private enum SharedDataKeyValues: Int32 {

View File

@ -105,5 +105,65 @@ public extension TelegramEngine {
|> ignoreValues
|> then(remoteApply)
}
public func updateAccountBusinessHours(businessHours: TelegramBusinessHours?) -> Signal<Never, NoError> {
let peerId = self.account.peerId
var flags: Int32 = 0
if businessHours != nil {
flags |= 1 << 0
}
let remoteApply: Signal<Never, NoError> = self.account.network.request(Api.functions.account.updateBusinessWorkHours(flags: flags, businessWorkHours: businessHours?.apiBusinessHours))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> ignoreValues
return self.account.postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
let current = current as? CachedUserData ?? CachedUserData()
return current.withUpdatedBusinessHours(businessHours)
})
}
|> ignoreValues
|> then(remoteApply)
}
public func updateAccountBusinessLocation(businessLocation: TelegramBusinessLocation?) -> Signal<Never, NoError> {
let peerId = self.account.peerId
var flags: Int32 = 0
var inputGeoPoint: Api.InputGeoPoint?
var inputAddress: String?
if let businessLocation {
flags |= 1 << 0
inputGeoPoint = businessLocation.coordinates?.apiInputGeoPoint ?? .inputGeoPointEmpty
inputAddress = businessLocation.address
}
let remoteApply: Signal<Never, NoError> = self.account.network.request(Api.functions.account.updateBusinessLocation(flags: flags, geoPoint: inputGeoPoint, address: inputAddress))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> ignoreValues
return self.account.postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
let current = current as? CachedUserData ?? CachedUserData()
return current.withUpdatedBusinessLocation(businessLocation)
})
}
|> ignoreValues
|> then(remoteApply)
}
public func shortcutMessages() -> Signal<QuickReplyMessageShortcutsState, NoError> {
return _internal_shortcutMessages(account: self.account)
}
public func updateShortcutMessages(state: QuickReplyMessageShortcutsState) {
let _ = _internal_updateShortcutMessages(account: self.account, state: state).startStandalone()
}
}
}

View File

@ -4,6 +4,7 @@ import Postbox
public typealias EngineExportedPeerInvitation = ExportedInvitation
public typealias EngineSecretChatKeyFingerprint = SecretChatKeyFingerprint
public enum EnginePeerCachedInfoItem<T> {
case known(T)
case unknown
@ -1443,6 +1444,61 @@ public extension TelegramEngine.EngineData.Item {
}
}
}
public struct BusinessHours: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = TelegramBusinessHours?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.businessHours
} else {
return nil
}
}
}
public struct BusinessLocation: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = TelegramBusinessLocation?
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.businessLocation
} else {
return nil
}
}
}
}
}

View File

@ -14,7 +14,7 @@ func _internal_forwardGameWithScore(account: Account, messageId: MessageId, to p
flags |= (1 << 13)
}
return account.network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: fromInputPeer, id: [messageId.id], randomId: [Int64.random(in: Int64.min ... Int64.max)], toPeer: toInputPeer, topMsgId: threadId.flatMap { Int32(clamping: $0) }, scheduleDate: nil, sendAs: sendAsInputPeer))
return account.network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: fromInputPeer, id: [messageId.id], randomId: [Int64.random(in: Int64.min ... Int64.max)], toPeer: toInputPeer, topMsgId: threadId.flatMap { Int32(clamping: $0) }, scheduleDate: nil, sendAs: sendAsInputPeer, quickReplyShortcut: nil))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil)

View File

@ -135,7 +135,7 @@ func _internal_requestClosePoll(postbox: Postbox, network: Network, stateManager
pollMediaFlags |= 1 << 1
}
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(flags: pollMediaFlags, poll: .poll(id: poll.pollId.id, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities), replyMarkup: nil, entities: nil, scheduleDate: nil))
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(flags: pollMediaFlags, poll: .poll(id: poll.pollId.id, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities), replyMarkup: nil, entities: nil, scheduleDate: nil, quickReplyShortcutId: nil))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil)

View File

@ -0,0 +1,157 @@
import Foundation
import Postbox
import SwiftSignalKit
import TelegramApi
import MtProtoKit
public final class QuickReplyMessageShortcut: Codable, Equatable {
private final class CodableMessage: Codable {
let message: Message
init(message: Message) {
self.message = message
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
var media: [Media] = []
if let mediaData = try container.decodeIfPresent(Data.self, forKey: "media") {
if let value = PostboxDecoder(buffer: MemoryBuffer(data: mediaData)).decodeRootObject() as? Media {
media.append(value)
}
}
var attributes: [MessageAttribute] = []
if let attributesData = try container.decodeIfPresent([Data].self, forKey: "attributes") {
for attribute in attributesData {
if let value = PostboxDecoder(buffer: MemoryBuffer(data: attribute)).decodeRootObject() as? MessageAttribute {
attributes.append(value)
}
}
}
self.message = Message(
stableId: 0,
stableVersion: 0,
id: MessageId(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(0)), namespace: 0, id: 0),
globallyUniqueId: nil,
groupingKey: nil,
groupInfo: nil,
threadId: nil,
timestamp: 0,
flags: [],
tags: [],
globalTags: [],
localTags: [],
customTags: [],
forwardInfo: nil,
author: nil,
text: try container.decode(String.self, forKey: "text"),
attributes: attributes,
media: media,
peers: SimpleDictionary(),
associatedMessages: SimpleDictionary(),
associatedMessageIds: [],
associatedMedia: [:],
associatedThreadInfo: nil,
associatedStories: [:]
)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
if let media = self.message.media.first {
let mediaEncoder = PostboxEncoder()
mediaEncoder.encodeRootObject(media)
try container.encode(mediaEncoder.makeData(), forKey: "media")
}
var attributesData: [Data] = []
for attribute in self.message.attributes {
let attributeEncoder = PostboxEncoder()
attributeEncoder.encodeRootObject(attribute)
attributesData.append(attributeEncoder.makeData())
}
try container.encode(attributesData, forKey: "attributes")
try container.encode(self.message.text, forKey: "text")
}
}
public let id: Int32
public let shortcut: String
public let messages: [EngineMessage]
public init(id: Int32, shortcut: String, messages: [EngineMessage]) {
self.id = id
self.shortcut = shortcut
self.messages = messages
}
public static func ==(lhs: QuickReplyMessageShortcut, rhs: QuickReplyMessageShortcut) -> Bool {
if lhs.id != rhs.id {
return false
}
if lhs.shortcut != rhs.shortcut {
return false
}
if lhs.messages != rhs.messages {
return false
}
return true
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.id = try container.decode(Int32.self, forKey: "id")
self.shortcut = try container.decode(String.self, forKey: "shortcut")
self.messages = try container.decode([CodableMessage].self, forKey: "messages").map { EngineMessage($0.message) }
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.id, forKey: "id")
try container.encode(self.shortcut, forKey: "shortcut")
try container.encode(self.messages.map { CodableMessage(message: $0._asMessage()) }, forKey: "messages")
}
}
public final class QuickReplyMessageShortcutsState: Codable, Equatable {
public let shortcuts: [QuickReplyMessageShortcut]
public init(shortcuts: [QuickReplyMessageShortcut]) {
self.shortcuts = shortcuts
}
public static func ==(lhs: QuickReplyMessageShortcutsState, rhs: QuickReplyMessageShortcutsState) -> Bool {
if lhs.shortcuts != rhs.shortcuts {
return false
}
return true
}
}
func _internal_shortcutMessages(account: Account) -> Signal<QuickReplyMessageShortcutsState, NoError> {
let viewKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.shortcutMessages()]))
return account.postbox.combinedView(keys: [viewKey])
|> map { views -> QuickReplyMessageShortcutsState in
guard let view = views.views[viewKey] as? PreferencesView else {
return QuickReplyMessageShortcutsState(shortcuts: [])
}
guard let value = view.values[PreferencesKeys.shortcutMessages()]?.get(QuickReplyMessageShortcutsState.self) else {
return QuickReplyMessageShortcutsState(shortcuts: [])
}
return value
}
}
func _internal_updateShortcutMessages(account: Account, state: QuickReplyMessageShortcutsState) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Void in
transaction.setPreferencesEntry(key: PreferencesKeys.shortcutMessages(), value: PreferencesEntry(state))
}
|> ignoreValues
}

View File

@ -216,7 +216,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
let _ = accountUser
switch fullUser {
case let .userFull(_, _, _, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _, _, _, _, _, _):
case let .userFull(_, _, _, _, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: userFullNotifySettings)])
}
@ -228,7 +228,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
previous = CachedUserData()
}
switch fullUser {
case let .userFull(userFullFlags, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories):
case let .userFull(userFullFlags, _, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories, businessWorkHours, businessLocation):
let _ = stories
let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:))
let isBlocked = (userFullFlags & (1 << 0)) != 0
@ -286,6 +286,16 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
let wallpaper = userWallpaper.flatMap { TelegramWallpaper(apiWallpaper: $0) }
var mappedBusinessHours: TelegramBusinessHours?
if let businessWorkHours {
mappedBusinessHours = TelegramBusinessHours(apiWorkingHours: businessWorkHours)
}
var mappedBusinessLocation: TelegramBusinessLocation?
if let businessLocation {
mappedBusinessLocation = TelegramBusinessLocation(apiLocation: businessLocation)
}
return previous.withUpdatedAbout(userFullAbout)
.withUpdatedBotInfo(botInfo)
.withUpdatedEditableBotInfo(editableBotInfo)
@ -307,6 +317,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
.withUpdatedVoiceMessagesAvailable(voiceMessagesAvailable)
.withUpdatedWallpaper(wallpaper)
.withUpdatedFlags(flags)
.withUpdatedBusinessHours(mappedBusinessHours)
.withUpdatedBusinessLocation(mappedBusinessLocation)
}
})
}

View File

@ -436,7 +436,7 @@ swift_library(
"//submodules/TelegramUI/Components/Settings/ChatbotSetupScreen",
"//submodules/TelegramUI/Components/Settings/BusinessLocationSetupScreen",
"//submodules/TelegramUI/Components/Settings/BusinessHoursSetupScreen",
"//submodules/TelegramUI/Components/Settings/GreetingMessageSetupScreen",
"//submodules/TelegramUI/Components/Settings/AutomaticBusinessMessageSetupScreen",
] + select({
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
"//build-system:ios_sim_arm64": [],

View File

@ -97,6 +97,8 @@ public final class ChatRecentActionsController: TelegramBaseController {
}, sendContextResult: { _, _, _, _ in
return false
}, sendBotCommand: { _, _ in
}, sendShortcut: { _ in
}, openEditShortcuts: {
}, sendBotStart: { _ in
}, botSwitchChatWithPayload: { _, _ in
}, beginMediaRecording: { _ in

View File

@ -27,6 +27,7 @@ public final class ChatListNavigationBar: Component {
public let statusBarHeight: CGFloat
public let sideInset: CGFloat
public let isSearchActive: Bool
public let isSearchEnabled: Bool
public let primaryContent: ChatListHeaderComponent.Content?
public let secondaryContent: ChatListHeaderComponent.Content?
public let secondaryTransition: CGFloat
@ -48,6 +49,7 @@ public final class ChatListNavigationBar: Component {
statusBarHeight: CGFloat,
sideInset: CGFloat,
isSearchActive: Bool,
isSearchEnabled: Bool,
primaryContent: ChatListHeaderComponent.Content?,
secondaryContent: ChatListHeaderComponent.Content?,
secondaryTransition: CGFloat,
@ -68,6 +70,7 @@ public final class ChatListNavigationBar: Component {
self.statusBarHeight = statusBarHeight
self.sideInset = sideInset
self.isSearchActive = isSearchActive
self.isSearchEnabled = isSearchEnabled
self.primaryContent = primaryContent
self.secondaryContent = secondaryContent
self.secondaryTransition = secondaryTransition
@ -102,6 +105,9 @@ public final class ChatListNavigationBar: Component {
if lhs.isSearchActive != rhs.isSearchActive {
return false
}
if lhs.isSearchEnabled != rhs.isSearchEnabled {
return false
}
if lhs.primaryContent != rhs.primaryContent {
return false
}
@ -316,6 +322,9 @@ public final class ChatListNavigationBar: Component {
searchContentNode.updateLayout(size: searchSize, leftInset: component.sideInset, rightInset: component.sideInset, transition: transition.containedViewLayoutTransition)
transition.setAlpha(view: searchContentNode.view, alpha: component.isSearchEnabled ? 1.0 : 0.5)
searchContentNode.isUserInteractionEnabled = component.isSearchEnabled
let headerTransition = transition
let storiesOffsetFraction: CGFloat
@ -520,6 +529,7 @@ public final class ChatListNavigationBar: Component {
statusBarHeight: component.statusBarHeight,
sideInset: component.sideInset,
isSearchActive: component.isSearchActive,
isSearchEnabled: component.isSearchEnabled,
primaryContent: component.primaryContent,
secondaryContent: component.secondaryContent,
secondaryTransition: component.secondaryTransition,

View File

@ -29,6 +29,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
public let placeholder: String
public let autocapitalizationType: UITextAutocapitalizationType
public let autocorrectionType: UITextAutocorrectionType
public let characterLimit: Int?
public let updated: ((String) -> Void)?
public let tag: AnyObject?
@ -41,6 +42,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
placeholder: String,
autocapitalizationType: UITextAutocapitalizationType = .sentences,
autocorrectionType: UITextAutocorrectionType = .default,
characterLimit: Int? = nil,
updated: ((String) -> Void)?,
tag: AnyObject? = nil
) {
@ -52,6 +54,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
self.placeholder = placeholder
self.autocapitalizationType = autocapitalizationType
self.autocorrectionType = autocorrectionType
self.characterLimit = characterLimit
self.updated = updated
self.tag = tag
}
@ -81,6 +84,9 @@ public final class ListMultilineTextFieldItemComponent: Component {
if lhs.autocorrectionType != rhs.autocorrectionType {
return false
}
if lhs.characterLimit != rhs.characterLimit {
return false
}
if (lhs.updated == nil) != (rhs.updated == nil) {
return false
}
@ -189,6 +195,7 @@ public final class ListMultilineTextFieldItemComponent: Component {
return NSAttributedString(string: resetText.value, font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor)
},
isOneLineWhenUnfocused: false,
characterLimit: component.characterLimit,
formatMenuAvailability: .none,
lockedFormatAction: {
},

View File

@ -346,6 +346,8 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
}, sendContextResult: { _, _, _, _ in
return false
}, sendBotCommand: { _, _ in
}, sendShortcut: { _ in
}, openEditShortcuts: {
}, sendBotStart: { _ in
}, botSwitchChatWithPayload: { _, _ in
}, beginMediaRecording: { _ in
@ -1162,6 +1164,91 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
interaction.requestLayout(false)
}))
}
if let businessHours = cachedData.businessHours {
//TODO:localize
var businessHoursText: String = ""
let days = businessHours.splitIntoWeekDays()
for i in 0 ..< days.count {
let title: String
//TODO:localize
switch i {
case 0:
title = "Monday"
case 1:
title = "Tuesday"
case 2:
title = "Wednesday"
case 3:
title = "Thursday"
case 4:
title = "Friday"
case 5:
title = "Saturday"
case 6:
title = "Sunday"
default:
title = " "
}
//TODO:localize
if !businessHoursText.isEmpty {
businessHoursText += "\n"
}
businessHoursText += "\(title): "
switch days[i] {
case .open:
businessHoursText += "open 24 hours"
case .closed:
businessHoursText += "closed"
case let .intervals(intervals):
func clipMinutes(_ value: Int) -> Int {
return value % (24 * 60)
}
var resultText: String = ""
for range in intervals {
if !resultText.isEmpty {
resultText.append(", ")
}
let startHours = clipMinutes(range.startMinute) / 60
let startMinutes = clipMinutes(range.startMinute) % 60
let startText = stringForShortTimestamp(hours: Int32(startHours), minutes: Int32(startMinutes), dateTimeFormat: PresentationDateTimeFormat())
let endHours = clipMinutes(range.endMinute) / 60
let endMinutes = clipMinutes(range.endMinute) % 60
let endText = stringForShortTimestamp(hours: Int32(endHours), minutes: Int32(endMinutes), dateTimeFormat: PresentationDateTimeFormat())
resultText.append("\(startText)\u{00a0}- \(endText)")
}
businessHoursText += resultText
}
}
items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: 300, label: "business hours", text: businessHoursText, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: user.isPremium ? enabledPublicBioEntities : enabledPrivateBioEntities), action: nil, longTapAction: bioContextAction, linkItemAction: bioLinkAction, requestLayout: {
interaction.requestLayout(false)
}))
}
if let businessLocation = cachedData.businessLocation {
if let coordinates = businessLocation.coordinates {
let imageSignal = chatMapSnapshotImage(engine: context.engine, resource: MapSnapshotMediaResource(latitude: coordinates.latitude, longitude: coordinates.longitude, width: 90, height: 90))
items[.peerInfo]!.append(PeerInfoScreenAddressItem(
id: 301,
label: "",
text: businessLocation.address,
imageSignal: imageSignal,
action: {
interaction.openLocation()
}
))
} else {
items[.peerInfo]!.append(PeerInfoScreenAddressItem(
id: 301,
label: "",
text: businessLocation.address,
imageSignal: nil,
action: nil
))
}
}
}
if let reactionSourceMessageId = reactionSourceMessageId, !data.isContact {
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 3, text: presentationData.strings.UserInfo_SendMessage, action: {
@ -7529,9 +7616,21 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
private func openLocation() {
guard let data = self.data, let peer = data.peer, let cachedData = data.cachedData as? CachedChannelData, let location = cachedData.peerGeoLocation else {
guard let data = self.data, let peer = data.peer else {
return
}
var location: PeerGeoLocation?
if let cachedData = data.cachedData as? CachedChannelData, let locationValue = cachedData.peerGeoLocation {
location = locationValue
} else if let cachedData = data.cachedData as? CachedUserData, let businessLocation = cachedData.businessLocation, let coordinates = businessLocation.coordinates {
location = PeerGeoLocation(latitude: coordinates.latitude, longitude: coordinates.longitude, address: businessLocation.address)
}
guard let location else {
return
}
let context = self.context
let presentationData = self.presentationData
let map = TelegramMediaMap(latitude: location.latitude, longitude: location.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: MapVenue(title: EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), address: location.address, provider: nil, id: nil, type: nil), liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)

View File

@ -589,6 +589,8 @@ final class PeerSelectionControllerNode: ASDisplayNode {
}, sendContextResult: { _, _, _, _ in
return false
}, sendBotCommand: { _, _ in
}, sendShortcut: { _ in
}, openEditShortcuts: {
}, sendBotStart: { _ in
}, botSwitchChatWithPayload: { _, _ in
}, beginMediaRecording: { _ in

View File

@ -1,8 +1,8 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "GreetingMessageSetupScreen",
module_name = "GreetingMessageSetupScreen",
name = "AutomaticBusinessMessageSetupScreen",
module_name = "AutomaticBusinessMessageSetupScreen",
srcs = glob([
"Sources/**/*.swift",
]),
@ -45,6 +45,7 @@ swift_library(
"//submodules/DateSelectionUI",
"//submodules/TelegramStringFormatting",
"//submodules/TelegramUI/Components/TimeSelectionActionSheet",
"//submodules/TelegramUI/Components/ChatListHeaderComponent",
],
visibility = [
"//visibility:public",

View File

@ -235,6 +235,7 @@ final class GreetingMessageListItemComponent: Component {
tags: [],
customMessageListData: ChatListItemContent.CustomMessageListData(
commandPrefix: nil,
searchQuery: nil,
messageCount: component.count
)
)),

View File

@ -5,7 +5,7 @@ import Postbox
import TelegramCore
import AccountContext
final class GreetingMessageSetupChatContents: ChatCustomContentsProtocol {
final class AutomaticBusinessMessageSetupChatContents: ChatCustomContentsProtocol {
private final class Impl {
let queue: Queue
let context: AccountContext

View File

@ -42,21 +42,21 @@ private let checkIcon: UIImage = {
})!.withRenderingMode(.alwaysTemplate)
}()
final class GreetingMessageSetupScreenComponent: Component {
final class AutomaticBusinessMessageSetupScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext
let mode: GreetingMessageSetupScreen.Mode
let mode: AutomaticBusinessMessageSetupScreen.Mode
init(
context: AccountContext,
mode: GreetingMessageSetupScreen.Mode
mode: AutomaticBusinessMessageSetupScreen.Mode
) {
self.context = context
self.mode = mode
}
static func ==(lhs: GreetingMessageSetupScreenComponent, rhs: GreetingMessageSetupScreenComponent) -> Bool {
static func ==(lhs: AutomaticBusinessMessageSetupScreenComponent, rhs: AutomaticBusinessMessageSetupScreenComponent) -> Bool {
if lhs.context !== rhs.context {
return false
}
@ -124,7 +124,7 @@ final class GreetingMessageSetupScreenComponent: Component {
private var ignoreScrolling: Bool = false
private var isUpdating: Bool = false
private var component: GreetingMessageSetupScreenComponent?
private var component: AutomaticBusinessMessageSetupScreenComponent?
private(set) weak var state: EmptyComponentState?
private var environment: EnvironmentType?
@ -350,7 +350,7 @@ final class GreetingMessageSetupScreenComponent: Component {
guard let component = self.component else {
return
}
let contents = GreetingMessageSetupChatContents(
let contents = AutomaticBusinessMessageSetupChatContents(
context: component.context,
messages: self.messages,
kind: component.mode == .away ? .awayMessageInput : .greetingMessageInput
@ -386,7 +386,8 @@ final class GreetingMessageSetupScreenComponent: Component {
let currentValue: Date = (isStartTime ? self.customScheduleStart : self.customScheduleEnd) ?? Date()
if isDate {
let calendar = Calendar.current
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
let components = calendar.dateComponents([.year, .month, .day], from: currentValue)
guard let clippedDate = calendar.date(from: components) else {
return
@ -462,7 +463,7 @@ final class GreetingMessageSetupScreenComponent: Component {
}
}
func update(component: GreetingMessageSetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
func update(component: AutomaticBusinessMessageSetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
self.isUpdating = true
defer {
self.isUpdating = false
@ -811,6 +812,7 @@ final class GreetingMessageSetupScreenComponent: Component {
}
var icon: ListActionItemComponent.Icon?
var accessory: ListActionItemComponent.Accessory?
if let itemDate {
let calendar = Calendar.current
let hours = calendar.component(.hour, from: itemDate)
@ -861,6 +863,16 @@ final class GreetingMessageSetupScreenComponent: Component {
animateScale: false
)))
], spacing: 4.0))), insets: .custom(UIEdgeInsets(top: 4.0, left: 0.0, bottom: 4.0, right: 0.0)), allowUserInteraction: true)
} else {
icon = ListActionItemComponent.Icon(component: AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: "Set",
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
textColor: environment.theme.list.itemSecondaryTextColor
)),
maximumNumberOfLines: 1
))))
accessory = .arrow
}
customScheduleSectionItems.append(AnyComponentWithIdentity(id: customScheduleSectionItems.count, component: AnyComponent(ListActionItemComponent(
@ -876,7 +888,7 @@ final class GreetingMessageSetupScreenComponent: Component {
))),
], alignment: .left, spacing: 2.0)),
icon: icon,
accessory: nil,
accessory: accessory,
action: itemDate != nil ? nil : { [weak self] _ in
guard let self else {
return
@ -1242,7 +1254,7 @@ final class GreetingMessageSetupScreenComponent: Component {
}
}
public final class GreetingMessageSetupScreen: ViewControllerComponentContainer {
public final class AutomaticBusinessMessageSetupScreen: ViewControllerComponentContainer {
public enum Mode {
case greeting
case away
@ -1253,7 +1265,7 @@ public final class GreetingMessageSetupScreen: ViewControllerComponentContainer
public init(context: AccountContext, mode: Mode) {
self.context = context
super.init(context: context, component: GreetingMessageSetupScreenComponent(
super.init(context: context, component: AutomaticBusinessMessageSetupScreenComponent(
context: context,
mode: mode
), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil)
@ -1263,14 +1275,14 @@ public final class GreetingMessageSetupScreen: ViewControllerComponentContainer
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
self.scrollToTop = { [weak self] in
guard let self, let componentView = self.node.hostView.componentView as? GreetingMessageSetupScreenComponent.View else {
guard let self, let componentView = self.node.hostView.componentView as? AutomaticBusinessMessageSetupScreenComponent.View else {
return
}
componentView.scrollToTop()
}
self.attemptNavigation = { [weak self] complete in
guard let self, let componentView = self.node.hostView.componentView as? GreetingMessageSetupScreenComponent.View else {
guard let self, let componentView = self.node.hostView.componentView as? AutomaticBusinessMessageSetupScreenComponent.View else {
return true
}

View File

@ -18,16 +18,20 @@ import ItemListPeerActionItem
import ItemListUI
import ChatListUI
import QuickReplyNameAlertController
import ChatListHeaderComponent
final class QuickReplySetupScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext
let initialData: QuickReplySetupScreen.InitialData
init(
context: AccountContext
context: AccountContext,
initialData: QuickReplySetupScreen.InitialData
) {
self.context = context
self.initialData = initialData
}
static func ==(lhs: QuickReplySetupScreenComponent, rhs: QuickReplySetupScreenComponent) -> Bool {
@ -38,16 +42,6 @@ final class QuickReplySetupScreenComponent: Component {
return true
}
private struct ShortcutItem: Equatable {
var shortcut: String
var messages: [EngineMessage]
init(shortcut: String, messages: [EngineMessage]) {
self.shortcut = shortcut
self.messages = messages
}
}
private enum ContentEntry: Comparable, Identifiable {
enum Id: Hashable {
case add
@ -58,23 +52,23 @@ final class QuickReplySetupScreenComponent: Component {
switch self {
case .add:
return .add
case let .item(item, _, _):
case let .item(item, _, _, _):
return .item(item.shortcut)
}
}
case add
case item(item: ShortcutItem, accountPeer: EnginePeer, sortIndex: Int)
case item(item: QuickReplyMessageShortcut, accountPeer: EnginePeer, sortIndex: Int, isEditing: Bool)
static func <(lhs: ContentEntry, rhs: ContentEntry) -> Bool {
switch lhs {
case .add:
return false
case let .item(lhsItem, _, lhsSortIndex):
case let .item(lhsItem, _, lhsSortIndex, _):
switch rhs {
case .add:
return false
case let .item(rhsItem, _, rhsSortIndex):
case let .item(rhsItem, _, rhsSortIndex, _):
if lhsSortIndex != rhsSortIndex {
return lhsSortIndex < rhsSortIndex
}
@ -106,7 +100,7 @@ final class QuickReplySetupScreenComponent: Component {
parentView.openQuickReplyChat(shortcut: nil)
}
)
case let .item(item, accountPeer, _):
case let .item(item, accountPeer, _, isEditing):
let chatListNodeInteraction = ChatListNodeInteraction(
context: listNode.context,
animationCache: listNode.context.animationCache,
@ -235,10 +229,11 @@ final class QuickReplySetupScreenComponent: Component {
tags: [],
customMessageListData: ChatListItemContent.CustomMessageListData(
commandPrefix: "/\(item.shortcut)",
searchQuery: nil,
messageCount: nil
)
)),
editing: false,
editing: isEditing,
hasActiveRevealControls: false,
selected: false,
header: nil,
@ -285,11 +280,16 @@ final class QuickReplySetupScreenComponent: Component {
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(listNode: self), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(listNode: self), directionHint: nil) }
var options: ListViewDeleteAndInsertOptions = [.Synchronous, .LowLatency]
if animated {
options.insert(.AnimateInsertion)
}
self.transaction(
deleteIndices: deletions,
insertIndicesAndItems: insertions,
updateIndicesAndItems: updates,
options: [.Synchronous, .LowLatency],
options: options,
scrollToItem: nil,
stationaryItemRange: nil,
updateOpaqueState: nil,
@ -303,14 +303,20 @@ final class QuickReplySetupScreenComponent: Component {
private var emptyState: ComponentView<Empty>?
private var contentListNode: ContentListNode?
private let navigationBarView = ComponentView<Empty>()
private var navigationHeight: CGFloat?
private var isUpdating: Bool = false
private var component: QuickReplySetupScreenComponent?
private(set) weak var state: EmptyComponentState?
private var environment: EnvironmentType?
private var items: [ShortcutItem] = []
private var items: [QuickReplyMessageShortcut] = []
private var messagesDisposable: Disposable?
private var isEditing: Bool = false
private var isSearchDisplayControllerActive: Bool = false
private var accountPeer: EnginePeer?
@ -330,6 +336,10 @@ final class QuickReplySetupScreenComponent: Component {
}
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
guard let component = self.component else {
return true
}
component.context.engine.accountData.updateShortcutMessages(state: QuickReplyMessageShortcutsState(shortcuts: self.items))
return true
}
@ -339,9 +349,22 @@ final class QuickReplySetupScreenComponent: Component {
}
if let shortcut {
let contents = GreetingMessageSetupChatContents(
var mappedMessages: [EngineMessage] = []
if let messages = self.items.first(where: { $0.shortcut == shortcut })?.messages {
var nextId: Int32 = 1
for message in messages {
var mappedMessage = message._asMessage()
mappedMessage = mappedMessage.withUpdatedId(id: MessageId(peerId: component.context.account.peerId, namespace: 0, id: nextId))
mappedMessage = mappedMessage.withUpdatedStableId(stableId: UInt32(nextId))
mappedMessage = mappedMessage.withUpdatedTimestamp(nextId)
mappedMessages.append(EngineMessage(mappedMessage))
nextId += 1
}
}
let contents = AutomaticBusinessMessageSetupChatContents(
context: component.context,
messages: self.items.first(where: { $0.shortcut == shortcut })?.messages ?? [],
messages: mappedMessages,
kind: .quickReplyMessageInput(shortcut: shortcut)
)
let chatController = component.context.sharedContext.makeChatController(
@ -359,7 +382,7 @@ final class QuickReplySetupScreenComponent: Component {
guard let self else {
return
}
let messages = messages.map(EngineMessage.init)
let messages = messages.reversed().map(EngineMessage.init)
if messages.isEmpty {
if let index = self.items.firstIndex(where: { $0.shortcut == shortcut }) {
@ -367,12 +390,9 @@ final class QuickReplySetupScreenComponent: Component {
}
} else {
if let index = self.items.firstIndex(where: { $0.shortcut == shortcut }) {
self.items[index].messages = messages
self.items[index] = QuickReplyMessageShortcut(id: self.items[index].id, shortcut: self.items[index].shortcut, messages: messages)
} else {
self.items.insert(ShortcutItem(
shortcut: shortcut,
messages: messages
), at: 0)
self.items.insert(QuickReplyMessageShortcut(id: Int32.random(in: Int32.min ... Int32.max), shortcut: shortcut, messages: messages), at: 0)
}
}
@ -406,6 +426,147 @@ final class QuickReplySetupScreenComponent: Component {
self.contentListNode?.clearHighlightAnimated(true)
}
private func updateNavigationBar(
component: QuickReplySetupScreenComponent,
theme: PresentationTheme,
strings: PresentationStrings,
size: CGSize,
insets: UIEdgeInsets,
statusBarHeight: CGFloat,
transition: Transition,
deferScrollApplication: Bool
) -> CGFloat {
var rightButtons: [AnyComponentWithIdentity<NavigationButtonComponentEnvironment>] = []
if self.isEditing {
rightButtons.append(AnyComponentWithIdentity(id: "done", component: AnyComponent(NavigationButtonComponent(
content: .text(title: strings.Common_Done, isBold: true),
pressed: { [weak self] _ in
guard let self else {
return
}
self.isEditing = false
self.state?.updated(transition: .spring(duration: 0.4))
}
))))
} else {
rightButtons.append(AnyComponentWithIdentity(id: "edit", component: AnyComponent(NavigationButtonComponent(
content: .text(title: strings.Common_Edit, isBold: false),
pressed: { [weak self] _ in
guard let self else {
return
}
self.isEditing = true
self.state?.updated(transition: .spring(duration: 0.4))
}
))))
}
let headerContent: ChatListHeaderComponent.Content? = ChatListHeaderComponent.Content(
title: "Quick Replies",
navigationBackTitle: nil,
titleComponent: nil,
chatListTitle: nil,
leftButton: nil,
rightButtons: rightButtons,
backTitle: "Back",
backPressed: { [weak self] in
guard let self else {
return
}
self.environment?.controller()?.dismiss()
}
)
let navigationBarSize = self.navigationBarView.update(
transition: transition,
component: AnyComponent(ChatListNavigationBar(
context: component.context,
theme: theme,
strings: strings,
statusBarHeight: statusBarHeight,
sideInset: insets.left,
isSearchActive: self.isSearchDisplayControllerActive,
isSearchEnabled: !self.isEditing,
primaryContent: headerContent,
secondaryContent: nil,
secondaryTransition: 0.0,
storySubscriptions: nil,
storiesIncludeHidden: false,
uploadProgress: [:],
tabsNode: nil,
tabsNodeIsSearch: false,
accessoryPanelContainer: nil,
accessoryPanelContainerHeight: 0.0,
activateSearch: { [weak self] searchContentNode in
guard let self else {
return
}
self.isSearchDisplayControllerActive = true
self.state?.updated(transition: .spring(duration: 0.4))
},
openStatusSetup: { _ in
},
allowAutomaticOrder: {
}
)),
environment: {},
containerSize: size
)
if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View {
if deferScrollApplication {
navigationBarComponentView.deferScrollApplication = true
}
if navigationBarComponentView.superview == nil {
self.addSubview(navigationBarComponentView)
}
transition.setFrame(view: navigationBarComponentView, frame: CGRect(origin: CGPoint(), size: navigationBarSize))
return navigationBarSize.height
} else {
return 0.0
}
}
private func updateNavigationScrolling(navigationHeight: CGFloat, transition: Transition) {
var mainOffset: CGFloat
if self.items.isEmpty {
mainOffset = navigationHeight
} else {
if let contentListNode = self.contentListNode {
switch contentListNode.visibleContentOffset() {
case .none:
mainOffset = 0.0
case .unknown:
mainOffset = navigationHeight
case let .known(value):
mainOffset = value
}
} else {
mainOffset = navigationHeight
}
}
mainOffset = min(mainOffset, ChatListNavigationBar.searchScrollHeight)
if abs(mainOffset) < 0.1 {
mainOffset = 0.0
}
let resultingOffset = mainOffset
var offset = resultingOffset
if self.isSearchDisplayControllerActive {
offset = 0.0
}
if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View {
navigationBarComponentView.applyScroll(offset: offset, allowAvatarsExpansion: false, forceUpdate: false, transition: transition.withUserData(ChatListNavigationBar.AnimationHint(
disableStoriesAnimations: false,
crossfadeStoryPeers: false
)))
}
}
func update(component: QuickReplySetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
self.isUpdating = true
defer {
@ -413,15 +574,8 @@ final class QuickReplySetupScreenComponent: Component {
}
if self.component == nil {
let _ = (component.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: component.context.account.peerId)
)
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let self else {
return
}
self.accountPeer = peer
})
self.accountPeer = component.initialData.accountPeer
self.items = component.initialData.shortcutMessages.shortcuts
}
let environment = environment[EnvironmentType.self].value
@ -479,29 +633,64 @@ final class QuickReplySetupScreenComponent: Component {
}
}
let navigationHeight = self.updateNavigationBar(
component: component,
theme: environment.theme,
strings: environment.strings,
size: availableSize,
insets: environment.safeInsets,
statusBarHeight: environment.statusBarHeight,
transition: transition,
deferScrollApplication: true
)
self.navigationHeight = navigationHeight
let contentListNode: ContentListNode
if let current = self.contentListNode {
contentListNode = current
} else {
contentListNode = ContentListNode(parentView: self, context: component.context)
self.contentListNode = contentListNode
self.addSubview(contentListNode.view)
contentListNode.visibleContentOffsetChanged = { [weak self] offset in
guard let self else {
return
}
guard let navigationHeight = self.navigationHeight else {
return
}
self.updateNavigationScrolling(navigationHeight: navigationHeight, transition: .immediate)
}
if let navigationBarComponentView = self.navigationBarView.view {
self.insertSubview(contentListNode.view, belowSubview: navigationBarComponentView)
} else {
self.addSubview(contentListNode.view)
}
}
transition.setFrame(view: contentListNode.view, frame: CGRect(origin: CGPoint(), size: availableSize))
contentListNode.update(size: availableSize, insets: UIEdgeInsets(top: environment.navigationHeight, left: environment.safeInsets.left, bottom: environment.safeInsets.bottom, right: environment.safeInsets.right), transition: transition)
contentListNode.update(size: availableSize, insets: UIEdgeInsets(top: navigationHeight, left: environment.safeInsets.left, bottom: environment.safeInsets.bottom, right: environment.safeInsets.right), transition: transition)
var entries: [ContentEntry] = []
if let accountPeer = self.accountPeer {
entries.append(.add)
for item in self.items {
entries.append(.item(item: item, accountPeer: accountPeer, sortIndex: entries.count))
entries.append(.item(item: item, accountPeer: accountPeer, sortIndex: entries.count, isEditing: self.isEditing))
}
}
contentListNode.setEntries(entries: entries, animated: false)
contentListNode.setEntries(entries: entries, animated: !transition.animation.isImmediate)
contentListNode.isHidden = self.items.isEmpty
self.updateNavigationScrolling(navigationHeight: navigationHeight, transition: transition)
if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View {
navigationBarComponentView.deferScrollApplication = false
navigationBarComponentView.applyCurrentScroll(transition: transition)
}
return availableSize
}
}
@ -516,19 +705,28 @@ final class QuickReplySetupScreenComponent: Component {
}
public final class QuickReplySetupScreen: ViewControllerComponentContainer {
public final class InitialData: QuickReplySetupScreenInitialData {
let accountPeer: EnginePeer?
let shortcutMessages: QuickReplyMessageShortcutsState
init(
accountPeer: EnginePeer?,
shortcutMessages: QuickReplyMessageShortcutsState
) {
self.accountPeer = accountPeer
self.shortcutMessages = shortcutMessages
}
}
private let context: AccountContext
public init(context: AccountContext) {
public init(context: AccountContext, initialData: InitialData) {
self.context = context
super.init(context: context, component: QuickReplySetupScreenComponent(
context: context
), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
self.title = "Quick Replies"
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
context: context,
initialData: initialData
), navigationBarAppearance: .none, theme: .default, updatedPresentationData: nil)
self.scrollToTop = { [weak self] in
guard let self, let componentView = self.node.hostView.componentView as? QuickReplySetupScreenComponent.View else {
@ -560,4 +758,20 @@ public final class QuickReplySetupScreen: ViewControllerComponentContainer {
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
super.containerLayoutUpdated(layout, transition: transition)
}
public static func initialData(context: AccountContext) -> Signal<QuickReplySetupScreenInitialData, NoError> {
return combineLatest(
context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)
),
context.engine.accountData.shortcutMessages()
|> take(1)
)
|> map { accountPeer, shortcutMessages -> QuickReplySetupScreenInitialData in
return InitialData(
accountPeer: accountPeer,
shortcutMessages: shortcutMessages
)
}
}
}

View File

@ -23,6 +23,10 @@ import TelegramStringFormatting
import PlainButtonComponent
import TimeSelectionActionSheet
func clipMinutes(_ value: Int) -> Int {
return value % (24 * 60)
}
final class BusinessDaySetupScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
@ -157,7 +161,7 @@ final class BusinessDaySetupScreenComponent: Component {
return
}
let controller = TimeSelectionActionSheet(context: component.context, currentValue: Int32(isStartTime ? range.startTime : range.endTime), applyValue: { [weak self] value in
let controller = TimeSelectionActionSheet(context: component.context, currentValue: Int32(isStartTime ? clipMinutes(range.startMinute) : clipMinutes(range.endMinute)) * 60, applyValue: { [weak self] value in
guard let self else {
return
}
@ -165,17 +169,30 @@ final class BusinessDaySetupScreenComponent: Component {
return
}
if let index = self.ranges.firstIndex(where: { $0.id == rangeId }) {
var startMinute = range.startMinute
var endMinute = range.endMinute
if isStartTime {
self.ranges[index].startTime = Int(value)
startMinute = Int(value) / 60
} else {
self.ranges[index].endTime = Int(value)
endMinute = Int(value) / 60
}
if endMinute < startMinute {
endMinute = endMinute + 24 * 60
}
self.ranges[index].startMinute = startMinute
self.ranges[index].endMinute = endMinute
self.validateRanges()
self.state?.updated(transition: .immediate)
}
})
self.environment?.controller()?.present(controller, in: .window(.root))
}
private func validateRanges() {
self.ranges.sort(by: { $0.startMinute < $1.startMinute })
}
func update(component: BusinessDaySetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
self.isUpdating = true
defer {
@ -190,6 +207,7 @@ final class BusinessDaySetupScreenComponent: Component {
self.isOpen = component.day.ranges != nil
self.ranges = component.day.ranges ?? []
self.nextRangeId = (self.ranges.map(\.id).max() ?? 0) + 1
self.validateRanges()
}
self.component = component
@ -309,11 +327,11 @@ final class BusinessDaySetupScreenComponent: Component {
rangeSectionTransition = rangeSectionTransition.withAnimation(.none)
}
let startHours = range.startTime / (60 * 60)
let startMinutes = range.startTime % (60 * 60)
let startHours = clipMinutes(range.startMinute) / 60
let startMinutes = clipMinutes(range.startMinute) % 60
let startText = stringForShortTimestamp(hours: Int32(startHours), minutes: Int32(startMinutes), dateTimeFormat: PresentationDateTimeFormat())
let endHours = range.endTime / (60 * 60)
let endMinutes = range.endTime % (60 * 60)
let endHours = clipMinutes(range.endMinute) / 60
let endMinutes = clipMinutes(range.endMinute) % 60
let endText = stringForShortTimestamp(hours: Int32(endHours), minutes: Int32(endMinutes), dateTimeFormat: PresentationDateTimeFormat())
var rangeSectionItems: [AnyComponentWithIdentity<Empty>] = []
@ -409,6 +427,7 @@ final class BusinessDaySetupScreenComponent: Component {
return
}
self.ranges.removeAll(where: { $0.id == rangeId })
self.validateRanges()
self.state?.updated(transition: .spring(duration: 0.4))
}
))))
@ -473,6 +492,11 @@ final class BusinessDaySetupScreenComponent: Component {
self.rangeSections.removeValue(forKey: id)
}
var canAddRanges = true
if let lastRange = self.ranges.last, lastRange.endMinute >= 24 * 60 * 2 - 1 {
canAddRanges = false
}
//TODO:localize
let addSectionSize = self.addSection.update(
transition: transition,
@ -509,10 +533,22 @@ final class BusinessDaySetupScreenComponent: Component {
guard let self else {
return
}
var rangeStart = 9 * 60
if let lastRange = self.ranges.last {
rangeStart = lastRange.endMinute + 1
}
if rangeStart >= 2 * 24 * 60 - 1 {
return
}
let rangeEnd = min(rangeStart + 9 * 60, 2 * 24 * 60)
let rangeId = self.nextRangeId
self.nextRangeId += 1
self.ranges.append(BusinessHoursSetupScreenComponent.WorkingHourRange(
id: rangeId, startTime: 9 * (60 * 60), endTime: 18 * (60 * 60)))
id: rangeId, startMinute: rangeStart, endMinute: rangeEnd))
self.validateRanges()
self.state?.updated(transition: .spring(duration: 0.4))
}
)))
@ -529,9 +565,11 @@ final class BusinessDaySetupScreenComponent: Component {
transition.setFrame(view: addSectionView, frame: addSectionFrame)
let alphaTransition = transition.animation.isImmediate ? transition : .easeInOut(duration: 0.25)
alphaTransition.setAlpha(view: addSectionView, alpha: self.isOpen ? 1.0 : 0.0)
alphaTransition.setAlpha(view: addSectionView, alpha: (self.isOpen && canAddRanges) ? 1.0 : 0.0)
}
if canAddRanges {
rangesSectionsHeight += addSectionSize.height
}
rangesSectionsHeight += addSectionSize.height
if self.isOpen {
contentHeight += rangesSectionsHeight

View File

@ -26,17 +26,26 @@ final class BusinessHoursSetupScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext
let initialValue: TelegramBusinessHours?
let completion: (TelegramBusinessHours?) -> Void
init(
context: AccountContext
context: AccountContext,
initialValue: TelegramBusinessHours?,
completion: @escaping (TelegramBusinessHours?) -> Void
) {
self.context = context
self.initialValue = initialValue
self.completion = completion
}
static func ==(lhs: BusinessHoursSetupScreenComponent, rhs: BusinessHoursSetupScreenComponent) -> Bool {
if lhs.context !== rhs.context {
return false
}
if lhs.initialValue != rhs.initialValue {
return false
}
return true
}
@ -49,13 +58,13 @@ final class BusinessHoursSetupScreenComponent: Component {
struct WorkingHourRange: Equatable {
var id: Int
var startTime: Int
var endTime: Int
var startMinute: Int
var endMinute: Int
init(id: Int, startTime: Int, endTime: Int) {
init(id: Int, startMinute: Int, endMinute: Int) {
self.id = id
self.startTime = startTime
self.endTime = endTime
self.startMinute = startMinute
self.endMinute = endMinute
}
}
@ -67,6 +76,74 @@ final class BusinessHoursSetupScreenComponent: Component {
}
}
struct DaysState: Equatable {
enum ValidationError: Error {
case intersectingRanges
}
var timezoneId: String
var days: [Day]
init(timezoneId: String, days: [Day]) {
self.timezoneId = timezoneId
self.days = days
}
init(businessHours: TelegramBusinessHours) {
self.timezoneId = businessHours.timezoneId
self.days = businessHours.splitIntoWeekDays().map { day in
switch day {
case .closed:
return Day(ranges: nil)
case .open:
return Day(ranges: [])
case let .intervals(intervals):
var nextIntervalId = 0
return Day(ranges: intervals.map { interval in
let intervalId = nextIntervalId
nextIntervalId += 1
return WorkingHourRange(id: intervalId, startMinute: interval.startMinute, endMinute: interval.endMinute)
})
}
}
}
func asBusinessHours() throws -> TelegramBusinessHours {
var mappedIntervals: [TelegramBusinessHours.WorkingTimeInterval] = []
var filledMinutes = IndexSet()
for i in 0 ..< self.days.count {
let dayStartMinute = i * 24 * 60
guard var effectiveRanges = self.days[i].ranges else {
continue
}
if effectiveRanges.isEmpty {
effectiveRanges = [WorkingHourRange(id: 0, startMinute: 0, endMinute: 24 * 60)]
}
for range in effectiveRanges {
let minuteRange: Range<Int> = (dayStartMinute + range.startMinute) ..< (dayStartMinute + range.endMinute)
var wrappedMinutes = IndexSet()
if minuteRange.upperBound > 7 * 24 * 60 {
wrappedMinutes.insert(integersIn: minuteRange.lowerBound ..< 7 * 24 * 60)
wrappedMinutes.insert(integersIn: 0 ..< (7 * 24 * 60 - minuteRange.upperBound))
} else {
wrappedMinutes.insert(integersIn: minuteRange)
}
if !filledMinutes.intersection(wrappedMinutes).isEmpty {
throw ValidationError.intersectingRanges
}
filledMinutes.formUnion(wrappedMinutes)
mappedIntervals.append(TelegramBusinessHours.WorkingTimeInterval(startMinute: minuteRange.lowerBound, endMinute: minuteRange.upperBound))
}
}
return TelegramBusinessHours(timezoneId: self.timezoneId, weeklyTimeIntervals: mappedIntervals)
}
}
final class View: UIView, UIScrollViewDelegate {
private let topOverscrollLayer = SimpleLayer()
private let scrollView: ScrollView
@ -86,8 +163,7 @@ final class BusinessHoursSetupScreenComponent: Component {
private var environment: EnvironmentType?
private var showHours: Bool = false
private var days: [Day] = []
private var timezoneId: String
private var daysState = DaysState(timezoneId: "", days: [])
override init(frame: CGRect) {
self.scrollView = ScrollView()
@ -102,18 +178,12 @@ final class BusinessHoursSetupScreenComponent: Component {
}
self.scrollView.alwaysBounceVertical = true
self.timezoneId = TimeZone.current.identifier
super.init(frame: frame)
self.scrollView.delegate = self
self.addSubview(self.scrollView)
self.scrollView.layer.addSublayer(self.topOverscrollLayer)
self.days = (0 ..< 7).map { _ in
return Day(ranges: [])
}
}
required init?(coder: NSCoder) {
@ -128,7 +198,28 @@ final class BusinessHoursSetupScreenComponent: Component {
}
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
return true
guard let component = self.component else {
return true
}
if self.showHours {
do {
let businessHours = try self.daysState.asBusinessHours()
let _ = component.context.engine.accountData.updateAccountBusinessHours(businessHours: businessHours).startStandalone()
return true
} catch let error {
let _ = error
//TODO:localize
return false
}
} else {
if component.initialValue != nil {
let _ = component.context.engine.accountData.updateAccountBusinessHours(businessHours: nil).startStandalone()
return true
} else {
return true
}
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
@ -173,6 +264,19 @@ final class BusinessHoursSetupScreenComponent: Component {
self.isUpdating = false
}
if self.component == nil {
if let initialValue = component.initialValue {
self.showHours = true
self.daysState = DaysState(businessHours: initialValue)
} else {
self.showHours = false
self.daysState.timezoneId = TimeZone.current.identifier
self.daysState.days = (0 ..< 7).map { _ in
return Day(ranges: [])
}
}
}
let environment = environment[EnvironmentType.self].value
let themeUpdated = self.environment?.theme !== environment.theme
self.environment = environment
@ -331,7 +435,7 @@ final class BusinessHoursSetupScreenComponent: Component {
var daysContentHeight: CGFloat = 0.0
var daysSectionItems: [AnyComponentWithIdentity<Empty>] = []
for day in self.days {
for day in self.daysState.days {
let dayIndex = daysSectionItems.count
let title: String
@ -356,7 +460,7 @@ final class BusinessHoursSetupScreenComponent: Component {
}
let subtitle: String
if let ranges = self.days[dayIndex].ranges {
if let ranges = self.daysState.days[dayIndex].ranges {
if ranges.isEmpty {
subtitle = "Open 24 Hours"
} else {
@ -365,11 +469,11 @@ final class BusinessHoursSetupScreenComponent: Component {
if !resultText.isEmpty {
resultText.append(", ")
}
let startHours = range.startTime / (60 * 60)
let startMinutes = range.startTime % (60 * 60)
let startHours = clipMinutes(range.startMinute) / 60
let startMinutes = clipMinutes(range.startMinute) % 60
let startText = stringForShortTimestamp(hours: Int32(startHours), minutes: Int32(startMinutes), dateTimeFormat: PresentationDateTimeFormat())
let endHours = range.endTime / (60 * 60)
let endMinutes = range.endTime % (60 * 60)
let endHours = clipMinutes(range.endMinute) / 60
let endMinutes = clipMinutes(range.endMinute) % 60
let endText = stringForShortTimestamp(hours: Int32(endHours), minutes: Int32(endMinutes), dateTimeFormat: PresentationDateTimeFormat())
resultText.append("\(startText)\u{00a0}- \(endText)")
}
@ -403,11 +507,11 @@ final class BusinessHoursSetupScreenComponent: Component {
guard let self else {
return
}
if dayIndex < self.days.count {
if self.days[dayIndex].ranges == nil {
self.days[dayIndex].ranges = []
if dayIndex < self.daysState.days.count {
if self.daysState.days[dayIndex].ranges == nil {
self.daysState.days[dayIndex].ranges = []
} else {
self.days[dayIndex].ranges = nil
self.daysState.days[dayIndex].ranges = nil
}
}
self.state?.updated(transition: .immediate)
@ -419,13 +523,13 @@ final class BusinessHoursSetupScreenComponent: Component {
self.environment?.controller()?.push(BusinessDaySetupScreen(
context: component.context,
dayIndex: dayIndex,
day: self.days[dayIndex],
day: self.daysState.days[dayIndex],
updateDay: { [weak self] day in
guard let self else {
return
}
if self.days[dayIndex] != day {
self.days[dayIndex] = day
if self.daysState.days[dayIndex] != day {
self.daysState.days[dayIndex] = day
self.state?.updated(transition: .immediate)
}
}
@ -484,7 +588,7 @@ final class BusinessHoursSetupScreenComponent: Component {
)),
icon: ListActionItemComponent.Icon(component: AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: TimeZone(identifier: self.timezoneId)?.localizedName(for: .shortStandard, locale: Locale.current) ?? self.timezoneId,
string: TimeZone(identifier: self.daysState.timezoneId)?.localizedName(for: .shortStandard, locale: Locale.current) ?? self.daysState.timezoneId,
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
textColor: environment.theme.list.itemSecondaryTextColor
)),
@ -506,7 +610,7 @@ final class BusinessHoursSetupScreenComponent: Component {
controller?.dismiss()
return
}
self.timezoneId = timezoneId
self.daysState.timezoneId = timezoneId
self.state?.updated(transition: .immediate)
controller?.dismiss()
}
@ -579,11 +683,13 @@ final class BusinessHoursSetupScreenComponent: Component {
public final class BusinessHoursSetupScreen: ViewControllerComponentContainer {
private let context: AccountContext
public init(context: AccountContext) {
public init(context: AccountContext, initialValue: TelegramBusinessHours?, completion: @escaping (TelegramBusinessHours?) -> Void) {
self.context = context
super.init(context: context, component: BusinessHoursSetupScreenComponent(
context: context
context: context,
initialValue: initialValue,
completion: completion
), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -25,17 +25,26 @@ final class BusinessLocationSetupScreenComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext
let initialValue: TelegramBusinessLocation?
let completion: (TelegramBusinessLocation?) -> Void
init(
context: AccountContext
context: AccountContext,
initialValue: TelegramBusinessLocation?,
completion: @escaping (TelegramBusinessLocation?) -> Void
) {
self.context = context
self.initialValue = initialValue
self.completion = completion
}
static func ==(lhs: BusinessLocationSetupScreenComponent, rhs: BusinessLocationSetupScreenComponent) -> Bool {
if lhs.context !== rhs.context {
return false
}
if lhs.initialValue != rhs.initialValue {
return false
}
return true
}
@ -65,7 +74,7 @@ final class BusinessLocationSetupScreenComponent: Component {
private let textFieldTag = NSObject()
private var resetAddressText: String?
private var mapCoordinates: (Double, Double)?
private var mapCoordinates: TelegramBusinessLocation.Coordinates?
override init(frame: CGRect) {
self.scrollView = ScrollView()
@ -100,6 +109,20 @@ final class BusinessLocationSetupScreenComponent: Component {
}
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
if let component = self.component {
var address = ""
if let textView = self.addressSection.findTaggedView(tag: self.textFieldTag) as? ListMultilineTextFieldItemComponent.View {
address = textView.currentText
}
var businessLocation: TelegramBusinessLocation?
if !address.isEmpty || self.mapCoordinates != nil {
businessLocation = TelegramBusinessLocation(address: address, coordinates: self.mapCoordinates)
}
let _ = component.context.engine.accountData.updateAccountBusinessLocation(businessLocation: businessLocation).startStandalone()
}
return true
}
@ -147,7 +170,7 @@ final class BusinessLocationSetupScreenComponent: Component {
return
}
self.mapCoordinates = (location.latitude, location.longitude)
self.mapCoordinates = TelegramBusinessLocation.Coordinates(latitude: location.latitude, longitude: location.longitude)
if let textView = self.addressSection.findTaggedView(tag: self.textFieldTag) as? ListMultilineTextFieldItemComponent.View, textView.currentText.isEmpty {
self.resetAddressText = address
}
@ -163,6 +186,13 @@ final class BusinessLocationSetupScreenComponent: Component {
self.isUpdating = false
}
if self.component == nil {
if let initialValue = component.initialValue {
self.mapCoordinates = initialValue.coordinates
self.resetAddressText = initialValue.address
}
}
let environment = environment[EnvironmentType.self].value
let themeUpdated = self.environment?.theme !== environment.theme
self.environment = environment
@ -286,6 +316,7 @@ final class BusinessLocationSetupScreenComponent: Component {
placeholder: "Enter Address",
autocapitalizationType: .none,
autocorrectionType: .no,
characterLimit: 64,
updated: { [weak self] value in
guard let self else {
return
@ -351,8 +382,8 @@ final class BusinessLocationSetupScreenComponent: Component {
mapSectionItems.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(MapPreviewComponent(
theme: environment.theme,
location: MapPreviewComponent.Location(
latitude: mapCoordinates.0,
longitude: mapCoordinates.1
latitude: mapCoordinates.latitude,
longitude: mapCoordinates.longitude
),
action: { [weak self] in
guard let self else {
@ -430,11 +461,17 @@ final class BusinessLocationSetupScreenComponent: Component {
public final class BusinessLocationSetupScreen: ViewControllerComponentContainer {
private let context: AccountContext
public init(context: AccountContext) {
public init(
context: AccountContext,
initialValue: TelegramBusinessLocation?,
completion: @escaping (TelegramBusinessLocation?) -> Void
) {
self.context = context
super.init(context: context, component: BusinessLocationSetupScreenComponent(
context: context
context: context,
initialValue: initialValue,
completion: completion
), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -59,6 +59,10 @@ final class BusinessSetupScreenComponent: Component {
private(set) weak var state: EmptyComponentState?
private var environment: EnvironmentType?
private var businessHours: TelegramBusinessHours?
private var businessLocation: TelegramBusinessLocation?
private var dataDisposable: Disposable?
override init(frame: CGRect) {
self.scrollView = ScrollView()
self.scrollView.showsVerticalScrollIndicator = true
@ -85,6 +89,7 @@ final class BusinessSetupScreenComponent: Component {
}
deinit {
self.dataDisposable?.dispose()
}
func scrollToTop() {
@ -139,6 +144,20 @@ final class BusinessSetupScreenComponent: Component {
self.isUpdating = false
}
if self.dataDisposable == nil {
self.dataDisposable = (component.context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.BusinessHours(id: component.context.account.peerId),
TelegramEngine.EngineData.Item.Peer.BusinessLocation(id: component.context.account.peerId)
)
|> deliverOnMainQueue).start(next: { [weak self] businessHours, businessLocation in
guard let self else {
return
}
self.businessHours = businessHours
self.businessLocation = businessLocation
})
}
let environment = environment[EnvironmentType.self].value
let themeUpdated = self.environment?.theme !== environment.theme
self.environment = environment
@ -245,7 +264,8 @@ final class BusinessSetupScreenComponent: Component {
guard let self else {
return
}
self.environment?.controller()?.push(component.context.sharedContext.makeBusinessLocationSetupScreen(context: component.context))
self.environment?.controller()?.push(component.context.sharedContext.makeBusinessLocationSetupScreen(context: component.context, initialValue: self.businessLocation, completion: { _ in
}))
}
))
items.append(Item(
@ -256,7 +276,7 @@ final class BusinessSetupScreenComponent: Component {
guard let self else {
return
}
self.environment?.controller()?.push(component.context.sharedContext.makeBusinessHoursSetupScreen(context: component.context))
self.environment?.controller()?.push(component.context.sharedContext.makeBusinessHoursSetupScreen(context: component.context, initialValue: self.businessHours, completion: { _ in }))
}
))
items.append(Item(
@ -264,10 +284,19 @@ final class BusinessSetupScreenComponent: Component {
title: "Quick Replies",
subtitle: "Set up shortcuts with rich text and media to respond to messages faster.",
action: { [weak self] in
guard let self, let component = self.component, let environment = self.environment else {
guard let self, let component = self.component else {
return
}
environment.controller()?.push(component.context.sharedContext.makeQuickReplySetupScreen(context: component.context))
let _ = (component.context.sharedContext.makeQuickReplySetupScreenInitialData(context: component.context)
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] initialData in
guard let self, let component = self.component, let environment = self.environment else {
return
}
environment.controller()?.push(component.context.sharedContext.makeQuickReplySetupScreen(context: component.context, initialData: initialData))
})
}
))
items.append(Item(
@ -278,7 +307,7 @@ final class BusinessSetupScreenComponent: Component {
guard let self, let component = self.component, let environment = self.environment else {
return
}
environment.controller()?.push(component.context.sharedContext.makeGreetingMessageSetupScreen(context: component.context, isAwayMode: false))
environment.controller()?.push(component.context.sharedContext.makeAutomaticBusinessMessageSetupScreen(context: component.context, isAwayMode: false))
}
))
items.append(Item(
@ -289,7 +318,7 @@ final class BusinessSetupScreenComponent: Component {
guard let self, let component = self.component, let environment = self.environment else {
return
}
environment.controller()?.push(component.context.sharedContext.makeGreetingMessageSetupScreen(context: component.context, isAwayMode: true))
environment.controller()?.push(component.context.sharedContext.makeAutomaticBusinessMessageSetupScreen(context: component.context, isAwayMode: true))
}
))
items.append(Item(

View File

@ -96,6 +96,7 @@ public final class TextFieldComponent: Component {
public let customInputView: UIView?
public let resetText: NSAttributedString?
public let isOneLineWhenUnfocused: Bool
public let characterLimit: Int?
public let formatMenuAvailability: FormatMenuAvailability
public let lockedFormatAction: () -> Void
public let present: (ViewController) -> Void
@ -112,6 +113,7 @@ public final class TextFieldComponent: Component {
customInputView: UIView?,
resetText: NSAttributedString?,
isOneLineWhenUnfocused: Bool,
characterLimit: Int? = nil,
formatMenuAvailability: FormatMenuAvailability,
lockedFormatAction: @escaping () -> Void,
present: @escaping (ViewController) -> Void,
@ -127,6 +129,7 @@ public final class TextFieldComponent: Component {
self.customInputView = customInputView
self.resetText = resetText
self.isOneLineWhenUnfocused = isOneLineWhenUnfocused
self.characterLimit = characterLimit
self.formatMenuAvailability = formatMenuAvailability
self.lockedFormatAction = lockedFormatAction
self.present = present
@ -161,6 +164,9 @@ public final class TextFieldComponent: Component {
if lhs.isOneLineWhenUnfocused != rhs.isOneLineWhenUnfocused {
return false
}
if lhs.characterLimit != rhs.characterLimit {
return false
}
if lhs.formatMenuAvailability != rhs.formatMenuAvailability {
return false
}
@ -537,6 +543,17 @@ public final class TextFieldComponent: Component {
}
public func chatInputTextNode(shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let component = self.component else {
return true
}
if let characterLimit = component.characterLimit {
let string = self.inputState.inputText.string as NSString
let updatedString = string.replacingCharacters(in: range, with: text)
if (updatedString as NSString).length > characterLimit {
return false
}
}
return true
}

View File

@ -9460,6 +9460,56 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
}
}, sendShortcut: { [weak self] shortcut in
guard let self else {
return
}
self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in
guard let self else {
return
}
self.updateChatPresentationInterfaceState(animated: true, interactive: false, {
$0.updatedInterfaceState { $0.withUpdatedReplyMessageSubject(nil).withUpdatedComposeInputState(ChatTextInputState(inputText: NSAttributedString(string: ""))).withUpdatedComposeDisableUrlPreviews([]) }
})
}, nil)
var messages: [EnqueueMessage] = []
for message in shortcut.messages {
var attributes: [MessageAttribute] = []
let entities = generateTextEntities(message.text, enabledTypes: .all)
if !entities.isEmpty {
attributes.append(TextEntitiesMessageAttribute(entities: entities))
}
messages.append(.message(
text: message.text,
attributes: attributes,
inlineStickers: [:],
mediaReference: message.media.first.flatMap { AnyMediaReference.standalone(media: $0) },
threadId: self.chatLocation.threadId,
replyToMessageId: nil,
replyToStoryId: nil,
localGroupingKey: nil,
correlationId: nil,
bubbleUpEmojiOrStickersets: []
))
}
self.sendMessages(messages)
}, openEditShortcuts: { [weak self] in
guard let self else {
return
}
let _ = (self.context.sharedContext.makeQuickReplySetupScreenInitialData(context: self.context)
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] initialData in
guard let self else {
return
}
self.push(self.context.sharedContext.makeQuickReplySetupScreen(context: self.context, initialData: initialData))
})
}, sendBotStart: { [weak self] payload in
if let strongSelf = self, canSendMessagesToChat(strongSelf.presentationInterfaceState) {
strongSelf.startBot(payload)

View File

@ -15,7 +15,7 @@ private func inputQueryResultPriority(_ result: ChatPresentationInputQueryResult
case let .mentions(items):
return (2, !items.isEmpty)
case let .commands(items):
return (3, !items.isEmpty)
return (3, !items.commands.isEmpty || items.hasShortcuts)
case let .contextRequestResult(_, result):
var nonEmpty = false
if let result = result, !result.results.isEmpty {
@ -141,14 +141,14 @@ func inputContextPanelForChatPresentationIntefaceState(_ chatPresentationInterfa
return nil
}
case let .commands(commands):
if !commands.isEmpty {
if !commands.commands.isEmpty || commands.hasShortcuts {
if let currentPanel = currentPanel as? CommandChatInputContextPanelNode {
currentPanel.updateResults(commands)
currentPanel.updateResults(commands.commands, accountPeer: commands.accountPeer, hasShortcuts: commands.hasShortcuts, query: commands.query)
return currentPanel
} else {
let panel = CommandChatInputContextPanelNode(context: context, theme: chatPresentationInterfaceState.theme, strings: chatPresentationInterfaceState.strings, fontSize: chatPresentationInterfaceState.fontSize, chatPresentationContext: controllerInteraction.presentationContext)
panel.interfaceInteraction = interfaceInteraction
panel.updateResults(commands)
panel.updateResults(commands.commands, accountPeer: commands.accountPeer, hasShortcuts: commands.hasShortcuts, query: commands.query)
return panel
}
} else {

View File

@ -199,25 +199,59 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
var signal: Signal<(ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?, ChatContextQueryError> = .complete()
if let previousQuery = previousQuery {
switch previousQuery {
case .command:
break
default:
signal = .single({ _ in return .commands([]) })
case .command:
break
default:
signal = .single({ _ in return .commands(ChatInputQueryCommandsResult(
commands: [],
accountPeer: nil,
hasShortcuts: false,
query: ""
)) })
}
} else {
signal = .single({ _ in return .commands([]) })
signal = .single({ _ in return .commands(ChatInputQueryCommandsResult(
commands: [],
accountPeer: nil,
hasShortcuts: false,
query: ""
)) })
}
var shortcuts: Signal<[QuickReplyMessageShortcut], NoError> = .single([])
if peer is TelegramUser {
shortcuts = context.engine.accountData.shortcutMessages()
|> map { shortcuts -> [QuickReplyMessageShortcut] in
return shortcuts.shortcuts.filter { item in
return item.shortcut.hasPrefix(normalizedQuery)
}
}
}
let commands = context.engine.peers.peerCommands(id: peer.id)
|> map { commands -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let commands = combineLatest(
context.engine.peers.peerCommands(id: peer.id),
shortcuts,
context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)
)
)
|> map { commands, shortcuts, accountPeer -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let filteredCommands = commands.commands.filter { command in
if command.command.text.hasPrefix(normalizedQuery) {
return true
}
return false
}
let sortedCommands = filteredCommands
return { _ in return .commands(sortedCommands) }
var sortedCommands = filteredCommands.map(ChatInputTextCommand.command)
for shortcut in shortcuts {
sortedCommands.append(.shortcut(shortcut))
}
return { _ in return .commands(ChatInputQueryCommandsResult(
commands: sortedCommands,
accountPeer: accountPeer,
hasShortcuts: !shortcuts.isEmpty,
query: normalizedQuery
)) }
}
|> castError(ChatContextQueryError.self)
return signal |> then(commands)

View File

@ -13,34 +13,223 @@ import ChatControllerInteraction
import ItemListUI
import ChatContextQuery
import ChatInputContextPanelNode
import ChatListUI
import ComponentFlow
private struct CommandChatInputContextPanelEntryStableId: Hashable {
let command: PeerCommand
private enum CommandChatInputContextPanelEntryStableId: Hashable {
case editShortcuts
case command(PeerCommand)
case shortcut(Int32)
}
private struct CommandChatInputContextPanelEntry: Comparable, Identifiable {
let index: Int
let command: PeerCommand
let theme: PresentationTheme
var stableId: CommandChatInputContextPanelEntryStableId {
return CommandChatInputContextPanelEntryStableId(command: self.command)
struct Command: Equatable {
let command: ChatInputTextCommand
let accountPeer: EnginePeer?
let searchQuery: String?
static func ==(lhs: Command, rhs: Command) -> Bool {
return lhs.command == rhs.command && lhs.accountPeer == rhs.accountPeer && lhs.searchQuery == rhs.searchQuery
}
}
func withUpdatedTheme(_ theme: PresentationTheme) -> CommandChatInputContextPanelEntry {
return CommandChatInputContextPanelEntry(index: self.index, command: self.command, theme: theme)
enum Content: Equatable {
case editShortcuts
case command(Command)
}
let content: Content
let index: Int
let theme: PresentationTheme
init(index: Int, content: Content, theme: PresentationTheme) {
self.content = content
self.index = index
self.theme = theme
}
static func ==(lhs: CommandChatInputContextPanelEntry, rhs: CommandChatInputContextPanelEntry) -> Bool {
return lhs.index == rhs.index && lhs.command == rhs.command && lhs.theme === rhs.theme
return lhs.index == rhs.index && lhs.content == rhs.content && lhs.theme === rhs.theme
}
static func <(lhs: CommandChatInputContextPanelEntry, rhs: CommandChatInputContextPanelEntry) -> Bool {
return lhs.index < rhs.index
}
func item(context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> ListViewItem {
return CommandChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), command: self.command, commandSelected: commandSelected)
var stableId: CommandChatInputContextPanelEntryStableId {
switch self.content {
case .editShortcuts:
return .editShortcuts
case let .command(command):
switch command.command {
case let .command(command):
return .command(command)
case let .shortcut(shortcut):
return .shortcut(shortcut.id)
}
}
}
func withUpdatedTheme(_ theme: PresentationTheme) -> CommandChatInputContextPanelEntry {
return CommandChatInputContextPanelEntry(index: self.index, content: self.content, theme: theme)
}
func item(context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (ChatInputTextCommand, Bool) -> Void, openEditShortcuts: @escaping () -> Void) -> ListViewItem {
switch self.content {
case .editShortcuts:
//TODO:localzie
return VerticalListContextResultsChatInputPanelButtonItem(theme: presentationData.theme, style: .round, title: "Edit Quick Replies", pressed: {
openEditShortcuts()
})
case let .command(command):
switch command.command {
case let .command(command):
return CommandChatInputPanelItem(context: context, presentationData: ItemListPresentationData(presentationData), command: command, commandSelected: { value, sendImmediately in
commandSelected(.command(value), sendImmediately)
})
case let .shortcut(shortcut):
let chatListNodeInteraction = ChatListNodeInteraction(
context: context,
animationCache: context.animationCache,
animationRenderer: context.animationRenderer,
activateSearch: {
},
peerSelected: { _, _, _, _ in
commandSelected(.shortcut(shortcut), true)
},
disabledPeerSelected: { _, _, _ in
},
togglePeerSelected: { _, _ in
},
togglePeersSelection: { _, _ in
},
additionalCategorySelected: { _ in
},
messageSelected: { _, _, _, _ in
commandSelected(.shortcut(shortcut), true)
},
groupSelected: { _ in
},
addContact: { _ in
},
setPeerIdWithRevealedOptions: { _, _ in
},
setItemPinned: { _, _ in
},
setPeerMuted: { _, _ in
},
setPeerThreadMuted: { _, _, _ in
},
deletePeer: { _, _ in
},
deletePeerThread: { _, _ in
},
setPeerThreadStopped: { _, _, _ in
},
setPeerThreadPinned: { _, _, _ in
},
setPeerThreadHidden: { _, _, _ in
},
updatePeerGrouping: { _, _ in
},
togglePeerMarkedUnread: { _, _ in
},
toggleArchivedFolderHiddenByDefault: {
},
toggleThreadsSelection: { _, _ in
},
hidePsa: { _ in
},
activateChatPreview: { _, _, _, _, _ in
},
present: { _ in
},
openForumThread: { _, _ in
},
openStorageManagement: {
},
openPasswordSetup: {
},
openPremiumIntro: {
},
openPremiumGift: {
},
openActiveSessions: {
},
performActiveSessionAction: { _, _ in
},
openChatFolderUpdates: {
},
hideChatFolderUpdates: {
},
openStories: { _, _ in
},
dismissNotice: { _ in
}
)
let chatListPresentationData = ChatListPresentationData(
theme: presentationData.theme,
fontSize: presentationData.listsFontSize,
strings: presentationData.strings,
dateTimeFormat: presentationData.dateTimeFormat,
nameSortOrder: presentationData.nameSortOrder,
nameDisplayOrder: presentationData.nameDisplayOrder,
disableAnimations: false
)
let renderedPeer: EngineRenderedPeer
if let accountPeer = command.accountPeer {
renderedPeer = EngineRenderedPeer(peer: accountPeer)
} else {
renderedPeer = EngineRenderedPeer(peerId: context.account.peerId, peers: [:], associatedMedia: [:])
}
return ChatListItem(
presentationData: chatListPresentationData,
context: context,
chatListLocation: .chatList(groupId: .root),
filterData: nil,
index: EngineChatList.Item.Index.chatList(ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: context.account.peerId, namespace: 0, id: 0), timestamp: 0))),
content: .peer(ChatListItemContent.PeerData(
messages: shortcut.messages.first.flatMap({ [$0] }) ?? [],
peer: renderedPeer,
threadInfo: nil,
combinedReadState: nil,
isRemovedFromTotalUnreadCount: false,
presence: nil,
hasUnseenMentions: false,
hasUnseenReactions: false,
draftState: nil,
mediaDraftContentType: nil,
inputActivities: nil,
promoInfo: nil,
ignoreUnreadBadge: false,
displayAsMessage: false,
hasFailedMessages: false,
forumTopicData: nil,
topForumTopicItems: [],
autoremoveTimeout: nil,
storyState: nil,
requiresPremiumForMessaging: false,
displayAsTopicList: false,
tags: [],
customMessageListData: ChatListItemContent.CustomMessageListData(
commandPrefix: "/\(shortcut.shortcut)",
searchQuery: command.searchQuery.flatMap { "/\($0)"},
messageCount: nil
)
)),
editing: false,
hasActiveRevealControls: false,
selected: false,
header: nil,
enableContextActions: false,
hiddenOffset: false,
interaction: chatListNodeInteraction
)
}
}
}
}
@ -48,21 +237,33 @@ private struct CommandChatInputContextPanelTransition {
let deletions: [ListViewDeleteItem]
let insertions: [ListViewInsertItem]
let updates: [ListViewUpdateItem]
let hasShortcuts: Bool
let itemCountChanged: Bool
}
private func preparedTransition(from fromEntries: [CommandChatInputContextPanelEntry], to toEntries: [CommandChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (PeerCommand, Bool) -> Void) -> CommandChatInputContextPanelTransition {
private func preparedTransition(from fromEntries: [CommandChatInputContextPanelEntry], to toEntries: [CommandChatInputContextPanelEntry], context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (ChatInputTextCommand, Bool) -> Void, openEditShortcuts: @escaping () -> Void) -> CommandChatInputContextPanelTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected), directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected, openEditShortcuts: openEditShortcuts), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, commandSelected: commandSelected, openEditShortcuts: openEditShortcuts), directionHint: nil) }
return CommandChatInputContextPanelTransition(deletions: deletions, insertions: insertions, updates: updates)
let itemCountChanged = fromEntries.count != toEntries.count
return CommandChatInputContextPanelTransition(deletions: deletions, insertions: insertions, updates: updates, hasShortcuts: toEntries.contains(where: { entry in
if case .editShortcuts = entry.content {
return true
}
return false
}), itemCountChanged: itemCountChanged)
}
final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
private let listView: ListView
private let listBackgroundView: UIView
private var currentEntries: [CommandChatInputContextPanelEntry]?
private var contentOffsetChangeTransition: Transition?
private var isAnimatingOut: Bool = false
private var enqueuedTransitions: [(CommandChatInputContextPanelTransition, Bool)] = []
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)?
@ -78,20 +279,54 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
return strings.VoiceOver_ScrollStatus(row, count).string
}
self.listBackgroundView = UIView()
self.listBackgroundView.backgroundColor = theme.list.plainBackgroundColor
self.listBackgroundView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
self.listBackgroundView.layer.cornerRadius = 10.0
super.init(context: context, theme: theme, strings: strings, fontSize: fontSize, chatPresentationContext: chatPresentationContext)
self.isOpaque = false
self.clipsToBounds = true
self.view.addSubview(self.listBackgroundView)
self.addSubnode(self.listView)
self.listView.visibleContentOffsetChanged = { [weak self] offset in
guard let self else {
return
}
if self.isAnimatingOut {
return
}
var topItemOffset: CGFloat = self.listView.bounds.height
var isFirst = true
self.listView.forEachItemNode { itemNode in
if isFirst {
isFirst = false
topItemOffset = itemNode.frame.minY
}
}
let transition: Transition = self.contentOffsetChangeTransition ?? .immediate
transition.setFrame(view: self.listBackgroundView, frame: CGRect(origin: CGPoint(x: 0.0, y: topItemOffset), size: CGSize(width: self.listView.bounds.width, height: self.listView.bounds.height + 1000.0)))
}
}
func updateResults(_ results: [PeerCommand]) {
func updateResults(_ results: [ChatInputTextCommand], accountPeer: EnginePeer?, hasShortcuts: Bool, query: String?) {
var entries: [CommandChatInputContextPanelEntry] = []
var index = 0
var stableIds = Set<CommandChatInputContextPanelEntryStableId>()
if hasShortcuts {
let entry = CommandChatInputContextPanelEntry(index: index, content: .editShortcuts, theme: self.theme)
stableIds.insert(entry.stableId)
entries.append(entry)
index += 1
}
for command in results {
let entry = CommandChatInputContextPanelEntry(index: index, command: command, theme: self.theme)
let entry = CommandChatInputContextPanelEntry(index: index, content: .command(CommandChatInputContextPanelEntry.Command(command: command, accountPeer: accountPeer, searchQuery: query)), theme: self.theme)
if stableIds.contains(entry.stableId) {
continue
}
@ -106,7 +341,11 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
let firstTime = self.currentEntries == nil
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let transition = preparedTransition(from: from ?? [], to: to, context: self.context, presentationData: presentationData, commandSelected: { [weak self] command, sendImmediately in
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
guard let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction else {
return
}
switch command {
case let .command(command):
if sendImmediately {
interfaceInteraction.sendBotCommand(command.peer, "/" + command.command.text)
} else {
@ -132,7 +371,14 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
return (textInputState, inputMode)
}
}
case let .shortcut(shortcut):
interfaceInteraction.sendShortcut(shortcut)
}
}, openEditShortcuts: { [weak self] in
guard let self, let interfaceInteraction = self.interfaceInteraction else {
return
}
interfaceInteraction.openEditShortcuts()
})
self.currentEntries = to
self.enqueueTransition(transition, firstTime: firstTime)
@ -153,16 +399,23 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
self.enqueuedTransitions.remove(at: 0)
var options = ListViewDeleteAndInsertOptions()
options.insert(.Synchronous)
options.insert(.LowLatency)
if firstTime {
//options.insert(.Synchronous)
//options.insert(.LowLatency)
self.contentOffsetChangeTransition = .spring(duration: 0.4)
self.listBackgroundView.frame = CGRect(origin: CGPoint(x: 0.0, y: self.listView.bounds.height), size: CGSize(width: self.listView.bounds.width, height: self.listView.bounds.height + 1000.0))
} else {
options.insert(.AnimateTopItemPosition)
options.insert(.AnimateCrossfade)
if transition.itemCountChanged {
options.insert(.AnimateTopItemPosition)
options.insert(.AnimateCrossfade)
}
self.contentOffsetChangeTransition = .spring(duration: 0.4)
}
var insets = UIEdgeInsets()
insets.top = topInsetForLayout(size: validLayout.0)
insets.top = topInsetForLayout(size: validLayout.0, hasShortcuts: transition.hasShortcuts)
insets.left = validLayout.1
insets.right = validLayout.2
@ -178,19 +431,28 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
}
if let topItemOffset = topItemOffset {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
let position = strongSelf.listView.layer.position
strongSelf.listView.position = CGPoint(x: position.x, y: position.y + (strongSelf.listView.bounds.size.height - topItemOffset))
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .spring).animateView {
transition.animateView {
strongSelf.listView.position = position
}
//transition.animatePositionAdditive(layer: strongSelf.listBackgroundView.layer, offset: CGPoint(x: 0.0, y: strongSelf.listView.bounds.size.height - topItemOffset))
}
}
})
self.contentOffsetChangeTransition = nil
}
}
private func topInsetForLayout(size: CGSize) -> CGFloat {
let minimumItemHeights: CGFloat = floor(MentionChatInputPanelItemNode.itemHeight * 3.5)
private func topInsetForLayout(size: CGSize, hasShortcuts: Bool) -> CGFloat {
var minimumItemHeights: CGFloat = floor(MentionChatInputPanelItemNode.itemHeight * 3.5)
if hasShortcuts {
minimumItemHeights += VerticalListContextResultsChatInputPanelButtonItemNode.itemHeight(style: .round)
}
return max(size.height - minimumItemHeights, 0.0)
}
@ -199,7 +461,16 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
self.validLayout = (size, leftInset, rightInset, bottomInset)
var insets = UIEdgeInsets()
insets.top = self.topInsetForLayout(size: size)
var hasShortcuts = false
if let currentEntries = self.currentEntries {
hasShortcuts = currentEntries.contains(where: { entry in
if case .editShortcuts = entry.content {
return true
}
return false
})
}
insets.top = self.topInsetForLayout(size: size, hasShortcuts: hasShortcuts)
insets.left = leftInset
insets.right = rightInset
@ -226,6 +497,8 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
}
override func animateOut(completion: @escaping () -> Void) {
self.isAnimatingOut = true
var topItemOffset: CGFloat?
self.listView.forEachItemNode { itemNode in
if topItemOffset == nil {
@ -235,9 +508,12 @@ final class CommandChatInputContextPanelNode: ChatInputContextPanelNode {
if let topItemOffset = topItemOffset {
let position = self.listView.layer.position
self.listView.layer.animatePosition(from: position, to: CGPoint(x: position.x, y: position.y + (self.listView.bounds.size.height - topItemOffset)), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
let offset = (self.listView.bounds.size.height - topItemOffset)
self.listView.layer.animatePosition(from: position, to: CGPoint(x: position.x, y: position.y + offset), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
completion()
})
self.listBackgroundView.layer.animatePosition(from: self.listBackgroundView.layer.position, to: CGPoint(x: self.listBackgroundView.layer.position.x, y: self.listBackgroundView.layer.position.y + offset), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
})
} else {
completion()
}

View File

@ -55,7 +55,7 @@ import BusinessSetupScreen
import ChatbotSetupScreen
import BusinessLocationSetupScreen
import BusinessHoursSetupScreen
import GreetingMessageSetupScreen
import AutomaticBusinessMessageSetupScreen
private final class AccountUserInterfaceInUseContext {
let subscribers = Bag<(Bool) -> Void>()
@ -1891,20 +1891,24 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return ChatbotSetupScreen(context: context)
}
public func makeBusinessLocationSetupScreen(context: AccountContext) -> ViewController {
return BusinessLocationSetupScreen(context: context)
public func makeBusinessLocationSetupScreen(context: AccountContext, initialValue: TelegramBusinessLocation?, completion: @escaping (TelegramBusinessLocation?) -> Void) -> ViewController {
return BusinessLocationSetupScreen(context: context, initialValue: initialValue, completion: completion)
}
public func makeBusinessHoursSetupScreen(context: AccountContext) -> ViewController {
return BusinessHoursSetupScreen(context: context)
public func makeBusinessHoursSetupScreen(context: AccountContext, initialValue: TelegramBusinessHours?, completion: @escaping (TelegramBusinessHours?) -> Void) -> ViewController {
return BusinessHoursSetupScreen(context: context, initialValue: initialValue, completion: completion)
}
public func makeGreetingMessageSetupScreen(context: AccountContext, isAwayMode: Bool) -> ViewController {
return GreetingMessageSetupScreen(context: context, mode: isAwayMode ? .away : .greeting)
public func makeAutomaticBusinessMessageSetupScreen(context: AccountContext, isAwayMode: Bool) -> ViewController {
return AutomaticBusinessMessageSetupScreen(context: context, mode: isAwayMode ? .away : .greeting)
}
public func makeQuickReplySetupScreen(context: AccountContext) -> ViewController {
return QuickReplySetupScreen(context: context)
public func makeQuickReplySetupScreen(context: AccountContext, initialData: QuickReplySetupScreenInitialData) -> ViewController {
return QuickReplySetupScreen(context: context, initialData: initialData as! QuickReplySetupScreen.InitialData)
}
public func makeQuickReplySetupScreenInitialData(context: AccountContext) -> Signal<QuickReplySetupScreenInitialData, NoError> {
return QuickReplySetupScreen.initialData(context: context)
}
public func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController {

View File

@ -287,7 +287,7 @@ final class VerticalListContextResultsChatInputContextPanelNode: ChatInputContex
private func topInsetForLayout(size: CGSize, hasSwitchPeer: Bool) -> CGFloat {
var minimumItemHeights: CGFloat = floor(VerticalListContextResultsChatInputPanelItemNode.itemHeight * 3.5)
if hasSwitchPeer {
minimumItemHeights += VerticalListContextResultsChatInputPanelButtonItemNode.itemHeight
minimumItemHeights += VerticalListContextResultsChatInputPanelButtonItemNode.itemHeight(style: .regular)
}
return max(size.height - minimumItemHeights, 0.0)

View File

@ -7,12 +7,19 @@ import SwiftSignalKit
import TelegramPresentationData
final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem {
enum Style {
case regular
case round
}
fileprivate let theme: PresentationTheme
fileprivate let style: Style
fileprivate let title: String
fileprivate let pressed: () -> Void
public init(theme: PresentationTheme, title: String, pressed: @escaping () -> Void) {
public init(theme: PresentationTheme, style: Style = .regular, title: String, pressed: @escaping () -> Void) {
self.theme = theme
self.style = style
self.title = title
self.pressed = pressed
}
@ -65,10 +72,15 @@ final class VerticalListContextResultsChatInputPanelButtonItem: ListViewItem {
}
}
private let titleFont = Font.regular(15.0)
final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItemNode {
static let itemHeight: CGFloat = 32.0
static func itemHeight(style: VerticalListContextResultsChatInputPanelButtonItem.Style) -> CGFloat {
switch style {
case .regular:
return 32.0
case .round:
return 42.0
}
}
private let buttonNode: HighlightTrackingButtonNode
private let titleNode: TextNode
@ -125,11 +137,19 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
return { [weak self] item, params, mergedTop, mergedBottom in
let titleFont: UIFont
switch item.style {
case .regular:
titleFont = Font.regular(15.0)
case .round:
titleFont = Font.regular(17.0)
}
let titleString = NSAttributedString(string: item.title, font: titleFont, textColor: item.theme.list.itemAccentColor)
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - 16.0, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: VerticalListContextResultsChatInputPanelButtonItemNode.itemHeight), insets: UIEdgeInsets())
let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: VerticalListContextResultsChatInputPanelButtonItemNode.itemHeight(style: item.style)), insets: UIEdgeInsets())
return (nodeLayout, { _ in
if let strongSelf = self {
@ -137,7 +157,13 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
strongSelf.separatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor
strongSelf.topSeparatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor
strongSelf.backgroundColor = item.theme.list.plainBackgroundColor
switch item.style {
case .regular:
strongSelf.backgroundColor = item.theme.list.plainBackgroundColor
case .round:
strongSelf.backgroundColor = nil
}
let _ = titleApply()