Recent apps

This commit is contained in:
Isaac 2024-07-16 13:33:46 +08:00
parent 61578961ce
commit d15818649b
20 changed files with 1140 additions and 601 deletions

View File

@ -714,6 +714,7 @@ public enum ChatListSearchFilter: Equatable {
case chats
case topics
case channels
case apps
case media
case downloads
case links
@ -731,18 +732,20 @@ public enum ChatListSearchFilter: Equatable {
return 1
case .channels:
return 2
case .media:
case .apps:
return 3
case .downloads:
case .media:
return 4
case .links:
case .downloads:
return 5
case .files:
case .links:
return 6
case .music:
case .files:
return 7
case .voice:
case .music:
return 8
case .voice:
return 9
case let .peer(peerId, _, _, _):
return peerId.id._internalGetInt64Value()
case let .date(_, date, _):

View File

@ -145,6 +145,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
private var validLayout: (ContainerViewLayout, CGFloat)?
private let sharedOpenStoryDisposable = MetaDisposable()
private var recentAppsDisposable: Disposable?
public init(context: AccountContext, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, filter: ChatListNodePeersFilter, requestPeerType: [ReplyMarkupButtonRequestPeerType]?, location: ChatListControllerLocation, displaySearchFilters: Bool, hasDownloads: Bool, initialFilter: ChatListSearchFilter = .chats, openPeer originalOpenPeer: @escaping (EnginePeer, EnginePeer?, Int64?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer, Int64?, ChatListDisabledPeerReason) -> Void, openRecentPeerOptions: @escaping (EnginePeer) -> Void, openMessage originalOpenMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, addContact: ((String) -> Void)?, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, presentInGlobalOverlay: @escaping (ViewController, Any?) -> Void, navigationController: NavigationController?, parentController: @escaping () -> ViewController?) {
var initialFilter = initialFilter
@ -293,6 +294,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
filterKey = .topics
case .channels:
filterKey = .channels
case .apps:
filterKey = .apps
case .media:
filterKey = .media
case .downloads:
@ -347,6 +350,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
key = .topics
case .channels:
key = .channels
case .apps:
key = .apps
case .media:
key = .media
case .downloads:
@ -386,7 +391,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
switch filter {
case let .filter(filter):
switch filter {
case .downloads, .channels:
case .downloads, .channels, .apps:
return false
default:
return true
@ -518,6 +523,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
})
}
self.recentAppsDisposable = context.engine.peers.managedUpdatedRecentApps().startStrict()
self._ready.set(self.paneContainerNode.isReady.get()
|> map { _ in Void() })
}
@ -528,6 +535,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
self.suggestedFiltersDisposable.dispose()
self.shareStatusDisposable?.dispose()
self.sharedOpenStoryDisposable.dispose()
self.recentAppsDisposable?.dispose()
self.copyProtectionTooltipController?.dismiss()
}

View File

@ -87,6 +87,10 @@ private final class ItemNode: ASDisplayNode {
case .channels:
title = presentationData.strings.ChatList_Search_FilterChannels
icon = nil
case .apps:
//TODO:localize
title = "Apps"
icon = nil
case .media:
title = presentationData.strings.ChatList_Search_FilterMedia
icon = nil

View File

@ -41,6 +41,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
enum Section {
case local
case recommendedChannels
case popularApps
}
case topPeers([EnginePeer], PresentationTheme, PresentationStrings)
@ -108,7 +109,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
animationCache: AnimationCache,
animationRenderer: MultiAnimationRenderer,
openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void,
isChannelsTabExpanded: Bool,
isChannelsTabExpanded: Bool?,
toggleChannelsTabExpanded: @escaping () -> Void
) -> ListViewItem {
switch self {
@ -240,9 +241,26 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
if case .recommendedChannels = section {
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionRecommendedChannels, 1), theme: theme, strings: strings)
} else {
if let isChannelsTabExpanded {
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionLocalChannels, 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: {
toggleChannelsTabExpanded()
})
} else {
header = ChatListSearchItemHeader(type: .text(presentationData.strings.ChatList_Search_SectionLocalChannels, 0), theme: theme, strings: strings, actionTitle: nil, action: nil)
}
}
} else if case .apps = key {
//TODO:localize
if case .popularApps = section {
header = ChatListSearchItemHeader(type: .text("POPULAR APPS", 1), theme: theme, strings: strings)
} else {
if let isChannelsTabExpanded {
header = ChatListSearchItemHeader(type: .text("APPS YOU USE", 0), theme: theme, strings: strings, actionTitle: isChannelsTabExpanded ? presentationData.strings.ChatList_Search_SectionActionShowLess : presentationData.strings.ChatList_Search_SectionActionShowMore, action: {
toggleChannelsTabExpanded()
})
} else {
header = ChatListSearchItemHeader(type: .text("APPS YOU USE", 0), theme: theme, strings: strings, actionTitle: nil, action: nil)
}
}
} else {
header = ChatListSearchItemHeader(type: .recentPeers, theme: theme, strings: strings, actionTitle: strings.WebSearch_RecentSectionClear, action: {
@ -276,7 +294,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
}
},
deletePeer: deletePeer,
contextAction: key == .channels ? nil : peerContextAction.flatMap { peerContextAction in
contextAction: (key == .channels || key == .apps) ? nil : peerContextAction.flatMap { peerContextAction in
return { node, gesture, location in
if let chatPeer = peer.peer.peers[peer.peer.peerId] {
peerContextAction(EnginePeer(chatPeer), .recentSearch, node, gesture, location)
@ -708,6 +726,8 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
let headerType: ChatListSearchItemHeaderType
if case .channels = key {
headerType = .channels
} else if case .apps = key {
headerType = .channels
} else {
if filter.contains(.onlyGroups) {
headerType = .chats
@ -977,7 +997,7 @@ private func chatListSearchContainerPreparedRecentTransition(
animationCache: AnimationCache,
animationRenderer: MultiAnimationRenderer,
openStories: @escaping (EnginePeer.Id, AvatarNode) -> Void,
isChannelsTabExpanded: Bool,
isChannelsTabExpanded: Bool?,
toggleChannelsTabExpanded: @escaping () -> Void,
isEmpty: Bool
) -> ChatListSearchContainerRecentTransition {
@ -1327,6 +1347,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
tagMask = nil
case .channels:
tagMask = nil
case .apps:
tagMask = nil
case .media:
tagMask = .photoOrVideo
case .downloads:
@ -1396,7 +1418,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
self.emptyResultsAnimationNode = DefaultAnimatedStickerNodeImpl()
self.emptyResultsAnimationNode.isHidden = true
if key == .channels {
if key == .channels || key == .apps {
let emptyRecentTitleNode = ImmediateTextNode()
emptyRecentTitleNode.displaysAsynchronously = false
emptyRecentTitleNode.attributedText = NSAttributedString(string: presentationData.strings.ChatList_Search_RecommendedChannelsEmpty_Title, font: Font.semibold(17.0), textColor: self.presentationData.theme.list.freeTextColor)
@ -1409,7 +1431,12 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
emptyRecentTextNode.maximumNumberOfLines = 0
emptyRecentTextNode.textAlignment = .center
emptyRecentTextNode.isHidden = true
if key == .channels {
emptyRecentTextNode.attributedText = NSAttributedString(string: presentationData.strings.ChatList_Search_RecommendedChannelsEmpty_Text, font: Font.regular(15.0), textColor: presentationData.theme.list.freeTextColor)
} else if key == .apps {
//TODO:localize
emptyRecentTextNode.attributedText = NSAttributedString(string: "No Apps Found", font: Font.regular(15.0), textColor: presentationData.theme.list.freeTextColor)
}
self.emptyRecentTextNode = emptyRecentTextNode
let emptyRecentAnimationNode = DefaultAnimatedStickerNodeImpl()
@ -1575,7 +1602,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let foundItems: Signal<([ChatListSearchEntry], Bool)?, NoError> = combineLatest(queue: .mainQueue(), searchQuery, searchOptions, downloadItems)
|> mapToSignal { [weak self] query, options, downloadItems -> Signal<([ChatListSearchEntry], Bool)?, NoError> in
if query == nil && options == nil && [.chats, .topics, .channels].contains(key) {
if query == nil && options == nil && [.chats, .topics, .channels, .apps].contains(key) {
let _ = currentRemotePeers.swap(nil)
return .single(nil)
}
@ -1900,6 +1927,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return (peers: resultPeers, unread: unread, recentlySearchedPeerIds: Set())
}
}
} else if let query, key == .apps {
let _ = query
foundLocalPeers = .single(([], [:], Set()))
} else {
foundLocalPeers = .single((peers: [], unread: [:], recentlySearchedPeerIds: Set()))
@ -1926,6 +1956,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|> map { ($0.0, $0.1, false) }
)
)
} else if let query, case .apps = key {
let _ = query
foundRemotePeers = .single(([], [], false))
} else {
foundRemotePeers = .single(([], [], false))
}
@ -2990,6 +3023,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let hasRecentPeers: Signal<Bool, NoError>
if case .channels = key {
hasRecentPeers = .single(false)
} else if case .apps = key {
hasRecentPeers = .single(false)
} else {
hasRecentPeers = context.engine.peers.recentPeers()
|> map { value -> Bool in
@ -3005,7 +3040,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
struct RecentItems {
var entries: [ChatListRecentEntry]
var isChannelsTabExpanded: Bool
var isChannelsTabExpanded: Bool?
var recommendedChannelOrder: [EnginePeer.Id]
var isEmpty: Bool
}
@ -3094,19 +3129,19 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
}
return .single(RecentItems(entries: entries, isChannelsTabExpanded: false, recommendedChannelOrder: [], isEmpty: false))
return .single(RecentItems(entries: entries, isChannelsTabExpanded: nil, recommendedChannelOrder: [], isEmpty: false))
}
if peersFilter.contains(.excludeRecent) {
recentItems = .single(RecentItems(entries: [], isChannelsTabExpanded: false, recommendedChannelOrder: [], isEmpty: false))
recentItems = .single(RecentItems(entries: [], isChannelsTabExpanded: nil, recommendedChannelOrder: [], isEmpty: false))
}
if case .savedMessagesChats = location {
recentItems = .single(RecentItems(entries: [], isChannelsTabExpanded: false, recommendedChannelOrder: [], isEmpty: false))
recentItems = .single(RecentItems(entries: [], isChannelsTabExpanded: nil, recommendedChannelOrder: [], isEmpty: false))
}
if case .channels = key {
struct LocalChannels {
var peerIds: [EnginePeer.Id]
var isExpanded: Bool
var isExpanded: Bool?
}
let localChannels = isChannelsTabExpandedValue.get()
|> mapToSignal { isChannelsTabExpanded -> Signal<LocalChannels, NoError> in
@ -3278,6 +3313,165 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return RecentItems(entries: result, isChannelsTabExpanded: isChannelsTabExpanded, recommendedChannelOrder: recommendedChannelOrder, isEmpty: isEmpty)
}
}
} else if case .apps = key {
struct LocalApps {
var peerIds: [EnginePeer.Id]
var isExpanded: Bool?
}
let localApps = isChannelsTabExpandedValue.get()
|> mapToSignal { isChannelsTabExpanded -> Signal<LocalApps, NoError> in
return context.engine.peers.recentApps()
|> map { peerIds -> LocalApps in
var isExpanded: Bool? = isChannelsTabExpanded
var peerIds = peerIds
if peerIds.count > 5 {
if !isChannelsTabExpanded {
peerIds = Array(peerIds.prefix(5))
}
} else {
isExpanded = nil
}
return LocalApps(peerIds: peerIds, isExpanded: isExpanded)
}
}
let remoteApps: Signal<[EnginePeer.Id]?, NoError> = context.engine.peers.recommendedAppPeerIds()
let _ = self.context.engine.peers.requestRecommendedAppsIfNeeded().startStandalone()
recentItems = combineLatest(
localApps,
remoteApps
)
|> mapToSignal { localApps, remoteApps -> Signal<RecentItems, NoError> in
var allAppIds = localApps.peerIds
var recommendedAppOrder: [EnginePeer.Id] = []
if let remoteApps {
for peerId in remoteApps {
if !allAppIds.contains(peerId) {
allAppIds.append(peerId)
}
recommendedAppOrder.append(peerId)
}
}
return context.engine.data.subscribe(
EngineDataMap(
allAppIds.map { peerId -> TelegramEngine.EngineData.Item.Peer.Peer in
return TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
}
),
EngineDataMap(
allAppIds.map { peerId -> TelegramEngine.EngineData.Item.Peer.NotificationSettings in
return TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId)
}
),
EngineDataMap(
allAppIds.map { peerId -> TelegramEngine.EngineData.Item.Messages.PeerUnreadCount in
return TelegramEngine.EngineData.Item.Messages.PeerUnreadCount(id: peerId)
}
),
EngineDataMap(
allAppIds.map { peerId -> TelegramEngine.EngineData.Item.Peer.StoryStats in
return TelegramEngine.EngineData.Item.Peer.StoryStats(id: peerId)
}
),
EngineDataMap(
allAppIds.map { peerId -> TelegramEngine.EngineData.Item.Messages.PeerReadCounters in
return TelegramEngine.EngineData.Item.Messages.PeerReadCounters(id: peerId)
}
),
TelegramEngine.EngineData.Item.NotificationSettings.Global()
)
|> map { peers, notificationSettings, unreadCounts, storyStats, readCounters, globalNotificationSettings -> RecentItems in
var result: [ChatListRecentEntry] = []
var existingIds = Set<PeerId>()
for id in localApps.peerIds {
if existingIds.contains(id) {
continue
}
existingIds.insert(id)
guard let peer = peers[id], let peer else {
continue
}
let peerNotificationSettings = notificationSettings[id]
//TODO:localize
let subpeerSummary: RecentlySearchedPeerSubpeerSummary? = nil
var peerStoryStats: PeerStoryStats?
if let value = storyStats[peer.id] {
peerStoryStats = value
}
var unreadCount: Int32 = 0
if let value = readCounters[peer.id] {
unreadCount = value.count
}
result.append(.peer(
index: result.count,
peer: RecentlySearchedPeer(
peer: RenderedPeer(peer: peer._asPeer()),
presence: nil,
notificationSettings: peerNotificationSettings.flatMap({ $0._asNotificationSettings() }),
unreadCount: unreadCount,
subpeerSummary: subpeerSummary
),
.local,
presentationData.theme,
presentationData.strings,
presentationData.dateTimeFormat,
presentationData.nameSortOrder,
presentationData.nameDisplayOrder,
globalNotificationSettings,
peerStoryStats,
false
))
}
if let remoteApps {
for appPeerId in remoteApps {
if existingIds.contains(appPeerId) {
continue
}
existingIds.insert(appPeerId)
guard let peer = peers[appPeerId], let peer else {
continue
}
let peerNotificationSettings = notificationSettings[appPeerId]
let subpeerSummary: RecentlySearchedPeerSubpeerSummary? = nil
var peerStoryStats: PeerStoryStats?
if let value = storyStats[peer.id] {
peerStoryStats = value
}
result.append(.peer(
index: result.count,
peer: RecentlySearchedPeer(
peer: RenderedPeer(peer: peer._asPeer()),
presence: nil,
notificationSettings: peerNotificationSettings.flatMap({ $0._asNotificationSettings() }),
unreadCount: 0,
subpeerSummary: subpeerSummary
),
.popularApps,
presentationData.theme,
presentationData.strings,
presentationData.dateTimeFormat,
presentationData.nameSortOrder,
presentationData.nameDisplayOrder,
globalNotificationSettings,
peerStoryStats,
false
))
}
}
var isEmpty = false
if localApps.peerIds.isEmpty, let remoteApps, remoteApps.isEmpty {
isEmpty = true
}
return RecentItems(entries: result, isChannelsTabExpanded: localApps.isExpanded, recommendedChannelOrder: recommendedAppOrder, isEmpty: isEmpty)
}
}
}
if case .chats = key, !peersFilter.contains(.excludeRecent) {
@ -3331,6 +3525,25 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
customChatNavigationStack: customChatNavigationStack
))
}
} else if case .apps = key {
if let navigationController = self.navigationController {
var customChatNavigationStack: [EnginePeer.Id]?
if isRecommended {
if let recommendedChannelOrder = previousRecentItemsValue.with({ $0 })?.recommendedChannelOrder {
var customChatNavigationStackValue: [EnginePeer.Id] = []
customChatNavigationStackValue.append(contentsOf: recommendedChannelOrder)
customChatNavigationStack = customChatNavigationStackValue
}
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
navigationController: navigationController,
context: self.context,
chatLocation: .peer(peer),
keepStack: .always,
customChatNavigationStack: customChatNavigationStack
))
}
} else {
interaction.openPeer(peer, nil, threadId, true)
if threadId == nil {
@ -4000,7 +4213,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
self.enqueuedTransitions.remove(at: 0)
var options = ListViewDeleteAndInsertOptions()
if isFirstTime && [.chats, .topics, .channels].contains(self.key) {
if isFirstTime && [.chats, .topics, .channels, .apps].contains(self.key) {
options.insert(.PreferSynchronousDrawing)
options.insert(.PreferSynchronousResourceLoading)
} else if transition.animated {
@ -4073,7 +4286,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
strongSelf.emptyResultsAnimationNode.visibility = emptyResults
}
var displayPlaceholder = transition.isLoading && (![.chats, .topics, .channels].contains(strongSelf.key) || (strongSelf.currentEntries?.isEmpty ?? true))
var displayPlaceholder = transition.isLoading && (![.chats, .topics, .channels, .apps].contains(strongSelf.key) || (strongSelf.currentEntries?.isEmpty ?? true))
if strongSelf.key == .downloads {
displayPlaceholder = false
}
@ -4309,7 +4522,7 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
let items = (0 ..< 2).compactMap { _ -> ListViewItem? in
switch key {
case .chats, .topics, .channels, .downloads:
case .chats, .topics, .channels, .apps, .downloads:
let message = EngineMessage(
stableId: 0,
stableVersion: 0,

View File

@ -51,6 +51,7 @@ public enum ChatListSearchPaneKey {
case chats
case topics
case channels
case apps
case media
case downloads
case links
@ -68,6 +69,8 @@ extension ChatListSearchPaneKey {
return .topics
case .channels:
return .channels
case .apps:
return .apps
case .media:
return .media
case .downloads:
@ -92,6 +95,7 @@ func defaultAvailableSearchPanes(isForum: Bool, hasDownloads: Bool) -> [ChatList
result.append(.chats)
}
result.append(.channels)
result.append(.apps)
result.append(contentsOf: [.media, .downloads, .links, .files, .music, .voice])
if !hasDownloads {

View File

@ -921,6 +921,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
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[-39945236] = { return Api.TopPeerCategory.parse_topPeerCategoryBotsApp($0) }
dict[344356834] = { return Api.TopPeerCategory.parse_topPeerCategoryBotsInline($0) }
dict[-1419371685] = { return Api.TopPeerCategory.parse_topPeerCategoryBotsPM($0) }
dict[371037736] = { return Api.TopPeerCategory.parse_topPeerCategoryChannels($0) }
@ -1167,6 +1168,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1284008785] = { return Api.auth.SentCodeType.parse_sentCodeTypeSmsPhrase($0) }
dict[-1542017919] = { return Api.auth.SentCodeType.parse_sentCodeTypeSmsWord($0) }
dict[-391678544] = { return Api.bots.BotInfo.parse_botInfo($0) }
dict[428978491] = { return Api.bots.PopularAppBots.parse_popularAppBots($0) }
dict[-309659827] = { return Api.channels.AdminLogResults.parse_adminLogResults($0) }
dict[-541588713] = { return Api.channels.ChannelParticipant.parse_channelParticipant($0) }
dict[-1699676497] = { return Api.channels.ChannelParticipants.parse_channelParticipants($0) }
@ -1396,7 +1398,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
}
}
@ -2146,6 +2148,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.bots.BotInfo:
_1.serialize(buffer, boxed)
case let _1 as Api.bots.PopularAppBots:
_1.serialize(buffer, boxed)
case let _1 as Api.channels.AdminLogResults:
_1.serialize(buffer, boxed)
case let _1 as Api.channels.ChannelParticipant:

View File

@ -86,6 +86,7 @@ public extension Api {
}
public extension Api {
enum TopPeerCategory: TypeConstructorDescription {
case topPeerCategoryBotsApp
case topPeerCategoryBotsInline
case topPeerCategoryBotsPM
case topPeerCategoryChannels
@ -97,6 +98,12 @@ public extension Api {
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .topPeerCategoryBotsApp:
if boxed {
buffer.appendInt32(-39945236)
}
break
case .topPeerCategoryBotsInline:
if boxed {
buffer.appendInt32(344356834)
@ -150,6 +157,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .topPeerCategoryBotsApp:
return ("topPeerCategoryBotsApp", [])
case .topPeerCategoryBotsInline:
return ("topPeerCategoryBotsInline", [])
case .topPeerCategoryBotsPM:
@ -169,6 +178,9 @@ public extension Api {
}
}
public static func parse_topPeerCategoryBotsApp(_ reader: BufferReader) -> TopPeerCategory? {
return Api.TopPeerCategory.topPeerCategoryBotsApp
}
public static func parse_topPeerCategoryBotsInline(_ reader: BufferReader) -> TopPeerCategory? {
return Api.TopPeerCategory.topPeerCategoryBotsInline
}

View File

@ -920,26 +920,18 @@ public extension Api.bots {
}
}
public extension Api.channels {
enum AdminLogResults: TypeConstructorDescription {
case adminLogResults(events: [Api.ChannelAdminLogEvent], chats: [Api.Chat], users: [Api.User])
public extension Api.bots {
enum PopularAppBots: TypeConstructorDescription {
case popularAppBots(flags: Int32, nextOffset: String?, users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .adminLogResults(let events, let chats, let users):
case .popularAppBots(let flags, let nextOffset, let users):
if boxed {
buffer.appendInt32(-309659827)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(events.count))
for item in events {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
buffer.appendInt32(428978491)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
@ -951,29 +943,25 @@ public extension Api.channels {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .adminLogResults(let events, let chats, let users):
return ("adminLogResults", [("events", events as Any), ("chats", chats as Any), ("users", users as Any)])
case .popularAppBots(let flags, let nextOffset, let users):
return ("popularAppBots", [("flags", flags as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
}
}
public static func parse_adminLogResults(_ reader: BufferReader) -> AdminLogResults? {
var _1: [Api.ChannelAdminLogEvent]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ChannelAdminLogEvent.self)
}
var _2: [Api.Chat]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
public static func parse_popularAppBots(_ reader: BufferReader) -> PopularAppBots? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 0) != 0 {_2 = parseString(reader) }
var _3: [Api.User]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.channels.AdminLogResults.adminLogResults(events: _1!, chats: _2!, users: _3!)
return Api.bots.PopularAppBots.popularAppBots(flags: _1!, nextOffset: _2, users: _3!)
}
else {
return nil

View File

@ -1,3 +1,65 @@
public extension Api.channels {
enum AdminLogResults: TypeConstructorDescription {
case adminLogResults(events: [Api.ChannelAdminLogEvent], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .adminLogResults(let events, let chats, let users):
if boxed {
buffer.appendInt32(-309659827)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(events.count))
for item in events {
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 .adminLogResults(let events, let chats, let users):
return ("adminLogResults", [("events", events as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_adminLogResults(_ reader: BufferReader) -> AdminLogResults? {
var _1: [Api.ChannelAdminLogEvent]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ChannelAdminLogEvent.self)
}
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.channels.AdminLogResults.adminLogResults(events: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}
public extension Api.channels {
enum ChannelParticipant: TypeConstructorDescription {
case channelParticipant(participant: Api.ChannelParticipant, chats: [Api.Chat], users: [Api.User])
@ -1400,63 +1462,3 @@ public extension Api.help {
}
}
public extension Api.help {
enum CountryCode: TypeConstructorDescription {
case countryCode(flags: Int32, countryCode: String, prefixes: [String]?, patterns: [String]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
if boxed {
buffer.appendInt32(1107543535)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(countryCode, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(prefixes!.count))
for item in prefixes! {
serializeString(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(patterns!.count))
for item in patterns! {
serializeString(item, buffer: buffer, boxed: false)
}}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
return ("countryCode", [("flags", flags as Any), ("countryCode", countryCode as Any), ("prefixes", prefixes as Any), ("patterns", patterns as Any)])
}
}
public static func parse_countryCode(_ reader: BufferReader) -> CountryCode? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: [String]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
} }
var _4: [String]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.help.CountryCode.countryCode(flags: _1!, countryCode: _2!, prefixes: _3, patterns: _4)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,63 @@
public extension Api.help {
enum CountryCode: TypeConstructorDescription {
case countryCode(flags: Int32, countryCode: String, prefixes: [String]?, patterns: [String]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
if boxed {
buffer.appendInt32(1107543535)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(countryCode, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(prefixes!.count))
for item in prefixes! {
serializeString(item, buffer: buffer, boxed: false)
}}
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(patterns!.count))
for item in patterns! {
serializeString(item, buffer: buffer, boxed: false)
}}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .countryCode(let flags, let countryCode, let prefixes, let patterns):
return ("countryCode", [("flags", flags as Any), ("countryCode", countryCode as Any), ("prefixes", prefixes as Any), ("patterns", patterns as Any)])
}
}
public static func parse_countryCode(_ reader: BufferReader) -> CountryCode? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: [String]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
} }
var _4: [String]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.help.CountryCode.countryCode(flags: _1!, countryCode: _2!, prefixes: _3, patterns: _4)
}
else {
return nil
}
}
}
}
public extension Api.help {
enum DeepLinkInfo: TypeConstructorDescription {
case deepLinkInfo(flags: Int32, message: String, entities: [Api.MessageEntity]?)
@ -1232,61 +1292,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum AvailableReactions: TypeConstructorDescription {
case availableReactions(hash: Int32, reactions: [Api.AvailableReaction])
case availableReactionsNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .availableReactions(let hash, let reactions):
if boxed {
buffer.appendInt32(1989032621)
}
serializeInt32(hash, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(reactions.count))
for item in reactions {
item.serialize(buffer, true)
}
break
case .availableReactionsNotModified:
if boxed {
buffer.appendInt32(-1626924713)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .availableReactions(let hash, let reactions):
return ("availableReactions", [("hash", hash as Any), ("reactions", reactions as Any)])
case .availableReactionsNotModified:
return ("availableReactionsNotModified", [])
}
}
public static func parse_availableReactions(_ reader: BufferReader) -> AvailableReactions? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.AvailableReaction]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableReaction.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.messages.AvailableReactions.availableReactions(hash: _1!, reactions: _2!)
}
else {
return nil
}
}
public static func parse_availableReactionsNotModified(_ reader: BufferReader) -> AvailableReactions? {
return Api.messages.AvailableReactions.availableReactionsNotModified
}
}
}

View File

@ -1,3 +1,61 @@
public extension Api.messages {
enum AvailableReactions: TypeConstructorDescription {
case availableReactions(hash: Int32, reactions: [Api.AvailableReaction])
case availableReactionsNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .availableReactions(let hash, let reactions):
if boxed {
buffer.appendInt32(1989032621)
}
serializeInt32(hash, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(reactions.count))
for item in reactions {
item.serialize(buffer, true)
}
break
case .availableReactionsNotModified:
if boxed {
buffer.appendInt32(-1626924713)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .availableReactions(let hash, let reactions):
return ("availableReactions", [("hash", hash as Any), ("reactions", reactions as Any)])
case .availableReactionsNotModified:
return ("availableReactionsNotModified", [])
}
}
public static func parse_availableReactions(_ reader: BufferReader) -> AvailableReactions? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.AvailableReaction]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.AvailableReaction.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.messages.AvailableReactions.availableReactions(hash: _1!, reactions: _2!)
}
else {
return nil
}
}
public static func parse_availableReactionsNotModified(_ reader: BufferReader) -> AvailableReactions? {
return Api.messages.AvailableReactions.availableReactionsNotModified
}
}
}
public extension Api.messages {
enum BotApp: TypeConstructorDescription {
case botApp(flags: Int32, app: Api.BotApp)
@ -1372,105 +1430,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum HistoryImportParsed: TypeConstructorDescription {
case historyImportParsed(flags: Int32, title: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .historyImportParsed(let flags, let title):
if boxed {
buffer.appendInt32(1578088377)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .historyImportParsed(let flags, let title):
return ("historyImportParsed", [("flags", flags as Any), ("title", title as Any)])
}
}
public static func parse_historyImportParsed(_ reader: BufferReader) -> HistoryImportParsed? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 2) != 0 {_2 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 2) == 0) || _2 != nil
if _c1 && _c2 {
return Api.messages.HistoryImportParsed.historyImportParsed(flags: _1!, title: _2)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum InactiveChats: TypeConstructorDescription {
case inactiveChats(dates: [Int32], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inactiveChats(let dates, let chats, let users):
if boxed {
buffer.appendInt32(-1456996667)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dates.count))
for item in dates {
serializeInt32(item, buffer: buffer, boxed: false)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inactiveChats(let dates, let chats, let users):
return ("inactiveChats", [("dates", dates as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_inactiveChats(_ reader: BufferReader) -> InactiveChats? {
var _1: [Int32]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
}
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.messages.InactiveChats.inactiveChats(dates: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,105 @@
public extension Api.messages {
enum HistoryImportParsed: TypeConstructorDescription {
case historyImportParsed(flags: Int32, title: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .historyImportParsed(let flags, let title):
if boxed {
buffer.appendInt32(1578088377)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .historyImportParsed(let flags, let title):
return ("historyImportParsed", [("flags", flags as Any), ("title", title as Any)])
}
}
public static func parse_historyImportParsed(_ reader: BufferReader) -> HistoryImportParsed? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
if Int(_1!) & Int(1 << 2) != 0 {_2 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 2) == 0) || _2 != nil
if _c1 && _c2 {
return Api.messages.HistoryImportParsed.historyImportParsed(flags: _1!, title: _2)
}
else {
return nil
}
}
}
}
public extension Api.messages {
enum InactiveChats: TypeConstructorDescription {
case inactiveChats(dates: [Int32], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inactiveChats(let dates, let chats, let users):
if boxed {
buffer.appendInt32(-1456996667)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(dates.count))
for item in dates {
serializeInt32(item, buffer: buffer, boxed: false)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inactiveChats(let dates, let chats, let users):
return ("inactiveChats", [("dates", dates as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_inactiveChats(_ reader: BufferReader) -> InactiveChats? {
var _1: [Int32]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
}
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.messages.InactiveChats.inactiveChats(dates: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}
public extension Api.messages {
indirect enum InvitedUsers: TypeConstructorDescription {
case invitedUsers(updates: Api.Updates, missingInvitees: [Api.MissingInvitee])
@ -1432,83 +1534,3 @@ public extension Api.messages {
}
}
public extension Api.messages {
enum StickerSet: TypeConstructorDescription {
case stickerSet(set: Api.StickerSet, packs: [Api.StickerPack], keywords: [Api.StickerKeyword], documents: [Api.Document])
case stickerSetNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .stickerSet(let set, let packs, let keywords, let documents):
if boxed {
buffer.appendInt32(1846886166)
}
set.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(packs.count))
for item in packs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(keywords.count))
for item in keywords {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(documents.count))
for item in documents {
item.serialize(buffer, true)
}
break
case .stickerSetNotModified:
if boxed {
buffer.appendInt32(-738646805)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .stickerSet(let set, let packs, let keywords, let documents):
return ("stickerSet", [("set", set as Any), ("packs", packs as Any), ("keywords", keywords as Any), ("documents", documents as Any)])
case .stickerSetNotModified:
return ("stickerSetNotModified", [])
}
}
public static func parse_stickerSet(_ reader: BufferReader) -> StickerSet? {
var _1: Api.StickerSet?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.StickerSet
}
var _2: [Api.StickerPack]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerPack.self)
}
var _3: [Api.StickerKeyword]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerKeyword.self)
}
var _4: [Api.Document]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.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.StickerSet.stickerSet(set: _1!, packs: _2!, keywords: _3!, documents: _4!)
}
else {
return nil
}
}
public static func parse_stickerSetNotModified(_ reader: BufferReader) -> StickerSet? {
return Api.messages.StickerSet.stickerSetNotModified
}
}
}

View File

@ -1,3 +1,83 @@
public extension Api.messages {
enum StickerSet: TypeConstructorDescription {
case stickerSet(set: Api.StickerSet, packs: [Api.StickerPack], keywords: [Api.StickerKeyword], documents: [Api.Document])
case stickerSetNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .stickerSet(let set, let packs, let keywords, let documents):
if boxed {
buffer.appendInt32(1846886166)
}
set.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(packs.count))
for item in packs {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(keywords.count))
for item in keywords {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(documents.count))
for item in documents {
item.serialize(buffer, true)
}
break
case .stickerSetNotModified:
if boxed {
buffer.appendInt32(-738646805)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .stickerSet(let set, let packs, let keywords, let documents):
return ("stickerSet", [("set", set as Any), ("packs", packs as Any), ("keywords", keywords as Any), ("documents", documents as Any)])
case .stickerSetNotModified:
return ("stickerSetNotModified", [])
}
}
public static func parse_stickerSet(_ reader: BufferReader) -> StickerSet? {
var _1: Api.StickerSet?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.StickerSet
}
var _2: [Api.StickerPack]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerPack.self)
}
var _3: [Api.StickerKeyword]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerKeyword.self)
}
var _4: [Api.Document]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Document.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.StickerSet.stickerSet(set: _1!, packs: _2!, keywords: _3!, documents: _4!)
}
else {
return nil
}
}
public static func parse_stickerSetNotModified(_ reader: BufferReader) -> StickerSet? {
return Api.messages.StickerSet.stickerSetNotModified
}
}
}
public extension Api.messages {
enum StickerSetInstallResult: TypeConstructorDescription {
case stickerSetInstallResultArchive(sets: [Api.StickerSetCovered])
@ -1552,113 +1632,3 @@ public extension Api.phone {
}
}
public extension Api.phone {
enum JoinAsPeers: TypeConstructorDescription {
case joinAsPeers(peers: [Api.Peer], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .joinAsPeers(let peers, let chats, let users):
if boxed {
buffer.appendInt32(-1343921601)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(peers.count))
for item in peers {
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 .joinAsPeers(let peers, let chats, let users):
return ("joinAsPeers", [("peers", peers as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_joinAsPeers(_ reader: BufferReader) -> JoinAsPeers? {
var _1: [Api.Peer]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Peer.self)
}
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.phone.JoinAsPeers.joinAsPeers(peers: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}
public extension Api.phone {
enum PhoneCall: TypeConstructorDescription {
case phoneCall(phoneCall: Api.PhoneCall, users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .phoneCall(let phoneCall, let users):
if boxed {
buffer.appendInt32(-326966976)
}
phoneCall.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 .phoneCall(let phoneCall, let users):
return ("phoneCall", [("phoneCall", phoneCall as Any), ("users", users as Any)])
}
}
public static func parse_phoneCall(_ reader: BufferReader) -> PhoneCall? {
var _1: Api.PhoneCall?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.PhoneCall
}
var _2: [Api.User]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.phone.PhoneCall.phoneCall(phoneCall: _1!, users: _2!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,113 @@
public extension Api.phone {
enum JoinAsPeers: TypeConstructorDescription {
case joinAsPeers(peers: [Api.Peer], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .joinAsPeers(let peers, let chats, let users):
if boxed {
buffer.appendInt32(-1343921601)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(peers.count))
for item in peers {
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 .joinAsPeers(let peers, let chats, let users):
return ("joinAsPeers", [("peers", peers as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_joinAsPeers(_ reader: BufferReader) -> JoinAsPeers? {
var _1: [Api.Peer]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Peer.self)
}
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.phone.JoinAsPeers.joinAsPeers(peers: _1!, chats: _2!, users: _3!)
}
else {
return nil
}
}
}
}
public extension Api.phone {
enum PhoneCall: TypeConstructorDescription {
case phoneCall(phoneCall: Api.PhoneCall, users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .phoneCall(let phoneCall, let users):
if boxed {
buffer.appendInt32(-326966976)
}
phoneCall.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 .phoneCall(let phoneCall, let users):
return ("phoneCall", [("phoneCall", phoneCall as Any), ("users", users as Any)])
}
}
public static func parse_phoneCall(_ reader: BufferReader) -> PhoneCall? {
var _1: Api.PhoneCall?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.PhoneCall
}
var _2: [Api.User]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.phone.PhoneCall.phoneCall(phoneCall: _1!, users: _2!)
}
else {
return nil
}
}
}
}
public extension Api.photos {
enum Photo: TypeConstructorDescription {
case photo(photo: Api.Photo, users: [Api.User])
@ -1426,141 +1536,3 @@ public extension Api.stories {
}
}
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(flags: Int32, count: Int32, stories: [Api.StoryItem], pinnedToTop: [Int32]?, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .stories(let flags, let count, let stories, let pinnedToTop, let chats, let users):
if boxed {
buffer.appendInt32(1673780490)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(stories.count))
for item in stories {
item.serialize(buffer, true)
}
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(pinnedToTop!.count))
for item in pinnedToTop! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .stories(let flags, let count, let stories, let pinnedToTop, let chats, let users):
return ("stories", [("flags", flags as Any), ("count", count as Any), ("stories", stories as Any), ("pinnedToTop", pinnedToTop as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_stories(_ reader: BufferReader) -> Stories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: [Api.StoryItem]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StoryItem.self)
}
var _4: [Int32]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.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)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.stories.Stories.stories(flags: _1!, count: _2!, stories: _3!, pinnedToTop: _4, chats: _5!, users: _6!)
}
else {
return nil
}
}
}
}

View File

@ -1,3 +1,141 @@
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(flags: Int32, count: Int32, stories: [Api.StoryItem], pinnedToTop: [Int32]?, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .stories(let flags, let count, let stories, let pinnedToTop, let chats, let users):
if boxed {
buffer.appendInt32(1673780490)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(stories.count))
for item in stories {
item.serialize(buffer, true)
}
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(pinnedToTop!.count))
for item in pinnedToTop! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .stories(let flags, let count, let stories, let pinnedToTop, let chats, let users):
return ("stories", [("flags", flags as Any), ("count", count as Any), ("stories", stories as Any), ("pinnedToTop", pinnedToTop as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
public static func parse_stories(_ reader: BufferReader) -> Stories? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: [Api.StoryItem]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StoryItem.self)
}
var _4: [Int32]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.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)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.stories.Stories.stories(flags: _1!, count: _2!, stories: _3!, pinnedToTop: _4, chats: _5!, users: _6!)
}
else {
return nil
}
}
}
}
public extension Api.stories {
enum StoryReactionsList: TypeConstructorDescription {
case storyReactionsList(flags: Int32, count: Int32, reactions: [Api.StoryReaction], chats: [Api.Chat], users: [Api.User], nextOffset: String?)

View File

@ -2200,6 +2200,22 @@ public extension Api.functions.auth {
})
}
}
public extension Api.functions.bots {
static func addPreviewMedia(bot: Api.InputUser, media: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.MessageMedia>) {
let buffer = Buffer()
buffer.appendInt32(1633332331)
bot.serialize(buffer, true)
media.serialize(buffer, true)
return (FunctionDescription(name: "bots.addPreviewMedia", parameters: [("bot", String(describing: bot)), ("media", String(describing: media))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.MessageMedia? in
let reader = BufferReader(buffer)
var result: Api.MessageMedia?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.MessageMedia
}
return result
})
}
}
public extension Api.functions.bots {
static func allowSendMessage(bot: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
@ -2246,6 +2262,39 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.bots {
static func deletePreviewMedia(bot: Api.InputUser, media: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1220635873)
bot.serialize(buffer, true)
media.serialize(buffer, true)
return (FunctionDescription(name: "bots.deletePreviewMedia", parameters: [("bot", String(describing: bot)), ("media", String(describing: media))]), 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.bots {
static func editPreviewMedia(bot: Api.InputUser, media: Api.InputMedia, newMedia: Api.InputMedia) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.MessageMedia>) {
let buffer = Buffer()
buffer.appendInt32(-1436441263)
bot.serialize(buffer, true)
media.serialize(buffer, true)
newMedia.serialize(buffer, true)
return (FunctionDescription(name: "bots.editPreviewMedia", parameters: [("bot", String(describing: bot)), ("media", String(describing: media)), ("newMedia", String(describing: newMedia))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.MessageMedia? in
let reader = BufferReader(buffer)
var result: Api.MessageMedia?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.MessageMedia
}
return result
})
}
}
public extension Api.functions.bots {
static func getBotCommands(scope: Api.BotCommandScope, langCode: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.BotCommand]>) {
let buffer = Buffer()
@ -2294,6 +2343,37 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.bots {
static func getPopularAppBots(offset: String, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.bots.PopularAppBots>) {
let buffer = Buffer()
buffer.appendInt32(-1034878574)
serializeString(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "bots.getPopularAppBots", parameters: [("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.bots.PopularAppBots? in
let reader = BufferReader(buffer)
var result: Api.bots.PopularAppBots?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.bots.PopularAppBots
}
return result
})
}
}
public extension Api.functions.bots {
static func getPreviewMedias(bot: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.MessageMedia]>) {
let buffer = Buffer()
buffer.appendInt32(1720252591)
bot.serialize(buffer, true)
return (FunctionDescription(name: "bots.getPreviewMedias", parameters: [("bot", String(describing: bot))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Api.MessageMedia]? in
let reader = BufferReader(buffer)
var result: [Api.MessageMedia]?
if let _ = reader.readInt32() {
result = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageMedia.self)
}
return result
})
}
}
public extension Api.functions.bots {
static func invokeWebViewCustomMethod(bot: Api.InputUser, customMethod: String, params: Api.DataJSON) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.DataJSON>) {
let buffer = Buffer()
@ -2311,6 +2391,26 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.bots {
static func reorderPreviewMedias(bot: Api.InputUser, order: [Api.InputMedia]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1472444656)
bot.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
item.serialize(buffer, true)
}
return (FunctionDescription(name: "bots.reorderPreviewMedias", parameters: [("bot", String(describing: bot)), ("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.bots {
static func reorderUsernames(bot: Api.InputUser, order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()

View File

@ -134,6 +134,7 @@ public struct Namespaces {
public static let availableMessageEffects: Int8 = 37
public static let cachedStarsRevenueStats: Int8 = 38
public static let cachedRevenueStats: Int8 = 39
public static let recommendedApps: Int8 = 40
}
public struct UnorderedItemList {

View File

@ -46,6 +46,12 @@ private func entryId(peerId: EnginePeer.Id?) -> ItemCacheEntryId {
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.recommendedChannels, key: cacheKey)
}
private func appsEntryId() -> ItemCacheEntryId {
let cacheKey = ValueBoxKey(length: 8)
cacheKey.setInt64(0, value: 0)
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.recommendedApps, key: cacheKey)
}
func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.Id?, forceUpdate: Bool) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> (Peer?, Bool) in
if let peerId {
@ -134,6 +140,55 @@ func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.I
}
}
func _internal_requestRecommendedApps(account: Account, forceUpdate: Bool) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> (Peer?, Bool) in
if let entry = transaction.retrieveItemCacheEntry(id: appsEntryId())?.get(CachedRecommendedChannels.self), !entry.peerIds.isEmpty && !forceUpdate {
var shouldUpdate = false
if let timestamp = entry.timestamp {
if timestamp + 60 * 60 < Int32(Date().timeIntervalSince1970) {
shouldUpdate = true
}
} else {
shouldUpdate = true
}
return (nil, shouldUpdate)
} else {
return (nil, true)
}
}
|> mapToSignal { channel, shouldUpdate in
if !shouldUpdate {
return .complete()
}
return account.network.request(Api.functions.bots.getPopularAppBots(offset: "", limit: 100))
|> retryRequest
|> mapToSignal { result -> Signal<Never, NoError> in
return account.postbox.transaction { transaction -> [EnginePeer] in
let users: [Api.User]
let parsedPeers: AccumulatedPeers
switch result {
case let .popularAppBots(_, nextOffset, apiUsers):
let _ = nextOffset
users = apiUsers
}
parsedPeers = AccumulatedPeers(transaction: transaction, chats: [], users: users)
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers)
var peers: [EnginePeer] = []
for user in users {
if let peer = transaction.getPeer(user.peerId) {
peers.append(EnginePeer(peer))
}
}
if let entry = CodableEntry(CachedRecommendedChannels(peerIds: peers.map(\.id), count: Int32(peers.count), isHidden: false, timestamp: Int32(Date().timeIntervalSince1970))) {
transaction.putItemCacheEntry(id: appsEntryId(), entry: entry)
}
return peers
}
|> ignoreValues
}
}
}
public struct RecommendedChannels: Equatable {
public struct Channel: Equatable {
public var peer: EnginePeer
@ -167,6 +222,17 @@ func _internal_recommendedChannelPeerIds(account: Account, peerId: EnginePeer.Id
}
}
func _internal_recommendedAppPeerIds(account: Account) -> Signal<[EnginePeer.Id]?, NoError> {
let key = PostboxViewKey.cachedItem(appsEntryId())
return account.postbox.combinedView(keys: [key])
|> mapToSignal { views -> Signal<[EnginePeer.Id]?, NoError> in
guard let cachedChannels = (views.views[key] as? CachedItemView)?.value?.get(CachedRecommendedChannels.self), !cachedChannels.peerIds.isEmpty else {
return .single(nil)
}
return .single(cachedChannels.peerIds)
}
}
func _internal_recommendedChannels(account: Account, peerId: EnginePeer.Id?) -> Signal<RecommendedChannels?, NoError> {
let key = PostboxViewKey.cachedItem(entryId(peerId: peerId))
return account.postbox.combinedView(keys: [key])

View File

@ -12,6 +12,10 @@ func cachedRecentPeersEntryId() -> ItemCacheEntryId {
return ItemCacheEntryId(collectionId: 101, key: CachedRecentPeers.cacheKey())
}
func cachedRecentAppsEntryId() -> ItemCacheEntryId {
return ItemCacheEntryId(collectionId: 102, key: CachedRecentPeers.cacheKey())
}
public func _internal_recentPeers(accountPeerId: EnginePeer.Id, postbox: Postbox) -> Signal<RecentPeers, NoError> {
let key = PostboxViewKey.cachedItem(cachedRecentPeersEntryId())
return postbox.combinedView(keys: [key])
@ -248,3 +252,57 @@ func _internal_removeRecentlyUsedInlineBot(account: Account, peerId: PeerId) ->
}
} |> switchToLatest
}
public func _internal_recentApps(accountPeerId: PeerId, postbox: Postbox) -> Signal<[EnginePeer.Id], NoError> {
let key = PostboxViewKey.cachedItem(cachedRecentAppsEntryId())
return postbox.combinedView(keys: [key])
|> mapToSignal { views -> Signal<[EnginePeer.Id], NoError> in
if let value = (views.views[key] as? CachedItemView)?.value?.get(CachedRecentPeers.self) {
return .single(value.ids)
} else {
return .single([])
}
}
}
public func _internal_managedUpdatedRecentApps(accountPeerId: PeerId, postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let key = PostboxViewKey.cachedItem(cachedRecentAppsEntryId())
let peersEnabled = postbox.combinedView(keys: [key])
|> map { views -> Bool in
if let value = (views.views[key] as? CachedItemView)?.value?.get(CachedRecentPeers.self) {
return value.enabled
} else {
return true
}
}
|> distinctUntilChanged
let updateOnce =
network.request(Api.functions.contacts.getTopPeers(flags: 1 << 16, offset: 0, limit: 50, hash: 0))
|> `catch` { _ -> Signal<Api.contacts.TopPeers, NoError> in
return .complete()
}
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.transaction { transaction -> Void in
switch result {
case let .topPeers(_, _, users):
let parsedPeers = AccumulatedPeers(users: users)
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
if let entry = CodableEntry(CachedRecentPeers(enabled: true, ids: users.map { $0.peerId })) {
transaction.putItemCacheEntry(id: cachedRecentAppsEntryId(), entry: entry)
}
case .topPeersNotModified:
break
case .topPeersDisabled:
if let entry = CodableEntry(CachedRecentPeers(enabled: false, ids: [])) {
transaction.putItemCacheEntry(id: cachedRecentAppsEntryId(), entry: entry)
}
}
}
}
return peersEnabled |> mapToSignal { _ -> Signal<Void, NoError> in
return updateOnce
}
}

View File

@ -601,6 +601,14 @@ public extension TelegramEngine {
return _internal_managedUpdatedRecentPeers(accountPeerId: self.account.peerId, postbox: self.account.postbox, network: self.account.network)
}
public func recentApps() -> Signal<[EnginePeer.Id], NoError> {
return _internal_recentApps(accountPeerId: self.account.peerId, postbox: self.account.postbox)
}
public func managedUpdatedRecentApps() -> Signal<Void, NoError> {
return _internal_managedUpdatedRecentApps(accountPeerId: self.account.peerId, postbox: self.account.postbox, network: self.account.network)
}
public func removeRecentPeer(peerId: PeerId) -> Signal<Void, NoError> {
return _internal_removeRecentPeer(account: self.account, peerId: peerId)
}
@ -1423,10 +1431,18 @@ public extension TelegramEngine {
return _internal_requestRecommendedChannels(account: self.account, peerId: peerId, forceUpdate: forceUpdate)
}
public func recommendedAppPeerIds() -> Signal<[EnginePeer.Id]?, NoError> {
return _internal_recommendedAppPeerIds(account: self.account)
}
public func requestGlobalRecommendedChannelsIfNeeded() -> Signal<Never, NoError> {
return _internal_requestRecommendedChannels(account: self.account, peerId: nil, forceUpdate: false)
}
public func requestRecommendedAppsIfNeeded() -> Signal<Never, NoError> {
return _internal_requestRecommendedApps(account: self.account, forceUpdate: false)
}
public func isPremiumRequiredToContact(_ peerIds: [EnginePeer.Id]) -> Signal<[EnginePeer.Id], NoError> {
return _internal_updateIsPremiumRequiredToContact(account: self.account, peerIds: peerIds)
}