mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Update API [skip ci]
This commit is contained in:
parent
83a7019d0f
commit
85b6a8ffe9
@ -278,6 +278,12 @@ public enum StickerPackUrlType {
|
||||
case emoji
|
||||
}
|
||||
|
||||
public enum ResolvedStartAppMode {
|
||||
case generic
|
||||
case compact
|
||||
case fullscreen
|
||||
}
|
||||
|
||||
public enum ResolvedUrl {
|
||||
case externalUrl(String)
|
||||
case urlAuth(String)
|
||||
@ -1044,7 +1050,7 @@ public protocol SharedAccountContext: AnyObject {
|
||||
func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError>
|
||||
func makeMiniAppListScreen(context: AccountContext, initialData: MiniAppListScreenInitialData) -> ViewController
|
||||
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?)
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?)
|
||||
|
||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||
|
||||
|
@ -301,13 +301,13 @@ public struct ChatControllerInitialBotAppStart {
|
||||
public let botApp: BotApp?
|
||||
public let payload: String?
|
||||
public let justInstalled: Bool
|
||||
public let compact: Bool
|
||||
public let mode: ResolvedStartAppMode
|
||||
|
||||
public init(botApp: BotApp?, payload: String?, justInstalled: Bool, compact: Bool) {
|
||||
public init(botApp: BotApp?, payload: String?, justInstalled: Bool, mode: ResolvedStartAppMode) {
|
||||
self.botApp = botApp
|
||||
self.payload = payload
|
||||
self.justInstalled = justInstalled
|
||||
self.compact = compact
|
||||
self.mode = mode
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1460,8 +1460,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
||||
}
|
||||
}
|
||||
|
||||
if result.isEmpty, let webViewUrl = self.webView.url {
|
||||
let schemeAndHostUrl = webViewUrl.deletingPathExtension()
|
||||
if result.isEmpty, let webViewUrl = self.webView.url, let schemeAndHostUrl = URL(string: "/", relativeTo: webViewUrl) {
|
||||
let url = schemeAndHostUrl.appendingPathComponent("favicon.ico")
|
||||
result.insert(Favicon(url: url.absoluteString, dimensions: nil))
|
||||
}
|
||||
|
@ -3816,7 +3816,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
context: self.context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
peer: peer,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
@ -3840,7 +3841,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
context: self.context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
peer: peer,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
|
@ -83,6 +83,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1262359766] = { return Api.Boost.parse_boost($0) }
|
||||
dict[-1778593322] = { return Api.BotApp.parse_botApp($0) }
|
||||
dict[1571189943] = { return Api.BotApp.parse_botAppNotModified($0) }
|
||||
dict[-2103898979] = { return Api.BotAppSettings.parse_botAppSettings($0) }
|
||||
dict[-1989921868] = { return Api.BotBusinessConnection.parse_botBusinessConnection($0) }
|
||||
dict[-1032140601] = { return Api.BotCommand.parse_botCommand($0) }
|
||||
dict[-1180016534] = { return Api.BotCommandScope.parse_botCommandScopeChatAdmins($0) }
|
||||
@ -92,7 +93,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1071145937] = { return Api.BotCommandScope.parse_botCommandScopePeerAdmins($0) }
|
||||
dict[169026035] = { return Api.BotCommandScope.parse_botCommandScopePeerUser($0) }
|
||||
dict[1011811544] = { return Api.BotCommandScope.parse_botCommandScopeUsers($0) }
|
||||
dict[-2109505932] = { return Api.BotInfo.parse_botInfo($0) }
|
||||
dict[912290611] = { return Api.BotInfo.parse_botInfo($0) }
|
||||
dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) }
|
||||
dict[416402882] = { return Api.BotInlineMessage.parse_botInlineMessageMediaContact($0) }
|
||||
dict[85477117] = { return Api.BotInlineMessage.parse_botInlineMessageMediaGeo($0) }
|
||||
@ -974,7 +975,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[675009298] = { return Api.Update.parse_updateBotPurchasedPaidMedia($0) }
|
||||
dict[-1246823043] = { return Api.Update.parse_updateBotShippingQuery($0) }
|
||||
dict[-997782967] = { return Api.Update.parse_updateBotStopped($0) }
|
||||
dict[-1464975695] = { return Api.Update.parse_updateBotSubscriptionExpire($0) }
|
||||
dict[756270830] = { return Api.Update.parse_updateBotSubscriptionExpire($0) }
|
||||
dict[-2095595325] = { return Api.Update.parse_updateBotWebhookJSON($0) }
|
||||
dict[-1684914010] = { return Api.Update.parse_updateBotWebhookJSONQuery($0) }
|
||||
dict[-539401739] = { return Api.Update.parse_updateBroadcastRevenueTransactions($0) }
|
||||
@ -1266,6 +1267,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1626924713] = { return Api.messages.AvailableReactions.parse_availableReactionsNotModified($0) }
|
||||
dict[-347034123] = { return Api.messages.BotApp.parse_botApp($0) }
|
||||
dict[911761060] = { return Api.messages.BotCallbackAnswer.parse_botCallbackAnswer($0) }
|
||||
dict[-1899035375] = { return Api.messages.BotPreparedInlineMessage.parse_botPreparedInlineMessage($0) }
|
||||
dict[-534646026] = { return Api.messages.BotResults.parse_botResults($0) }
|
||||
dict[-1231326505] = { return Api.messages.ChatAdminsWithInvites.parse_chatAdminsWithInvites($0) }
|
||||
dict[-438840932] = { return Api.messages.ChatFull.parse_chatFull($0) }
|
||||
@ -1307,6 +1309,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-83926371] = { return Api.messages.MyStickers.parse_myStickers($0) }
|
||||
dict[863093588] = { return Api.messages.PeerDialogs.parse_peerDialogs($0) }
|
||||
dict[1753266509] = { return Api.messages.PeerSettings.parse_peerSettings($0) }
|
||||
dict[1636301421] = { return Api.messages.PreparedInlineMessage.parse_preparedInlineMessage($0) }
|
||||
dict[-963811691] = { return Api.messages.QuickReplies.parse_quickReplies($0) }
|
||||
dict[1603398491] = { return Api.messages.QuickReplies.parse_quickRepliesNotModified($0) }
|
||||
dict[-352454890] = { return Api.messages.Reactions.parse_reactions($0) }
|
||||
@ -1511,6 +1514,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.BotApp:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.BotAppSettings:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.BotBusinessConnection:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.BotCommand:
|
||||
@ -2297,6 +2302,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.BotCallbackAnswer:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.BotPreparedInlineMessage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.BotResults:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.ChatAdminsWithInvites:
|
||||
@ -2355,6 +2362,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.PeerSettings:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.PreparedInlineMessage:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.QuickReplies:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.Reactions:
|
||||
|
@ -1112,6 +1112,64 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum BotAppSettings: TypeConstructorDescription {
|
||||
case botAppSettings(flags: Int32, placeholderDocument: Api.Document?, backgroundColor: Int32?, backgroundDarkColor: Int32?, headerColor: Int32?, headerDarkColor: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botAppSettings(let flags, let placeholderDocument, let backgroundColor, let backgroundDarkColor, let headerColor, let headerDarkColor):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2103898979)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {placeholderDocument!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(backgroundColor!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(backgroundDarkColor!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(headerColor!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(headerDarkColor!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botAppSettings(let flags, let placeholderDocument, let backgroundColor, let backgroundDarkColor, let headerColor, let headerDarkColor):
|
||||
return ("botAppSettings", [("flags", flags as Any), ("placeholderDocument", placeholderDocument as Any), ("backgroundColor", backgroundColor as Any), ("backgroundDarkColor", backgroundDarkColor as Any), ("headerColor", headerColor as Any), ("headerDarkColor", headerDarkColor as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botAppSettings(_ reader: BufferReader) -> BotAppSettings? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Document?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Document
|
||||
} }
|
||||
var _3: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_3 = reader.readInt32() }
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() }
|
||||
var _6: Int32?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_6 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 4) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.BotAppSettings.botAppSettings(flags: _1!, placeholderDocument: _2, backgroundColor: _3, backgroundDarkColor: _4, headerColor: _5, headerDarkColor: _6)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum BotBusinessConnection: TypeConstructorDescription {
|
||||
case botBusinessConnection(flags: Int32, connectionId: String, userId: Int64, dcId: Int32, date: Int32)
|
||||
@ -1164,43 +1222,3 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum BotCommand: TypeConstructorDescription {
|
||||
case botCommand(command: String, description: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botCommand(let command, let description):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1032140601)
|
||||
}
|
||||
serializeString(command, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botCommand(let command, let description):
|
||||
return ("botCommand", [("command", command as Any), ("description", description as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botCommand(_ reader: BufferReader) -> BotCommand? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.BotCommand.botCommand(command: _1!, description: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,43 @@
|
||||
public extension Api {
|
||||
enum BotCommand: TypeConstructorDescription {
|
||||
case botCommand(command: String, description: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botCommand(let command, let description):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1032140601)
|
||||
}
|
||||
serializeString(command, buffer: buffer, boxed: false)
|
||||
serializeString(description, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botCommand(let command, let description):
|
||||
return ("botCommand", [("command", command as Any), ("description", description as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botCommand(_ reader: BufferReader) -> BotCommand? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.BotCommand.botCommand(command: _1!, description: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum BotCommandScope: TypeConstructorDescription {
|
||||
case botCommandScopeChatAdmins
|
||||
@ -136,13 +176,13 @@ public extension Api {
|
||||
}
|
||||
public extension Api {
|
||||
enum BotInfo: TypeConstructorDescription {
|
||||
case botInfo(flags: Int32, userId: Int64?, description: String?, descriptionPhoto: Api.Photo?, descriptionDocument: Api.Document?, commands: [Api.BotCommand]?, menuButton: Api.BotMenuButton?, privacyPolicyUrl: String?)
|
||||
case botInfo(flags: Int32, userId: Int64?, description: String?, descriptionPhoto: Api.Photo?, descriptionDocument: Api.Document?, commands: [Api.BotCommand]?, menuButton: Api.BotMenuButton?, privacyPolicyUrl: String?, appSettings: Api.BotAppSettings?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botInfo(let flags, let userId, let description, let descriptionPhoto, let descriptionDocument, let commands, let menuButton, let privacyPolicyUrl):
|
||||
case .botInfo(let flags, let userId, let description, let descriptionPhoto, let descriptionDocument, let commands, let menuButton, let privacyPolicyUrl, let appSettings):
|
||||
if boxed {
|
||||
buffer.appendInt32(-2109505932)
|
||||
buffer.appendInt32(912290611)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(userId!, buffer: buffer, boxed: false)}
|
||||
@ -156,14 +196,15 @@ public extension Api {
|
||||
}}
|
||||
if Int(flags) & Int(1 << 3) != 0 {menuButton!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 7) != 0 {serializeString(privacyPolicyUrl!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 8) != 0 {appSettings!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botInfo(let flags, let userId, let description, let descriptionPhoto, let descriptionDocument, let commands, let menuButton, let privacyPolicyUrl):
|
||||
return ("botInfo", [("flags", flags as Any), ("userId", userId as Any), ("description", description as Any), ("descriptionPhoto", descriptionPhoto as Any), ("descriptionDocument", descriptionDocument as Any), ("commands", commands as Any), ("menuButton", menuButton as Any), ("privacyPolicyUrl", privacyPolicyUrl as Any)])
|
||||
case .botInfo(let flags, let userId, let description, let descriptionPhoto, let descriptionDocument, let commands, let menuButton, let privacyPolicyUrl, let appSettings):
|
||||
return ("botInfo", [("flags", flags as Any), ("userId", userId as Any), ("description", description as Any), ("descriptionPhoto", descriptionPhoto as Any), ("descriptionDocument", descriptionDocument as Any), ("commands", commands as Any), ("menuButton", menuButton as Any), ("privacyPolicyUrl", privacyPolicyUrl as Any), ("appSettings", appSettings as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,6 +233,10 @@ public extension Api {
|
||||
} }
|
||||
var _8: String?
|
||||
if Int(_1!) & Int(1 << 7) != 0 {_8 = parseString(reader) }
|
||||
var _9: Api.BotAppSettings?
|
||||
if Int(_1!) & Int(1 << 8) != 0 {if let signature = reader.readInt32() {
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.BotAppSettings
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
@ -200,8 +245,9 @@ public extension Api {
|
||||
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 7) == 0) || _8 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||
return Api.BotInfo.botInfo(flags: _1!, userId: _2, description: _3, descriptionPhoto: _4, descriptionDocument: _5, commands: _6, menuButton: _7, privacyPolicyUrl: _8)
|
||||
let _c9 = (Int(_1!) & Int(1 << 8) == 0) || _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.BotInfo.botInfo(flags: _1!, userId: _2, description: _3, descriptionPhoto: _4, descriptionDocument: _5, commands: _6, menuButton: _7, privacyPolicyUrl: _8, appSettings: _9)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
@ -1164,49 +1210,3 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum BusinessGreetingMessage: TypeConstructorDescription {
|
||||
case businessGreetingMessage(shortcutId: Int32, recipients: Api.BusinessRecipients, noActivityDays: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays):
|
||||
if boxed {
|
||||
buffer.appendInt32(-451302485)
|
||||
}
|
||||
serializeInt32(shortcutId, buffer: buffer, boxed: false)
|
||||
recipients.serialize(buffer, true)
|
||||
serializeInt32(noActivityDays, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays):
|
||||
return ("businessGreetingMessage", [("shortcutId", shortcutId as Any), ("recipients", recipients as Any), ("noActivityDays", noActivityDays as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_businessGreetingMessage(_ reader: BufferReader) -> BusinessGreetingMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.BusinessRecipients?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.BusinessGreetingMessage.businessGreetingMessage(shortcutId: _1!, recipients: _2!, noActivityDays: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -645,7 +645,7 @@ public extension Api {
|
||||
case updateBotPurchasedPaidMedia(userId: Int64, payload: String, qts: Int32)
|
||||
case updateBotShippingQuery(queryId: Int64, userId: Int64, payload: Buffer, shippingAddress: Api.PostAddress)
|
||||
case updateBotStopped(userId: Int64, date: Int32, stopped: Api.Bool, qts: Int32)
|
||||
case updateBotSubscriptionExpire(userId: Int64, payload: String, untilDate: Int32, qts: Int32)
|
||||
case updateBotSubscriptionExpire(userId: Int64, payload: String, invoiceSlug: String, untilDate: Int32, qts: Int32)
|
||||
case updateBotWebhookJSON(data: Api.DataJSON)
|
||||
case updateBotWebhookJSONQuery(queryId: Int64, data: Api.DataJSON, timeout: Int32)
|
||||
case updateBroadcastRevenueTransactions(peer: Api.Peer, balances: Api.BroadcastRevenueBalances)
|
||||
@ -970,12 +970,13 @@ public extension Api {
|
||||
stopped.serialize(buffer, true)
|
||||
serializeInt32(qts, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .updateBotSubscriptionExpire(let userId, let payload, let untilDate, let qts):
|
||||
case .updateBotSubscriptionExpire(let userId, let payload, let invoiceSlug, let untilDate, let qts):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1464975695)
|
||||
buffer.appendInt32(756270830)
|
||||
}
|
||||
serializeInt64(userId, buffer: buffer, boxed: false)
|
||||
serializeString(payload, buffer: buffer, boxed: false)
|
||||
serializeString(invoiceSlug, buffer: buffer, boxed: false)
|
||||
serializeInt32(untilDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(qts, buffer: buffer, boxed: false)
|
||||
break
|
||||
@ -2051,8 +2052,8 @@ public extension Api {
|
||||
return ("updateBotShippingQuery", [("queryId", queryId as Any), ("userId", userId as Any), ("payload", payload as Any), ("shippingAddress", shippingAddress as Any)])
|
||||
case .updateBotStopped(let userId, let date, let stopped, let qts):
|
||||
return ("updateBotStopped", [("userId", userId as Any), ("date", date as Any), ("stopped", stopped as Any), ("qts", qts as Any)])
|
||||
case .updateBotSubscriptionExpire(let userId, let payload, let untilDate, let qts):
|
||||
return ("updateBotSubscriptionExpire", [("userId", userId as Any), ("payload", payload as Any), ("untilDate", untilDate as Any), ("qts", qts as Any)])
|
||||
case .updateBotSubscriptionExpire(let userId, let payload, let invoiceSlug, let untilDate, let qts):
|
||||
return ("updateBotSubscriptionExpire", [("userId", userId as Any), ("payload", payload as Any), ("invoiceSlug", invoiceSlug as Any), ("untilDate", untilDate as Any), ("qts", qts as Any)])
|
||||
case .updateBotWebhookJSON(let data):
|
||||
return ("updateBotWebhookJSON", [("data", data as Any)])
|
||||
case .updateBotWebhookJSONQuery(let queryId, let data, let timeout):
|
||||
@ -2749,16 +2750,19 @@ public extension Api {
|
||||
_1 = reader.readInt64()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int32?
|
||||
_5 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.Update.updateBotSubscriptionExpire(userId: _1!, payload: _2!, untilDate: _3!, qts: _4!)
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.Update.updateBotSubscriptionExpire(userId: _1!, payload: _2!, invoiceSlug: _3!, untilDate: _4!, qts: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -1,3 +1,49 @@
|
||||
public extension Api {
|
||||
enum BusinessGreetingMessage: TypeConstructorDescription {
|
||||
case businessGreetingMessage(shortcutId: Int32, recipients: Api.BusinessRecipients, noActivityDays: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays):
|
||||
if boxed {
|
||||
buffer.appendInt32(-451302485)
|
||||
}
|
||||
serializeInt32(shortcutId, buffer: buffer, boxed: false)
|
||||
recipients.serialize(buffer, true)
|
||||
serializeInt32(noActivityDays, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .businessGreetingMessage(let shortcutId, let recipients, let noActivityDays):
|
||||
return ("businessGreetingMessage", [("shortcutId", shortcutId as Any), ("recipients", recipients as Any), ("noActivityDays", noActivityDays as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_businessGreetingMessage(_ reader: BufferReader) -> BusinessGreetingMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.BusinessRecipients?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.BusinessRecipients
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.BusinessGreetingMessage.businessGreetingMessage(shortcutId: _1!, recipients: _2!, noActivityDays: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum BusinessIntro: TypeConstructorDescription {
|
||||
case businessIntro(flags: Int32, title: String, description: String, sticker: Api.Document?)
|
||||
|
@ -260,6 +260,46 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum BotPreparedInlineMessage: TypeConstructorDescription {
|
||||
case botPreparedInlineMessage(id: String, expireDate: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .botPreparedInlineMessage(let id, let expireDate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1899035375)
|
||||
}
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
serializeInt32(expireDate, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .botPreparedInlineMessage(let id, let expireDate):
|
||||
return ("botPreparedInlineMessage", [("id", id as Any), ("expireDate", expireDate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_botPreparedInlineMessage(_ reader: BufferReader) -> BotPreparedInlineMessage? {
|
||||
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.messages.BotPreparedInlineMessage.botPreparedInlineMessage(id: _1!, expireDate: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum BotResults: TypeConstructorDescription {
|
||||
case botResults(flags: Int32, queryId: Int64, nextOffset: String?, switchPm: Api.InlineBotSwitchPM?, switchWebview: Api.InlineBotWebView?, results: [Api.BotInlineResult], cacheTime: Int32, users: [Api.User])
|
||||
@ -1398,61 +1438,3 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum FoundStickerSets: TypeConstructorDescription {
|
||||
case foundStickerSets(hash: Int64, sets: [Api.StickerSetCovered])
|
||||
case foundStickerSetsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .foundStickerSets(let hash, let sets):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1963942446)
|
||||
}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(sets.count))
|
||||
for item in sets {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .foundStickerSetsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(223655517)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .foundStickerSets(let hash, let sets):
|
||||
return ("foundStickerSets", [("hash", hash as Any), ("sets", sets as Any)])
|
||||
case .foundStickerSetsNotModified:
|
||||
return ("foundStickerSetsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_foundStickerSets(_ reader: BufferReader) -> FoundStickerSets? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: [Api.StickerSetCovered]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSetCovered.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.FoundStickerSets.foundStickerSets(hash: _1!, sets: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_foundStickerSetsNotModified(_ reader: BufferReader) -> FoundStickerSets? {
|
||||
return Api.messages.FoundStickerSets.foundStickerSetsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,61 @@
|
||||
public extension Api.messages {
|
||||
enum FoundStickerSets: TypeConstructorDescription {
|
||||
case foundStickerSets(hash: Int64, sets: [Api.StickerSetCovered])
|
||||
case foundStickerSetsNotModified
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .foundStickerSets(let hash, let sets):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1963942446)
|
||||
}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(sets.count))
|
||||
for item in sets {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .foundStickerSetsNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(223655517)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .foundStickerSets(let hash, let sets):
|
||||
return ("foundStickerSets", [("hash", hash as Any), ("sets", sets as Any)])
|
||||
case .foundStickerSetsNotModified:
|
||||
return ("foundStickerSetsNotModified", [])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_foundStickerSets(_ reader: BufferReader) -> FoundStickerSets? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: [Api.StickerSetCovered]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StickerSetCovered.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.FoundStickerSets.foundStickerSets(hash: _1!, sets: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_foundStickerSetsNotModified(_ reader: BufferReader) -> FoundStickerSets? {
|
||||
return Api.messages.FoundStickerSets.foundStickerSetsNotModified
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum HighScores: TypeConstructorDescription {
|
||||
case highScores(scores: [Api.HighScore], users: [Api.User])
|
||||
@ -806,6 +864,68 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum PreparedInlineMessage: TypeConstructorDescription {
|
||||
case preparedInlineMessage(queryId: Int64, result: Api.BotInlineResult, peerTypes: [Api.InlineQueryPeerType], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .preparedInlineMessage(let queryId, let result, let peerTypes, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1636301421)
|
||||
}
|
||||
serializeInt64(queryId, buffer: buffer, boxed: false)
|
||||
result.serialize(buffer, true)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(peerTypes.count))
|
||||
for item in peerTypes {
|
||||
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 .preparedInlineMessage(let queryId, let result, let peerTypes, let users):
|
||||
return ("preparedInlineMessage", [("queryId", queryId as Any), ("result", result as Any), ("peerTypes", peerTypes as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_preparedInlineMessage(_ reader: BufferReader) -> PreparedInlineMessage? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: Api.BotInlineResult?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.BotInlineResult
|
||||
}
|
||||
var _3: [Api.InlineQueryPeerType]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InlineQueryPeerType.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.PreparedInlineMessage.preparedInlineMessage(queryId: _1!, result: _2!, peerTypes: _3!, users: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum QuickReplies: TypeConstructorDescription {
|
||||
case quickReplies(quickReplies: [Api.QuickReply], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
@ -1340,203 +1460,3 @@ public extension Api.messages {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsCalendar: TypeConstructorDescription {
|
||||
case searchResultsCalendar(flags: Int32, count: Int32, minDate: Int32, minMsgId: Int32, offsetIdOffset: Int32?, periods: [Api.SearchResultsCalendarPeriod], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(343859772)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeInt32(minDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(periods.count))
|
||||
for item in periods {
|
||||
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 .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
return ("searchResultsCalendar", [("flags", flags as Any), ("count", count as Any), ("minDate", minDate as Any), ("minMsgId", minMsgId as Any), ("offsetIdOffset", offsetIdOffset as Any), ("periods", periods as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsCalendar(_ reader: BufferReader) -> SearchResultsCalendar? {
|
||||
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?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Api.SearchResultsCalendarPeriod]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsCalendarPeriod.self)
|
||||
}
|
||||
var _7: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = 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 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.messages.SearchResultsCalendar.searchResultsCalendar(flags: _1!, count: _2!, minDate: _3!, minMsgId: _4!, offsetIdOffset: _5, periods: _6!, messages: _7!, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsPositions: TypeConstructorDescription {
|
||||
case searchResultsPositions(count: Int32, positions: [Api.SearchResultsPosition])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1404185519)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(positions.count))
|
||||
for item in positions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
return ("searchResultsPositions", [("count", count as Any), ("positions", positions as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsPositions(_ reader: BufferReader) -> SearchResultsPositions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.SearchResultsPosition]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsPosition.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SearchResultsPositions.searchResultsPositions(count: _1!, positions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SentEncryptedMessage: TypeConstructorDescription {
|
||||
case sentEncryptedFile(date: Int32, file: Api.EncryptedFile)
|
||||
case sentEncryptedMessage(date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1802240206)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
file.serialize(buffer, true)
|
||||
break
|
||||
case .sentEncryptedMessage(let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(1443858741)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
return ("sentEncryptedFile", [("date", date as Any), ("file", file as Any)])
|
||||
case .sentEncryptedMessage(let date):
|
||||
return ("sentEncryptedMessage", [("date", date as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEncryptedFile(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.EncryptedFile?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.EncryptedFile
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedFile(date: _1!, file: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sentEncryptedMessage(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedMessage(date: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,203 @@
|
||||
public extension Api.messages {
|
||||
enum SearchResultsCalendar: TypeConstructorDescription {
|
||||
case searchResultsCalendar(flags: Int32, count: Int32, minDate: Int32, minMsgId: Int32, offsetIdOffset: Int32?, periods: [Api.SearchResultsCalendarPeriod], messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(343859772)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
serializeInt32(minDate, buffer: buffer, boxed: false)
|
||||
serializeInt32(minMsgId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(periods.count))
|
||||
for item in periods {
|
||||
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 .searchResultsCalendar(let flags, let count, let minDate, let minMsgId, let offsetIdOffset, let periods, let messages, let chats, let users):
|
||||
return ("searchResultsCalendar", [("flags", flags as Any), ("count", count as Any), ("minDate", minDate as Any), ("minMsgId", minMsgId as Any), ("offsetIdOffset", offsetIdOffset as Any), ("periods", periods as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsCalendar(_ reader: BufferReader) -> SearchResultsCalendar? {
|
||||
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?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_5 = reader.readInt32() }
|
||||
var _6: [Api.SearchResultsCalendarPeriod]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsCalendarPeriod.self)
|
||||
}
|
||||
var _7: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = 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 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.messages.SearchResultsCalendar.searchResultsCalendar(flags: _1!, count: _2!, minDate: _3!, minMsgId: _4!, offsetIdOffset: _5, periods: _6!, messages: _7!, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SearchResultsPositions: TypeConstructorDescription {
|
||||
case searchResultsPositions(count: Int32, positions: [Api.SearchResultsPosition])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
if boxed {
|
||||
buffer.appendInt32(1404185519)
|
||||
}
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(positions.count))
|
||||
for item in positions {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .searchResultsPositions(let count, let positions):
|
||||
return ("searchResultsPositions", [("count", count as Any), ("positions", positions as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_searchResultsPositions(_ reader: BufferReader) -> SearchResultsPositions? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: [Api.SearchResultsPosition]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.SearchResultsPosition.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SearchResultsPositions.searchResultsPositions(count: _1!, positions: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SentEncryptedMessage: TypeConstructorDescription {
|
||||
case sentEncryptedFile(date: Int32, file: Api.EncryptedFile)
|
||||
case sentEncryptedMessage(date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1802240206)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
file.serialize(buffer, true)
|
||||
break
|
||||
case .sentEncryptedMessage(let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(1443858741)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .sentEncryptedFile(let date, let file):
|
||||
return ("sentEncryptedFile", [("date", date as Any), ("file", file as Any)])
|
||||
case .sentEncryptedMessage(let date):
|
||||
return ("sentEncryptedMessage", [("date", date as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_sentEncryptedFile(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.EncryptedFile?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.EncryptedFile
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedFile(date: _1!, file: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_sentEncryptedMessage(_ reader: BufferReader) -> SentEncryptedMessage? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.messages.SentEncryptedMessage.sentEncryptedMessage(date: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.messages {
|
||||
enum SponsoredMessages: TypeConstructorDescription {
|
||||
case sponsoredMessages(flags: Int32, postsBetween: Int32?, messages: [Api.SponsoredMessage], chats: [Api.Chat], users: [Api.User])
|
||||
@ -1330,243 +1530,3 @@ public extension Api.payments {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsRevenueStats: TypeConstructorDescription {
|
||||
case starsRevenueStats(revenueGraph: Api.StatsGraph, status: Api.StarsRevenueStatus, usdRate: Double)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueStats(let revenueGraph, let status, let usdRate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-919881925)
|
||||
}
|
||||
revenueGraph.serialize(buffer, true)
|
||||
status.serialize(buffer, true)
|
||||
serializeDouble(usdRate, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueStats(let revenueGraph, let status, let usdRate):
|
||||
return ("starsRevenueStats", [("revenueGraph", revenueGraph as Any), ("status", status as Any), ("usdRate", usdRate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueStats(_ reader: BufferReader) -> StarsRevenueStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _2: Api.StarsRevenueStatus?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarsRevenueStatus
|
||||
}
|
||||
var _3: Double?
|
||||
_3 = reader.readDouble()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.payments.StarsRevenueStats.starsRevenueStats(revenueGraph: _1!, status: _2!, usdRate: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsRevenueWithdrawalUrl: TypeConstructorDescription {
|
||||
case starsRevenueWithdrawalUrl(url: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueWithdrawalUrl(let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(497778871)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueWithdrawalUrl(let url):
|
||||
return ("starsRevenueWithdrawalUrl", [("url", url as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueWithdrawalUrl(_ reader: BufferReader) -> StarsRevenueWithdrawalUrl? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.StarsRevenueWithdrawalUrl.starsRevenueWithdrawalUrl(url: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsStatus: TypeConstructorDescription {
|
||||
case starsStatus(flags: Int32, balance: Int64, subscriptions: [Api.StarsSubscription]?, subscriptionsNextOffset: String?, subscriptionsMissingBalance: Int64?, history: [Api.StarsTransaction]?, nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1141231252)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(balance, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(subscriptions!.count))
|
||||
for item in subscriptions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(subscriptionsNextOffset!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(subscriptionsMissingBalance!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(history!.count))
|
||||
for item in history! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("subscriptions", subscriptions as Any), ("subscriptionsNextOffset", subscriptionsNextOffset as Any), ("subscriptionsMissingBalance", subscriptionsMissingBalance as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsStatus(_ reader: BufferReader) -> StarsStatus? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: [Api.StarsSubscription]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsSubscription.self)
|
||||
} }
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = parseString(reader) }
|
||||
var _5: Int64?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_5 = reader.readInt64() }
|
||||
var _6: [Api.StarsTransaction]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
|
||||
} }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, subscriptions: _3, subscriptionsNextOffset: _4, subscriptionsMissingBalance: _5, history: _6, nextOffset: _7, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum UserStarGifts: TypeConstructorDescription {
|
||||
case userStarGifts(flags: Int32, count: Int32, gifts: [Api.UserStarGift], nextOffset: String?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1801827607)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(gifts.count))
|
||||
for item in gifts {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
return ("userStarGifts", [("flags", flags as Any), ("count", count as Any), ("gifts", gifts as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_userStarGifts(_ reader: BufferReader) -> UserStarGifts? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.UserStarGift]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.UserStarGift.self)
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.payments.UserStarGifts.userStarGifts(flags: _1!, count: _2!, gifts: _3!, nextOffset: _4, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,243 @@
|
||||
public extension Api.payments {
|
||||
enum StarsRevenueStats: TypeConstructorDescription {
|
||||
case starsRevenueStats(revenueGraph: Api.StatsGraph, status: Api.StarsRevenueStatus, usdRate: Double)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueStats(let revenueGraph, let status, let usdRate):
|
||||
if boxed {
|
||||
buffer.appendInt32(-919881925)
|
||||
}
|
||||
revenueGraph.serialize(buffer, true)
|
||||
status.serialize(buffer, true)
|
||||
serializeDouble(usdRate, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueStats(let revenueGraph, let status, let usdRate):
|
||||
return ("starsRevenueStats", [("revenueGraph", revenueGraph as Any), ("status", status as Any), ("usdRate", usdRate as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueStats(_ reader: BufferReader) -> StarsRevenueStats? {
|
||||
var _1: Api.StatsGraph?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.StatsGraph
|
||||
}
|
||||
var _2: Api.StarsRevenueStatus?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.StarsRevenueStatus
|
||||
}
|
||||
var _3: Double?
|
||||
_3 = reader.readDouble()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.payments.StarsRevenueStats.starsRevenueStats(revenueGraph: _1!, status: _2!, usdRate: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsRevenueWithdrawalUrl: TypeConstructorDescription {
|
||||
case starsRevenueWithdrawalUrl(url: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsRevenueWithdrawalUrl(let url):
|
||||
if boxed {
|
||||
buffer.appendInt32(497778871)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsRevenueWithdrawalUrl(let url):
|
||||
return ("starsRevenueWithdrawalUrl", [("url", url as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsRevenueWithdrawalUrl(_ reader: BufferReader) -> StarsRevenueWithdrawalUrl? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.payments.StarsRevenueWithdrawalUrl.starsRevenueWithdrawalUrl(url: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum StarsStatus: TypeConstructorDescription {
|
||||
case starsStatus(flags: Int32, balance: Int64, subscriptions: [Api.StarsSubscription]?, subscriptionsNextOffset: String?, subscriptionsMissingBalance: Int64?, history: [Api.StarsTransaction]?, nextOffset: String?, chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1141231252)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(balance, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(subscriptions!.count))
|
||||
for item in subscriptions! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(subscriptionsNextOffset!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(subscriptionsMissingBalance!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(history!.count))
|
||||
for item in history! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let subscriptionsMissingBalance, let history, let nextOffset, let chats, let users):
|
||||
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("subscriptions", subscriptions as Any), ("subscriptionsNextOffset", subscriptionsNextOffset as Any), ("subscriptionsMissingBalance", subscriptionsMissingBalance as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_starsStatus(_ reader: BufferReader) -> StarsStatus? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: [Api.StarsSubscription]?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsSubscription.self)
|
||||
} }
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {_4 = parseString(reader) }
|
||||
var _5: Int64?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {_5 = reader.readInt64() }
|
||||
var _6: [Api.StarsTransaction]?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
|
||||
} }
|
||||
var _7: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
|
||||
var _8: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _9: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
|
||||
let _c8 = _8 != nil
|
||||
let _c9 = _9 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
||||
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, subscriptions: _3, subscriptionsNextOffset: _4, subscriptionsMissingBalance: _5, history: _6, nextOffset: _7, chats: _8!, users: _9!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum UserStarGifts: TypeConstructorDescription {
|
||||
case userStarGifts(flags: Int32, count: Int32, gifts: [Api.UserStarGift], nextOffset: String?, users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(1801827607)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(count, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(gifts.count))
|
||||
for item in gifts {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .userStarGifts(let flags, let count, let gifts, let nextOffset, let users):
|
||||
return ("userStarGifts", [("flags", flags as Any), ("count", count as Any), ("gifts", gifts as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_userStarGifts(_ reader: BufferReader) -> UserStarGifts? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: [Api.UserStarGift]?
|
||||
if let _ = reader.readInt32() {
|
||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.UserStarGift.self)
|
||||
}
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
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
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.payments.UserStarGifts.userStarGifts(flags: _1!, count: _2!, gifts: _3!, nextOffset: _4, users: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api.payments {
|
||||
enum ValidatedRequestedInfo: TypeConstructorDescription {
|
||||
case validatedRequestedInfo(flags: Int32, id: String?, shippingOptions: [Api.ShippingOption]?)
|
||||
|
@ -2574,6 +2574,22 @@ public extension Api.functions.bots {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.bots {
|
||||
static func toggleUserEmojiStatusPermission(bot: Api.InputUser, enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(115237778)
|
||||
bot.serialize(buffer, true)
|
||||
enabled.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "bots.toggleUserEmojiStatusPermission", parameters: [("bot", String(describing: bot)), ("enabled", String(describing: enabled))]), 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 toggleUsername(bot: Api.InputUser, username: String, active: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
@ -2591,6 +2607,22 @@ public extension Api.functions.bots {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.bots {
|
||||
static func updateUserEmojiStatus(userId: Api.InputUser, emojiStatus: Api.EmojiStatus) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-308334395)
|
||||
userId.serialize(buffer, true)
|
||||
emojiStatus.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "bots.updateUserEmojiStatus", parameters: [("userId", String(describing: userId)), ("emojiStatus", String(describing: emojiStatus))]), 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.channels {
|
||||
static func checkUsername(channel: Api.InputChannel, username: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
@ -6493,6 +6525,22 @@ public extension Api.functions.messages {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func getPreparedInlineMessage(bot: Api.InputUser, id: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.PreparedInlineMessage>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-2055291464)
|
||||
bot.serialize(buffer, true)
|
||||
serializeString(id, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "messages.getPreparedInlineMessage", parameters: [("bot", String(describing: bot)), ("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.PreparedInlineMessage? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.messages.PreparedInlineMessage?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.messages.PreparedInlineMessage
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func getQuickReplies(hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.QuickReplies>) {
|
||||
let buffer = Buffer()
|
||||
@ -7608,6 +7656,28 @@ public extension Api.functions.messages {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func savePreparedInlineMessage(flags: Int32, result: Api.InputBotInlineResult, userId: Api.InputUser, peerTypes: [Api.InlineQueryPeerType]?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.BotPreparedInlineMessage>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-232816849)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
result.serialize(buffer, true)
|
||||
userId.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(peerTypes!.count))
|
||||
for item in peerTypes! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
return (FunctionDescription(name: "messages.savePreparedInlineMessage", parameters: [("flags", String(describing: flags)), ("result", String(describing: result)), ("userId", String(describing: userId)), ("peerTypes", String(describing: peerTypes))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.BotPreparedInlineMessage? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.messages.BotPreparedInlineMessage?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.messages.BotPreparedInlineMessage
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func saveRecentSticker(flags: Int32, id: Api.InputDocument, unsave: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
@ -8775,6 +8845,24 @@ public extension Api.functions.payments {
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func botCancelStarsSubscription(flags: Int32, userId: Api.InputUser, invoiceSlug: String?, chargeId: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1475996902)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
userId.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(invoiceSlug!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {serializeString(chargeId!, buffer: buffer, boxed: false)}
|
||||
return (FunctionDescription(name: "payments.botCancelStarsSubscription", parameters: [("flags", String(describing: flags)), ("userId", String(describing: userId)), ("invoiceSlug", String(describing: invoiceSlug)), ("chargeId", String(describing: chargeId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Bool?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.payments {
|
||||
static func canPurchasePremium(purpose: Api.InputStorePaymentPurpose) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
@ -13,10 +13,25 @@ extension BotMenuButton {
|
||||
}
|
||||
}
|
||||
|
||||
extension BotAppSettings {
|
||||
init(apiBotAppSettings: Api.BotAppSettings) {
|
||||
switch apiBotAppSettings {
|
||||
case let .botAppSettings(_, placeholderDocument, backgroundColor, backgroundDarkColor, headerColor, headerDarkColor):
|
||||
self.init(
|
||||
placeholder: placeholderDocument.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) },
|
||||
backgroundColor: backgroundColor,
|
||||
backgroundDarkColor: backgroundDarkColor,
|
||||
headerColor: headerColor,
|
||||
headerDarkColor: headerDarkColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BotInfo {
|
||||
convenience init(apiBotInfo: Api.BotInfo) {
|
||||
switch apiBotInfo {
|
||||
case let .botInfo(_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton, privacyPolicyUrl):
|
||||
case let .botInfo(_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton, privacyPolicyUrl, appSettings):
|
||||
let photo: TelegramMediaImage? = descriptionPhoto.flatMap(telegramMediaImageFromApiPhoto)
|
||||
let video: TelegramMediaFile? = descriptionDocument.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
var commands: [BotCommand] = []
|
||||
@ -32,7 +47,7 @@ extension BotInfo {
|
||||
if let apiMenuButton = apiMenuButton {
|
||||
menuButton = BotMenuButton(apiBotMenuButton: apiMenuButton)
|
||||
}
|
||||
self.init(description: description ?? "", photo: photo, video: video, commands: commands, menuButton: menuButton, privacyPolicyUrl: privacyPolicyUrl)
|
||||
self.init(description: description ?? "", photo: photo, video: video, commands: commands, menuButton: menuButton, privacyPolicyUrl: privacyPolicyUrl, appSettings: appSettings.flatMap { BotAppSettings(apiBotAppSettings: $0) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,22 @@ import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
|
||||
extension ReplyMarkupButtonAction.PeerTypes {
|
||||
init?(apiType: Api.InlineQueryPeerType) {
|
||||
switch apiType {
|
||||
case .inlineQueryPeerTypePM:
|
||||
self = .users
|
||||
case .inlineQueryPeerTypeBotPM:
|
||||
self = .bots
|
||||
case .inlineQueryPeerTypeBroadcast:
|
||||
self = .channels
|
||||
case .inlineQueryPeerTypeChat, .inlineQueryPeerTypeMegagroup:
|
||||
self = .groups
|
||||
case .inlineQueryPeerTypeSameBotPM:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ReplyMarkupButton {
|
||||
init(apiButton: Api.KeyboardButton) {
|
||||
|
@ -1706,14 +1706,14 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
||||
updatedState.updateCachedPeerData(peer.peerId, { current in
|
||||
if peer.peerId.namespace == Namespaces.Peer.CloudUser, let previous = current as? CachedUserData {
|
||||
if let botInfo = previous.botInfo {
|
||||
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: commands, menuButton: botInfo.menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl))
|
||||
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: commands, menuButton: botInfo.menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl, appSettings: botInfo.appSettings))
|
||||
}
|
||||
} else if peer.peerId.namespace == Namespaces.Peer.CloudGroup, let previous = current as? CachedGroupData {
|
||||
if let index = previous.botInfos.firstIndex(where: { $0.peerId == botPeerId }) {
|
||||
var updatedBotInfos = previous.botInfos
|
||||
let previousBotInfo = updatedBotInfos[index]
|
||||
updatedBotInfos.remove(at: index)
|
||||
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton, privacyPolicyUrl: previousBotInfo.botInfo.privacyPolicyUrl)), at: index)
|
||||
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton, privacyPolicyUrl: previousBotInfo.botInfo.privacyPolicyUrl, appSettings: previousBotInfo.botInfo.appSettings)), at: index)
|
||||
return previous.withUpdatedBotInfos(updatedBotInfos)
|
||||
}
|
||||
} else if peer.peerId.namespace == Namespaces.Peer.CloudChannel, let previous = current as? CachedChannelData {
|
||||
@ -1721,7 +1721,7 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
||||
var updatedBotInfos = previous.botInfos
|
||||
let previousBotInfo = updatedBotInfos[index]
|
||||
updatedBotInfos.remove(at: index)
|
||||
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton, privacyPolicyUrl: previousBotInfo.botInfo.privacyPolicyUrl)), at: index)
|
||||
updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton, privacyPolicyUrl: previousBotInfo.botInfo.privacyPolicyUrl, appSettings: previousBotInfo.botInfo.appSettings)), at: index)
|
||||
return previous.withUpdatedBotInfos(updatedBotInfos)
|
||||
}
|
||||
}
|
||||
@ -1733,7 +1733,7 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
||||
updatedState.updateCachedPeerData(botPeerId, { current in
|
||||
if let previous = current as? CachedUserData {
|
||||
if let botInfo = previous.botInfo {
|
||||
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: botInfo.commands, menuButton: menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl))
|
||||
return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: botInfo.commands, menuButton: menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl, appSettings: botInfo.appSettings))
|
||||
}
|
||||
}
|
||||
return current
|
||||
|
@ -45,6 +45,62 @@ public enum BotMenuButton: PostboxCoding, Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct BotAppSettings: PostboxCoding, Equatable {
|
||||
public let placeholder: TelegramMediaFile?
|
||||
public let backgroundColor: Int32?
|
||||
public let backgroundDarkColor: Int32?
|
||||
public let headerColor: Int32?
|
||||
public let headerDarkColor: Int32?
|
||||
|
||||
public init(placeholder: TelegramMediaFile?, backgroundColor: Int32?, backgroundDarkColor: Int32?, headerColor: Int32?, headerDarkColor: Int32?) {
|
||||
self.placeholder = placeholder
|
||||
self.backgroundColor = backgroundColor
|
||||
self.backgroundDarkColor = backgroundDarkColor
|
||||
self.headerColor = headerColor
|
||||
self.headerDarkColor = headerDarkColor
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
if let placeholder = decoder.decodeObjectForKey("p", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile {
|
||||
self.placeholder = placeholder
|
||||
} else {
|
||||
self.placeholder = nil
|
||||
}
|
||||
self.backgroundColor = decoder.decodeOptionalInt32ForKey("b")
|
||||
self.backgroundDarkColor = decoder.decodeOptionalInt32ForKey("bd")
|
||||
self.headerColor = decoder.decodeOptionalInt32ForKey("h")
|
||||
self.headerDarkColor = decoder.decodeOptionalInt32ForKey("hd")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
if let placeholder = self.placeholder {
|
||||
encoder.encodeObject(placeholder, forKey: "p")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "p")
|
||||
}
|
||||
if let backgroundColor = self.backgroundColor {
|
||||
encoder.encodeInt32(backgroundColor, forKey: "b")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "b")
|
||||
}
|
||||
if let backgroundDarkColor = self.backgroundDarkColor {
|
||||
encoder.encodeInt32(backgroundDarkColor, forKey: "bd")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "bd")
|
||||
}
|
||||
if let headerColor = self.headerColor {
|
||||
encoder.encodeInt32(headerColor, forKey: "h")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "h")
|
||||
}
|
||||
if let headerDarkColor = self.headerDarkColor {
|
||||
encoder.encodeInt32(headerDarkColor, forKey: "hd")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "hd")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class BotInfo: PostboxCoding, Equatable {
|
||||
public let description: String
|
||||
public let photo: TelegramMediaImage?
|
||||
@ -52,14 +108,16 @@ public final class BotInfo: PostboxCoding, Equatable {
|
||||
public let commands: [BotCommand]
|
||||
public let menuButton: BotMenuButton
|
||||
public let privacyPolicyUrl: String?
|
||||
public let appSettings: BotAppSettings?
|
||||
|
||||
public init(description: String, photo: TelegramMediaImage?, video: TelegramMediaFile?, commands: [BotCommand], menuButton: BotMenuButton, privacyPolicyUrl: String?) {
|
||||
public init(description: String, photo: TelegramMediaImage?, video: TelegramMediaFile?, commands: [BotCommand], menuButton: BotMenuButton, privacyPolicyUrl: String?, appSettings: BotAppSettings?) {
|
||||
self.description = description
|
||||
self.photo = photo
|
||||
self.video = video
|
||||
self.commands = commands
|
||||
self.menuButton = menuButton
|
||||
self.privacyPolicyUrl = privacyPolicyUrl
|
||||
self.appSettings = appSettings
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
@ -77,6 +135,11 @@ public final class BotInfo: PostboxCoding, Equatable {
|
||||
self.commands = decoder.decodeObjectArrayWithDecoderForKey("c")
|
||||
self.menuButton = (decoder.decodeObjectForKey("b", decoder: { BotMenuButton(decoder: $0) }) as? BotMenuButton) ?? .commands
|
||||
self.privacyPolicyUrl = decoder.decodeOptionalStringForKey("pp")
|
||||
if let appSettings = decoder.decodeObjectForKey("as", decoder: { BotAppSettings(decoder: $0) }) as? BotAppSettings {
|
||||
self.appSettings = appSettings
|
||||
} else {
|
||||
self.appSettings = nil
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -98,9 +161,14 @@ public final class BotInfo: PostboxCoding, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "pp")
|
||||
}
|
||||
if let appSettings = self.appSettings {
|
||||
encoder.encodeObject(appSettings, forKey: "as")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "as")
|
||||
}
|
||||
}
|
||||
|
||||
public static func ==(lhs: BotInfo, rhs: BotInfo) -> Bool {
|
||||
return lhs.description == rhs.description && lhs.commands == rhs.commands && lhs.menuButton == rhs.menuButton && lhs.photo == rhs.photo && lhs.privacyPolicyUrl == rhs.privacyPolicyUrl
|
||||
return lhs.description == rhs.description && lhs.commands == rhs.commands && lhs.menuButton == rhs.menuButton && lhs.photo == rhs.photo && lhs.privacyPolicyUrl == rhs.privacyPolicyUrl && lhs.appSettings == rhs.appSettings
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,7 @@ public struct CachedUserFlags: OptionSet {
|
||||
public static let premiumRequired = CachedUserFlags(rawValue: 1 << 3)
|
||||
public static let adsEnabled = CachedUserFlags(rawValue: 1 << 4)
|
||||
public static let canViewRevenue = CachedUserFlags(rawValue: 1 << 5)
|
||||
public static let botCanManageEmojiStatus = CachedUserFlags(rawValue: 1 << 6)
|
||||
}
|
||||
|
||||
public final class EditableBotInfo: PostboxCoding, Equatable {
|
||||
|
@ -1126,6 +1126,34 @@ public extension TelegramEngine.EngineData.Item {
|
||||
}
|
||||
}
|
||||
|
||||
public struct CanManageEmojiStatus: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Bool
|
||||
|
||||
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.flags.contains(.botCanManageEmojiStatus)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct CanViewStarsRevenue: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||
public typealias Result = Bool
|
||||
|
||||
|
@ -67,7 +67,7 @@ func _internal_requestSimpleWebView(postbox: Postbox, network: Network, botId: P
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
func _internal_requestMainWebView(postbox: Postbox, network: Network, botId: PeerId, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
func _internal_requestMainWebView(postbox: Postbox, network: Network, peerId: PeerId, botId: PeerId, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
@ -76,7 +76,7 @@ func _internal_requestMainWebView(postbox: Postbox, network: Network, botId: Pee
|
||||
guard let bot = transaction.getPeer(botId), let inputUser = apiInputUser(bot) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
guard let peer = transaction.getPeer(botId), let inputPeer = apiInputPeer(peer) else {
|
||||
guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ func _internal_sendWebViewData(postbox: Postbox, network: Network, stateManager:
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, appReference: BotAppReference, payload: String?, themeParams: [String: Any]?, compact: Bool, allowWrite: Bool) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, appReference: BotAppReference, payload: String?, themeParams: [String: Any]?, compact: Bool, fullscreen: Bool, allowWrite: Bool) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
@ -321,6 +321,9 @@ func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManage
|
||||
if compact {
|
||||
flags |= (1 << 7)
|
||||
}
|
||||
if fullscreen {
|
||||
flags |= (1 << 8)
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.requestAppWebView(flags: flags, peer: inputPeer, app: app, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform))
|
||||
|> mapError { _ -> RequestWebViewError in
|
||||
|
@ -0,0 +1,40 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
public struct PreparedInlineMessage: Equatable {
|
||||
let queryId: Int64
|
||||
let result: ChatContextResult
|
||||
let peerTypes: [ReplyMarkupButtonAction.PeerTypes]
|
||||
}
|
||||
|
||||
func _internal_getPreparedInlineMessage(account: Account, botId: EnginePeer.Id, id: String) -> Signal<PreparedInlineMessage?, NoError> {
|
||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||
return transaction.getPeer(botId).flatMap(apiInputUser)
|
||||
}
|
||||
|> mapToSignal { inputBot -> Signal<PreparedInlineMessage?, NoError> in
|
||||
guard let inputBot else {
|
||||
return .single(nil)
|
||||
}
|
||||
return account.network.request(Api.functions.messages.getPreparedInlineMessage(bot: inputBot, id: id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.messages.PreparedInlineMessage?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<PreparedInlineMessage?, NoError> in
|
||||
guard let result else {
|
||||
return .single(nil)
|
||||
}
|
||||
return account.postbox.transaction { transaction -> PreparedInlineMessage? in
|
||||
switch result {
|
||||
case let .preparedInlineMessage(queryId, result, peerTypes, users):
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
return PreparedInlineMessage(queryId: queryId, result: ChatContextResult(apiResult: result, queryId: queryId), peerTypes: peerTypes.compactMap { ReplyMarkupButtonAction.PeerTypes(apiType: $0) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -403,6 +403,10 @@ public extension TelegramEngine {
|
||||
public func messageReadStats(id: MessageId) -> Signal<MessageReadStats?, NoError> {
|
||||
return _internal_messageReadStats(account: self.account, id: id)
|
||||
}
|
||||
|
||||
public func getPreparedInlineMessage(botId: EnginePeer.Id, id: String) -> Signal<PreparedInlineMessage?, NoError> {
|
||||
return _internal_getPreparedInlineMessage(account: self.account, botId: botId, id: id)
|
||||
}
|
||||
|
||||
public func requestCancelLiveLocation(ids: [MessageId]) -> Signal<Never, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> Void in
|
||||
@ -590,12 +594,12 @@ public extension TelegramEngine {
|
||||
return _internal_requestSimpleWebView(postbox: self.account.postbox, network: self.account.network, botId: botId, url: url, source: source, themeParams: themeParams)
|
||||
}
|
||||
|
||||
public func requestMainWebView(botId: PeerId, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
return _internal_requestMainWebView(postbox: self.account.postbox, network: self.account.network, botId: botId, source: source, themeParams: themeParams)
|
||||
public func requestMainWebView(peerId: PeerId, botId: PeerId, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
return _internal_requestMainWebView(postbox: self.account.postbox, network: self.account.network, peerId: peerId, botId: botId, source: source, themeParams: themeParams)
|
||||
}
|
||||
|
||||
public func requestAppWebView(peerId: PeerId, appReference: BotAppReference, payload: String?, themeParams: [String: Any]?, compact: Bool, allowWrite: Bool) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
return _internal_requestAppWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, appReference: appReference, payload: payload, themeParams: themeParams, compact: compact, allowWrite: allowWrite)
|
||||
public func requestAppWebView(peerId: PeerId, appReference: BotAppReference, payload: String?, themeParams: [String: Any]?, compact: Bool, fullscreen: Bool, allowWrite: Bool) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
return _internal_requestAppWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, appReference: appReference, payload: payload, themeParams: themeParams, compact: compact, fullscreen: fullscreen, allowWrite: allowWrite)
|
||||
}
|
||||
|
||||
public func sendWebViewData(botId: PeerId, buttonText: String, data: String) -> Signal<Never, SendWebViewDataError> {
|
||||
|
@ -811,6 +811,10 @@ public extension TelegramEngine {
|
||||
return _internal_updateBotAbout(account: self.account, peerId: peerId, about: about)
|
||||
}
|
||||
|
||||
public func toggleBotEmojiStatusAccess(peerId: PeerId, enabled: Bool) -> Signal<Never, ToggleBotEmojiStatusAccessError> {
|
||||
return _internal_toggleBotEmojiStatusAccess(account: self.account, peerId: peerId, enabled: enabled)
|
||||
}
|
||||
|
||||
public func updatePeerNameColorAndEmoji(peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
|
||||
return _internal_updatePeerNameColorAndEmoji(account: self.account, peerId: peerId, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func _internal_updateBotDescription(account: Account, peerId: PeerId, descriptio
|
||||
if let botInfo = current.botInfo {
|
||||
var updatedBotInfo = botInfo
|
||||
if botInfo.description == editableBotInfo.description {
|
||||
updatedBotInfo = BotInfo(description: description, photo: botInfo.photo, video: botInfo.video, commands: botInfo.commands, menuButton: botInfo.menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl)
|
||||
updatedBotInfo = BotInfo(description: description, photo: botInfo.photo, video: botInfo.video, commands: botInfo.commands, menuButton: botInfo.menuButton, privacyPolicyUrl: botInfo.privacyPolicyUrl, appSettings: botInfo.appSettings)
|
||||
}
|
||||
return current.withUpdatedEditableBotInfo(editableBotInfo.withUpdatedDescription(description)).withUpdatedBotInfo(updatedBotInfo)
|
||||
} else {
|
||||
@ -121,3 +121,43 @@ func _internal_updateBotDescription(account: Account, peerId: PeerId, descriptio
|
||||
|> mapError { _ -> UpdateBotInfoError in }
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
public enum ToggleBotEmojiStatusAccessError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_toggleBotEmojiStatusAccess(account: Account, peerId: PeerId, enabled: Bool) -> Signal<Never, ToggleBotEmojiStatusAccessError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, ToggleBotEmojiStatusAccessError> in
|
||||
if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) {
|
||||
return account.network.request(Api.functions.bots.toggleUserEmojiStatusPermission(bot: inputUser, enabled: enabled ? .boolTrue : .boolFalse))
|
||||
|> mapError { _ -> ToggleBotEmojiStatusAccessError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, ToggleBotEmojiStatusAccessError> in
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
if case .boolTrue = result {
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||
if let current = current as? CachedUserData {
|
||||
var updatedFlags: CachedUserFlags = current.flags
|
||||
if enabled {
|
||||
updatedFlags.insert(.botCanManageEmojiStatus)
|
||||
} else {
|
||||
updatedFlags.remove(.botCanManageEmojiStatus)
|
||||
}
|
||||
return current.withUpdatedFlags(updatedFlags)
|
||||
} else {
|
||||
return current
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> ToggleBotEmojiStatusAccessError in }
|
||||
}
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> ToggleBotEmojiStatusAccessError in }
|
||||
|> switchToLatest
|
||||
|> ignoreValues
|
||||
}
|
||||
|
@ -282,6 +282,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
let translationsDisabled = (userFullFlags & (1 << 23)) != 0
|
||||
let adsEnabled = (userFullFlags2 & (1 << 7)) != 0
|
||||
let canViewRevenue = (userFullFlags2 & (1 << 9)) != 0
|
||||
let botCanManageEmojiStatus = (userFullFlags2 & (1 << 10)) != 0
|
||||
|
||||
var flags: CachedUserFlags = previous.flags
|
||||
if premiumRequired {
|
||||
@ -309,6 +310,11 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
} else {
|
||||
flags.remove(.canViewRevenue)
|
||||
}
|
||||
if botCanManageEmojiStatus {
|
||||
flags.insert(.botCanManageEmojiStatus)
|
||||
} else {
|
||||
flags.remove(.botCanManageEmojiStatus)
|
||||
}
|
||||
|
||||
let callsPrivate = (userFullFlags & (1 << 5)) != 0
|
||||
let canPinMessages = (userFullFlags & (1 << 7)) != 0
|
||||
@ -446,7 +452,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
var botInfos: [CachedPeerBotInfo] = []
|
||||
for botInfo in chatFullBotInfo ?? [] {
|
||||
switch botInfo {
|
||||
case let .botInfo(_, userId, _, _, _, _, _, _):
|
||||
case let .botInfo(_, userId, _, _, _, _, _, _, _):
|
||||
if let userId = userId {
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
|
||||
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
|
||||
@ -636,7 +642,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
var botInfos: [CachedPeerBotInfo] = []
|
||||
for botInfo in apiBotInfos {
|
||||
switch botInfo {
|
||||
case let .botInfo(_, userId, _, _, _, _, _, _):
|
||||
case let .botInfo(_, userId, _, _, _, _, _, _, _):
|
||||
if let userId = userId {
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
|
||||
let parsedBotInfo = BotInfo(apiBotInfo: botInfo)
|
||||
|
@ -1381,7 +1381,8 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
context: context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
peer: .user(user),
|
||||
botPeer: .user(user),
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
@ -1545,15 +1546,20 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
if let _ = user.botInfo {
|
||||
//TODO:localize
|
||||
items[.permissions]!.append(PeerInfoScreenHeaderItem(id: 30, text: "ALLOW ACCESS TO"))
|
||||
// items[.permissions]!.append(PeerInfoScreenSwitchItem(id: 31, text: "Emoji Status", value: false, icon: UIImage(bundleImageName: "Chat/Info/Status"), isLocked: false, toggled: { value in
|
||||
//
|
||||
// }))
|
||||
var canManageEmojiStatus = false
|
||||
if let cachedData = data.cachedData as? CachedUserData, cachedData.flags.contains(.botCanManageEmojiStatus) {
|
||||
canManageEmojiStatus = true
|
||||
}
|
||||
items[.permissions]!.append(PeerInfoScreenSwitchItem(id: 31, text: "Emoji Status", value: canManageEmojiStatus, icon: UIImage(bundleImageName: "Chat/Info/Status"), isLocked: false, toggled: { value in
|
||||
let _ = (context.engine.peers.toggleBotEmojiStatusAccess(peerId: user.id, enabled: value)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}))
|
||||
|
||||
if data.webAppPermissions?.location?.isRequested == true {
|
||||
items[.permissions]!.append(PeerInfoScreenSwitchItem(id: 32, text: "Geolocation", value: data.webAppPermissions?.location?.isAllowed ?? false, icon: UIImage(bundleImageName: "Chat/Info/Location"), isLocked: false, toggled: { value in
|
||||
let _ = updateWebAppPermissionsStateInteractively(context: context, peerId: user.id) { current in
|
||||
return WebAppPermissionsState(location: WebAppPermissionsState.Location(isRequested: true, isAllowed: value))
|
||||
}.start()
|
||||
}.startStandalone()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -946,7 +946,7 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
|
||||
if openAppIfAny, case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp), let parentController = self.rootController.viewControllers.last as? ViewController {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true, payload: nil)
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, botPeer: peer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true, payload: nil)
|
||||
} else {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
|
||||
}
|
||||
|
@ -14,7 +14,20 @@ import UndoUI
|
||||
import UrlHandling
|
||||
import TelegramPresentationData
|
||||
|
||||
func openWebAppImpl(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
func openWebAppImpl(
|
||||
context: AccountContext,
|
||||
parentController: ViewController,
|
||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
|
||||
botPeer: EnginePeer,
|
||||
chatPeer: EnginePeer?,
|
||||
threadId: Int64?,
|
||||
buttonText: String,
|
||||
url: String,
|
||||
simple: Bool,
|
||||
source: ChatOpenWebViewSource,
|
||||
skipTermsOfService: Bool,
|
||||
payload: String?
|
||||
) {
|
||||
let presentationData: PresentationData
|
||||
if let parentController = parentController as? ChatControllerImpl {
|
||||
presentationData = parentController.presentationData
|
||||
@ -30,9 +43,9 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
botAddress = bot.addressName ?? ""
|
||||
botVerified = bot.isVerified
|
||||
} else {
|
||||
botName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
botAddress = peer.addressName ?? ""
|
||||
botVerified = peer.isVerified
|
||||
botName = botPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
botAddress = botPeer.addressName ?? ""
|
||||
botVerified = botPeer.isVerified
|
||||
}
|
||||
|
||||
if source == .generic {
|
||||
@ -95,7 +108,7 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
|
||||
if let navigationController = parentController.navigationController as? NavigationController, let minimizedContainer = navigationController.minimizedContainer {
|
||||
for controller in minimizedContainer.controllers {
|
||||
if let controller = controller as? AttachmentController, let mainController = controller.mainController as? WebAppController, mainController.botId == peer.id && mainController.source == .menu {
|
||||
if let controller = controller as? AttachmentController, let mainController = controller.mainController as? WebAppController, mainController.botId == botPeer.id && mainController.source == .menu {
|
||||
navigationController.maximizeViewController(controller, animated: true)
|
||||
return
|
||||
}
|
||||
@ -105,22 +118,22 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
var fullSize = false
|
||||
var isFullscreen = false
|
||||
if isTelegramMeLink(url), let internalUrl = parseFullInternalUrl(sharedContext: context.sharedContext, url: url), case .peer(_, .appStart) = internalUrl {
|
||||
if url.contains("&mode=fullscreen") {
|
||||
if url.contains("mode=fullscreen") {
|
||||
isFullscreen = true
|
||||
fullSize = true
|
||||
} else {
|
||||
fullSize = !url.contains("?mode=compact")
|
||||
fullSize = !url.contains("mode=compact")
|
||||
}
|
||||
}
|
||||
|
||||
var presentImpl: ((ViewController, Any?) -> Void)?
|
||||
let params = WebAppParameters(source: .menu, peerId: peer.id, botId: peer.id, botName: botName, botVerified: botVerified, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: fullSize, isFullscreen: isFullscreen)
|
||||
let params = WebAppParameters(source: .menu, peerId: chatPeer?.id ?? botPeer.id, botId: botPeer.id, botName: botName, botVerified: botVerified, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: fullSize, isFullscreen: isFullscreen)
|
||||
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { [weak parentController] url, concealed, forceUpdate, commit in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: peer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: chatPeer?.id ?? botPeer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
presentImpl?(c, a)
|
||||
}, commit: commit)
|
||||
}, requestSwitchInline: { [weak parentController] query, chatTypes, completion in
|
||||
ChatControllerImpl.botRequestSwitchInline(context: context, controller: parentController as? ChatControllerImpl, peerId: peer.id, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
||||
ChatControllerImpl.botRequestSwitchInline(context: context, controller: parentController as? ChatControllerImpl, peerId: chatPeer?.id ?? botPeer.id, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
||||
}, getInputContainerNode: { [weak parentController] in
|
||||
if let parentController = parentController as? ChatControllerImpl, let layout = parentController.validLayout, case .compact = layout.metrics.widthClass {
|
||||
return (parentController.chatDisplayNode.getWindowInputAccessoryHeight(), parentController.chatDisplayNode.inputPanelContainerNode, {
|
||||
@ -160,10 +173,10 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
}
|
||||
} else if simple {
|
||||
var isInline = false
|
||||
var botId = peer.id
|
||||
var botId = botPeer.id
|
||||
var botName = botName
|
||||
var botAddress = ""
|
||||
var botVerified = peer.isVerified
|
||||
var botVerified = botPeer.isVerified
|
||||
if case let .inline(bot) = source {
|
||||
isInline = true
|
||||
botId = bot.id
|
||||
@ -180,9 +193,14 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
}
|
||||
|
||||
let webViewSignal: Signal<RequestWebViewResult, RequestWebViewError>
|
||||
let webViewSource: RequestSimpleWebViewSource = isInline ? .inline(startParam: payload) : .generic
|
||||
let webViewSource: RequestSimpleWebViewSource
|
||||
if let payload {
|
||||
webViewSource = .inline(startParam: payload)
|
||||
} else {
|
||||
webViewSource = .generic
|
||||
}
|
||||
if url.isEmpty {
|
||||
webViewSignal = context.engine.messages.requestMainWebView(botId: botId, source: webViewSource, themeParams: generateWebAppThemeParams(presentationData.theme))
|
||||
webViewSignal = context.engine.messages.requestMainWebView(peerId: chatPeer?.id ?? botId, botId: botId, source: webViewSource, themeParams: generateWebAppThemeParams(presentationData.theme))
|
||||
} else {
|
||||
webViewSignal = context.engine.messages.requestSimpleWebView(botId: botId, url: url, source: webViewSource, themeParams: generateWebAppThemeParams(presentationData.theme))
|
||||
}
|
||||
@ -202,13 +220,13 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
} else {
|
||||
source = url.isEmpty ? .generic : .simple
|
||||
}
|
||||
let params = WebAppParameters(source: source, peerId: peer.id, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: payload, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen))
|
||||
let params = WebAppParameters(source: source, peerId: chatPeer?.id ?? botId, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: payload, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen))
|
||||
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { [weak parentController] url, concealed, forceUpdate, commit in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: peer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: chatPeer?.id ?? botId, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
presentImpl?(c, a)
|
||||
}, commit: commit)
|
||||
}, requestSwitchInline: { [weak parentController] query, chatTypes, completion in
|
||||
ChatControllerImpl.botRequestSwitchInline(context: context, controller: parentController as? ChatControllerImpl, peerId: peer.id, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
||||
ChatControllerImpl.botRequestSwitchInline(context: context, controller: parentController as? ChatControllerImpl, peerId: chatPeer?.id ?? botId, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
||||
}, getNavigationController: { [weak parentController] in
|
||||
var navigationController: NavigationController?
|
||||
if let parentController = parentController as? ChatControllerImpl {
|
||||
@ -239,7 +257,7 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
messageActionCallbackDisposable = MetaDisposable()
|
||||
}
|
||||
|
||||
messageActionCallbackDisposable.set(((context.engine.messages.requestWebView(peerId: peer.id, botId: peer.id, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: false, replyToMessageId: nil, threadId: threadId)
|
||||
messageActionCallbackDisposable.set(((context.engine.messages.requestWebView(peerId: chatPeer?.id ?? botPeer.id, botId: botPeer.id, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: false, replyToMessageId: nil, threadId: threadId)
|
||||
|> afterDisposed {
|
||||
updateProgress()
|
||||
})
|
||||
@ -248,9 +266,9 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
return
|
||||
}
|
||||
var presentImpl: ((ViewController, Any?) -> Void)?
|
||||
let params = WebAppParameters(source: .button, peerId: peer.id, botId: peer.id, botName: botName, botVerified: botVerified, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, forceHasSettings: false, fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen))
|
||||
let params = WebAppParameters(source: .button, peerId: chatPeer?.id ?? botPeer.id, botId: botPeer.id, botName: botName, botVerified: botVerified, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, forceHasSettings: false, fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen))
|
||||
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { [weak parentController] url, concealed, forceUpdate, commit in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: peer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: chatPeer?.id ?? botPeer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||
presentImpl?(c, a)
|
||||
}, commit: commit)
|
||||
}, completion: { [weak parentController] in
|
||||
@ -285,7 +303,7 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
if skipTermsOfService {
|
||||
openWebView()
|
||||
} else {
|
||||
var botPeer = peer
|
||||
var botPeer = botPeer
|
||||
if case let .inline(bot) = source {
|
||||
botPeer = bot
|
||||
}
|
||||
@ -319,7 +337,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
self.chatDisplayNode.dismissInput()
|
||||
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: EnginePeer(peer), chatPeer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
||||
}
|
||||
|
||||
static func botRequestSwitchInline(context: AccountContext, controller: ChatControllerImpl?, peerId: EnginePeer.Id, botAddress: String, query: String, chatTypes: [ReplyMarkupButtonRequestPeerType]?, completion: @escaping () -> Void) -> Void {
|
||||
@ -413,7 +431,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
func presentBotApp(botApp: BotApp?, botPeer: EnginePeer, payload: String?, compact: Bool, concealed: Bool = false, commit: @escaping () -> Void = {}) {
|
||||
func presentBotApp(botApp: BotApp?, botPeer: EnginePeer, payload: String?, mode: ResolvedStartAppMode, concealed: Bool = false, commit: @escaping () -> Void = {}) {
|
||||
guard let peerId = self.chatLocation.peerId else {
|
||||
return
|
||||
}
|
||||
@ -469,7 +487,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
|
||||
let botAddress = botPeer.addressName ?? ""
|
||||
strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestAppWebView(peerId: peerId, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: payload, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), compact: compact, allowWrite: allowWrite)
|
||||
strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestAppWebView(peerId: peerId, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: payload, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), compact: mode == .compact, fullscreen: mode == .fullscreen, allowWrite: allowWrite)
|
||||
|> afterDisposed {
|
||||
updateProgress()
|
||||
})
|
||||
@ -570,7 +588,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: botPeer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: botPeer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9856,16 +9856,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case let .withBotApp(botAppStart):
|
||||
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId.id))
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
|
||||
if let strongSelf = self, let peer {
|
||||
if let botApp = botAppStart.botApp {
|
||||
strongSelf.presentBotApp(botApp: botApp, botPeer: peer, payload: botAppStart.payload, compact: botAppStart.compact, concealed: concealed, commit: {
|
||||
dismissWebAppControllers()
|
||||
commit()
|
||||
})
|
||||
} else {
|
||||
strongSelf.context.sharedContext.openWebApp(context: strongSelf.context, parentController: strongSelf, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: botAppStart.payload)
|
||||
guard let self, let peer else {
|
||||
return
|
||||
}
|
||||
if let botApp = botAppStart.botApp {
|
||||
self.presentBotApp(botApp: botApp, botPeer: peer, payload: botAppStart.payload, mode: botAppStart.mode, concealed: concealed, commit: {
|
||||
dismissWebAppControllers()
|
||||
commit()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: peer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: botAppStart.payload)
|
||||
commit()
|
||||
}
|
||||
})
|
||||
default:
|
||||
|
@ -668,9 +668,9 @@ func chatHistoryEntriesForView(
|
||||
if reverse {
|
||||
return (entries.reversed(), currentState)
|
||||
} else {
|
||||
#if DEBUG
|
||||
assert(entries.map(\.stableId) == entries.sorted().map(\.stableId))
|
||||
#endif
|
||||
// #if DEBUG
|
||||
// assert(entries.map(\.stableId) == entries.sorted().map(\.stableId))
|
||||
// #endif
|
||||
return (entries, currentState)
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
||||
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||
}
|
||||
if let botAppStart = params.botAppStart, case let .peer(peer) = params.chatLocation {
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, compact: botAppStart.compact)
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, mode: botAppStart.mode)
|
||||
}
|
||||
params.setupController(controller)
|
||||
found = true
|
||||
@ -188,7 +188,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
||||
}
|
||||
if let botAppStart = params.botAppStart, case let .peer(peer) = params.chatLocation {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, compact: botAppStart.compact)
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, mode: botAppStart.mode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -196,7 +196,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
||||
|
||||
if let botAppStart = params.botAppStart, case let .peer(peer) = params.chatLocation {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, compact: botAppStart.compact)
|
||||
controller.presentBotApp(botApp: botAppStart.botApp, botPeer: peer, payload: botAppStart.payload, mode: botAppStart.mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2825,8 +2825,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return MiniAppListScreen(context: context, initialData: initialData as! MiniAppListScreen.InitialData)
|
||||
}
|
||||
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, peer: peer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService, payload: payload)
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, botPeer: botPeer, chatPeer: chatPeer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService, payload: payload)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ public enum UndoOverlayContent {
|
||||
case peers(context: AccountContext, peers: [EnginePeer], title: String?, text: String, customUndoText: String?)
|
||||
case messageTagged(context: AccountContext, isSingleMessage: Bool, customEmoji: TelegramMediaFile, isBuiltinReaction: Bool, customUndoText: String?)
|
||||
case media(context: AccountContext, file: FileMediaReference, title: String?, text: String, undoText: String?, customAction: (() -> Void)?)
|
||||
case progress(progress: CGFloat, title: String, text: String, undoText: String?)
|
||||
}
|
||||
|
||||
public enum UndoOverlayAction {
|
||||
|
@ -1351,6 +1351,45 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
if let updatedImageSignal = updatedImageSignal {
|
||||
stillStickerNode.setSignal(updatedImageSignal)
|
||||
}
|
||||
case let .progress(progress, title, text, customUndoText):
|
||||
self.avatarNode = nil
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode?.displayWithoutProcessing = true
|
||||
self.iconNode?.displaysAsynchronously = false
|
||||
self.iconNode?.image = generateTintedImage(image: UIImage(bundleImageName: "Premium/File"), color: .white)
|
||||
self.iconImageSize = CGSize(width: 14.0, height: 14.0)
|
||||
self.iconCheckNode = nil
|
||||
self.animationNode = nil
|
||||
self.animatedStickerNode = nil
|
||||
|
||||
self.statusNode = RadialStatusNode(backgroundNodeColor: .clear)
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
|
||||
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||
let link = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: undoTextColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { contents in
|
||||
return ("URL", contents)
|
||||
}), textAlignment: .natural)
|
||||
self.textNode.attributedText = attributedText
|
||||
|
||||
|
||||
if text.contains("](") {
|
||||
isUserInteractionEnabled = true
|
||||
}
|
||||
self.originalRemainingSeconds = 5
|
||||
|
||||
self.textNode.maximumNumberOfLines = 5
|
||||
|
||||
if let customUndoText = customUndoText {
|
||||
undoText = customUndoText
|
||||
displayUndo = true
|
||||
} else {
|
||||
displayUndo = false
|
||||
}
|
||||
|
||||
self.statusNode?.transitionToState(.progress(color: .white, lineWidth: nil, value: max(progress, 0.027), cancelEnabled: false, animateRotation: true), completion: {})
|
||||
}
|
||||
|
||||
self.remainingSeconds = self.originalRemainingSeconds
|
||||
@ -1394,7 +1433,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
} else {
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
case .sticker, .customEmoji, .media:
|
||||
case .sticker, .customEmoji, .media, .progress:
|
||||
self.isUserInteractionEnabled = displayUndo
|
||||
case .dice:
|
||||
self.panelWrapperNode.clipsToBounds = true
|
||||
@ -1431,6 +1470,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.slotMachineNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.avatarNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
self.multiAvatarsNode.flatMap(self.panelWrapperNode.addSubnode)
|
||||
|
||||
self.panelWrapperNode.addSubnode(self.buttonNode)
|
||||
self.panelWrapperNode.addSubnode(self.titleNode)
|
||||
self.panelWrapperNode.addSubnode(self.textNode)
|
||||
@ -1629,6 +1669,15 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
|
||||
self.renewWithCurrentContent()
|
||||
transition = .animated(duration: 0.1, curve: .easeInOut)
|
||||
case let .progress(progress, title, text, _):
|
||||
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||
let link = MarkdownAttributeSet(font: Font.regular(14.0), textColor: undoTextColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
|
||||
self.textNode.attributedText = attributedText
|
||||
|
||||
self.statusNode?.transitionToState(.progress(color: .white, lineWidth: nil, value: max(progress, 0.027), cancelEnabled: false, animateRotation: true), completion: {})
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1667,7 +1716,10 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
|
||||
var leftInset: CGFloat = 50.0
|
||||
if let iconImageSize = self.iconImageSize {
|
||||
leftInset = 9.0 + iconImageSize.width + 9.0
|
||||
if case .progress = self.content {
|
||||
} else {
|
||||
leftInset = 9.0 + iconImageSize.width + 9.0
|
||||
}
|
||||
} else if let iconSize = preferredSize {
|
||||
if iconSize.width > leftInset {
|
||||
leftInset = iconSize.width - 8.0
|
||||
@ -1802,8 +1854,13 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
iconSize = CGSize()
|
||||
}
|
||||
|
||||
var isProgress = false
|
||||
if case .progress = self.content {
|
||||
isProgress = true
|
||||
}
|
||||
|
||||
let iconFrame: CGRect
|
||||
if self.iconImageSize != nil {
|
||||
if self.iconImageSize != nil && !isProgress {
|
||||
iconFrame = CGRect(origin: CGPoint(x: 9.0, y: floor((contentHeight - iconSize.height) / 2.0) + verticalOffset), size: iconSize)
|
||||
} else {
|
||||
iconFrame = CGRect(origin: CGPoint(x: floor((leftInset - iconSize.width) / 2.0), y: floor((contentHeight - iconSize.height) / 2.0) + verticalOffset), size: iconSize)
|
||||
@ -1885,13 +1942,17 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
transition.updateFrame(node: statusNode, frame: statusFrame)
|
||||
if !self.didStartStatusNode {
|
||||
let statusColor: UIColor
|
||||
if case .starsSent = self.content {
|
||||
statusColor = self.undoTextColor
|
||||
if case .progress = self.content {
|
||||
|
||||
} else {
|
||||
statusColor = .white
|
||||
let statusColor: UIColor
|
||||
if case .starsSent = self.content {
|
||||
statusColor = self.undoTextColor
|
||||
} else {
|
||||
statusColor = .white
|
||||
}
|
||||
statusNode.transitionToState(.secretTimeout(color: statusColor, icon: .none, beginTime: CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, timeout: Double(self.remainingSeconds), sparks: false), completion: {})
|
||||
}
|
||||
statusNode.transitionToState(.secretTimeout(color: statusColor, icon: .none, beginTime: CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970, timeout: Double(self.remainingSeconds), sparks: false), completion: {})
|
||||
self.didStartStatusNode = true
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public enum ParsedInternalPeerUrlParameter {
|
||||
case channelMessage(Int32, Double?)
|
||||
case replyThread(Int32, Int32)
|
||||
case voiceChat(String?)
|
||||
case appStart(String, String?, Bool)
|
||||
case appStart(String, String?, ResolvedStartAppMode)
|
||||
case story(Int32)
|
||||
case boost
|
||||
case text(String)
|
||||
@ -293,18 +293,25 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
|
||||
}
|
||||
return .startAttach(peerName, value, choose)
|
||||
} else if queryItem.name == "startapp" {
|
||||
var compact = false
|
||||
var mode: ResolvedStartAppMode = .generic
|
||||
if let queryItems = components.queryItems {
|
||||
for queryItem in queryItems {
|
||||
if let value = queryItem.value {
|
||||
if queryItem.name == "mode", value == "compact" {
|
||||
compact = true
|
||||
if queryItem.name == "mode" {
|
||||
switch value {
|
||||
case "compact":
|
||||
mode = .compact
|
||||
case "fullscreen":
|
||||
mode = .fullscreen
|
||||
default:
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return .peer(.name(peerName), .appStart("", queryItem.value, compact))
|
||||
return .peer(.name(peerName), .appStart("", queryItem.value, mode))
|
||||
} else if queryItem.name == "story" {
|
||||
if let id = Int32(value) {
|
||||
return .peer(.name(peerName), .story(id))
|
||||
@ -335,18 +342,25 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
|
||||
} else if queryItem.name == "profile" {
|
||||
return .peer(.name(peerName), .profile)
|
||||
} else if queryItem.name == "startapp" {
|
||||
var compact = false
|
||||
var mode: ResolvedStartAppMode = .generic
|
||||
if let queryItems = components.queryItems {
|
||||
for queryItem in queryItems {
|
||||
if let value = queryItem.value {
|
||||
if queryItem.name == "mode", value == "compact" {
|
||||
compact = true
|
||||
if queryItem.name == "mode" {
|
||||
switch value {
|
||||
case "compact":
|
||||
mode = .compact
|
||||
case "fullscreen":
|
||||
mode = .fullscreen
|
||||
default:
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return .peer(.name(peerName), .appStart("", nil, compact))
|
||||
return .peer(.name(peerName), .appStart("", queryItem.value, mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -615,19 +629,28 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
|
||||
} else if pathComponents.count == 2 {
|
||||
let appName = pathComponents[1]
|
||||
var startApp: String?
|
||||
var compact = false
|
||||
var mode: ResolvedStartAppMode = .generic
|
||||
if let queryItems = components.queryItems {
|
||||
for queryItem in queryItems {
|
||||
if let value = queryItem.value {
|
||||
if queryItem.name == "startapp" {
|
||||
startApp = value
|
||||
} else if queryItem.name == "mode", value == "compact" {
|
||||
compact = true
|
||||
}
|
||||
if queryItem.name == "mode" {
|
||||
switch value {
|
||||
case "compact":
|
||||
mode = .compact
|
||||
case "fullscreen":
|
||||
mode = .fullscreen
|
||||
default:
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return .peer(.name(peerName), .appStart(appName, startApp, compact))
|
||||
return .peer(.name(peerName), .appStart(appName, startApp, mode))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@ -745,10 +768,10 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .appStart(name, payload, compact):
|
||||
case let .appStart(name, payload, mode):
|
||||
if name.isEmpty {
|
||||
if case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp) {
|
||||
return .single(.result(.peer(peer._asPeer(), .withBotApp(ChatControllerInitialBotAppStart(botApp: nil, payload: payload, justInstalled: false, compact: compact)))))
|
||||
return .single(.result(.peer(peer._asPeer(), .withBotApp(ChatControllerInitialBotAppStart(botApp: nil, payload: payload, justInstalled: false, mode: mode)))))
|
||||
} else {
|
||||
return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))))
|
||||
}
|
||||
@ -760,7 +783,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
||||
}
|
||||
|> mapToSignal { botApp -> Signal<ResolveInternalUrlResult, NoError> in
|
||||
if let botApp {
|
||||
return .single(.result(.peer(peer._asPeer(), .withBotApp(ChatControllerInitialBotAppStart(botApp: botApp, payload: payload, justInstalled: false, compact: compact)))))
|
||||
return .single(.result(.peer(peer._asPeer(), .withBotApp(ChatControllerInitialBotAppStart(botApp: botApp, payload: payload, justInstalled: false, mode: mode)))))
|
||||
} else {
|
||||
return .single(.result(.peer(peer._asPeer(), .chat(textInputState: nil, subject: nil, peekData: nil))))
|
||||
}
|
||||
|
75
submodules/WebUI/Sources/FileDownload.swift
Normal file
75
submodules/WebUI/Sources/FileDownload.swift
Normal file
@ -0,0 +1,75 @@
|
||||
import Foundation
|
||||
import SwiftSignalKit
|
||||
|
||||
final class FileDownload: NSObject, URLSessionDownloadDelegate {
|
||||
private let fileSize: Int64?
|
||||
private var urlSession: URLSession!
|
||||
private var completion: ((URL?, Error?) -> Void)?
|
||||
private var progressHandler: ((Double) -> Void)?
|
||||
|
||||
init(from url: URL, fileSize: Int64?, progressHandler: @escaping (Double) -> Void, completion: @escaping (URL?, Error?) -> Void) {
|
||||
self.progressHandler = progressHandler
|
||||
self.fileSize = fileSize
|
||||
self.completion = completion
|
||||
|
||||
|
||||
super.init()
|
||||
|
||||
let configuration = URLSessionConfiguration.default
|
||||
urlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
|
||||
|
||||
let downloadTask = self.urlSession.downloadTask(with: url)
|
||||
downloadTask.resume()
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
|
||||
var totalBytesExpectedToWrite = totalBytesExpectedToWrite
|
||||
if totalBytesExpectedToWrite == -1, let fileSize = self.fileSize {
|
||||
totalBytesExpectedToWrite = fileSize
|
||||
}
|
||||
let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
|
||||
progressHandler?(progress)
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
|
||||
completion?(location, nil)
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
||||
if let error = error {
|
||||
completion?(nil, error)
|
||||
}
|
||||
}
|
||||
|
||||
static func getFileSize(url: String) -> Signal<Int64?, NoError> {
|
||||
if #available(iOS 13.0, *) {
|
||||
guard let url = URL(string: url) else {
|
||||
return .single(nil)
|
||||
}
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "HEAD"
|
||||
|
||||
return Signal { subscriber in
|
||||
let task = URLSession.shared.dataTask(with: request) { _, response, error in
|
||||
if let _ = error {
|
||||
subscriber.putNext(nil)
|
||||
subscriber.putCompletion()
|
||||
return
|
||||
}
|
||||
var fileSize: Int64?
|
||||
if let httpResponse = response as? HTTPURLResponse, let contentLength = httpResponse.value(forHTTPHeaderField: "Content-Length"), let size = Int64(contentLength) {
|
||||
fileSize = size
|
||||
}
|
||||
subscriber.putNext(fileSize)
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
task.resume()
|
||||
return ActionDisposable {
|
||||
task.cancel()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
@ -400,7 +400,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
controller.dismiss()
|
||||
return
|
||||
}
|
||||
let _ = (self.context.engine.messages.requestAppWebView(peerId: peer.id, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: appStart.payload, themeParams: generateWebAppThemeParams(self.presentationData.theme), compact: appStart.compact, allowWrite: true)
|
||||
let _ = (self.context.engine.messages.requestAppWebView(peerId: peer.id, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: appStart.payload, themeParams: generateWebAppThemeParams(self.presentationData.theme), compact: appStart.mode == .compact, fullscreen: appStart.mode == .fullscreen, allowWrite: true)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] result in
|
||||
guard let self, let parsedUrl = URL(string: result.url) else {
|
||||
return
|
||||
@ -626,6 +626,69 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
transition.updateFrame(node: self.headerBackgroundNode, frame: CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: navigationBarHeight)))
|
||||
transition.updateFrame(node: self.topOverscrollNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -1000.0), size: CGSize(width: layout.size.width, height: 1000.0)))
|
||||
|
||||
|
||||
var contentTopInset: CGFloat = 0.0
|
||||
if controller.isFullscreen {
|
||||
var added = false
|
||||
let fullscreenControls: ComponentView<Empty>
|
||||
if let current = self.fullscreenControls {
|
||||
fullscreenControls = current
|
||||
} else {
|
||||
fullscreenControls = ComponentView<Empty>()
|
||||
self.fullscreenControls = fullscreenControls
|
||||
added = true
|
||||
}
|
||||
let controlsMargin: CGFloat = 8.0
|
||||
let componentTransition: ComponentTransition = added ? .immediate : ComponentTransition(transition)
|
||||
let controlsSize = fullscreenControls.update(
|
||||
transition: componentTransition,
|
||||
component: AnyComponent(
|
||||
FullscreenControlsComponent(
|
||||
context: self.context,
|
||||
title: controller.botName,
|
||||
isVerified: controller.botVerified,
|
||||
insets: UIEdgeInsets(top: 0.0, left: layout.safeInsets.left, bottom: 0.0, right: layout.safeInsets.right),
|
||||
hasBack: self.hasBackButton,
|
||||
backPressed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.cancelPressed()
|
||||
},
|
||||
minimizePressed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.requestMinimize(topEdgeOffset: nil, initialVelocity: nil)
|
||||
},
|
||||
morePressed: { [weak self] node, gesture in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.morePressed(node: node, gesture: gesture)
|
||||
}
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: layout.size
|
||||
)
|
||||
if let view = fullscreenControls.view {
|
||||
if view.superview == nil {
|
||||
self.view.addSubview(view)
|
||||
}
|
||||
transition.updateFrame(view: view, frame: CGRect(origin: CGPoint(x: 0.0, y: (layout.statusBarHeight ?? 0.0) + controlsMargin), size: controlsSize))
|
||||
if added {
|
||||
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
}
|
||||
}
|
||||
contentTopInset = controlsSize.height + controlsMargin * 2.0
|
||||
} else if let fullscreenControls = self.fullscreenControls {
|
||||
self.fullscreenControls = nil
|
||||
fullscreenControls.view?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
fullscreenControls.view?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
if let webView = self.webView {
|
||||
var scrollInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0)
|
||||
var frameBottomInset: CGFloat = 0.0
|
||||
@ -683,6 +746,10 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
|
||||
if let controller = self.controller {
|
||||
webView.updateMetrics(height: viewportFrame.height, isExpanded: controller.isContainerExpanded(), isStable: !controller.isContainerPanning(), transition: transition)
|
||||
|
||||
let contentInsetsData = "{top:\(contentTopInset), bottom:0.0, left:0.0, right:0.0}"
|
||||
webView.sendEvent(name: "content_safe_area_changed", data: contentInsetsData)
|
||||
|
||||
if self.updateWebViewWhenStable && !controller.isContainerPanning() {
|
||||
self.updateWebViewWhenStable = false
|
||||
webView.setNeedsLayout()
|
||||
@ -710,66 +777,6 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
placeholderNode.updateAbsoluteRect(placeholderFrame, within: layout.size)
|
||||
}
|
||||
|
||||
if controller.isFullscreen {
|
||||
var added = false
|
||||
let fullscreenControls: ComponentView<Empty>
|
||||
if let current = self.fullscreenControls {
|
||||
fullscreenControls = current
|
||||
} else {
|
||||
fullscreenControls = ComponentView<Empty>()
|
||||
self.fullscreenControls = fullscreenControls
|
||||
added = true
|
||||
}
|
||||
|
||||
let componentTransition: ComponentTransition = added ? .immediate : ComponentTransition(transition)
|
||||
let controlsSize = fullscreenControls.update(
|
||||
transition: componentTransition,
|
||||
component: AnyComponent(
|
||||
FullscreenControlsComponent(
|
||||
context: self.context,
|
||||
title: controller.botName,
|
||||
isVerified: controller.botVerified,
|
||||
insets: UIEdgeInsets(top: 0.0, left: layout.safeInsets.left, bottom: 0.0, right: layout.safeInsets.right),
|
||||
hasBack: self.hasBackButton,
|
||||
backPressed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.cancelPressed()
|
||||
},
|
||||
minimizePressed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.requestMinimize(topEdgeOffset: nil, initialVelocity: nil)
|
||||
},
|
||||
morePressed: { [weak self] node, gesture in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.controller?.morePressed(node: node, gesture: gesture)
|
||||
}
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: layout.size
|
||||
)
|
||||
if let view = fullscreenControls.view {
|
||||
if view.superview == nil {
|
||||
self.view.addSubview(view)
|
||||
}
|
||||
transition.updateFrame(view: view, frame: CGRect(origin: CGPoint(x: 0.0, y: (layout.statusBarHeight ?? 0.0) + 8.0), size: controlsSize))
|
||||
if added {
|
||||
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
}
|
||||
}
|
||||
} else if let fullscreenControls = self.fullscreenControls {
|
||||
self.fullscreenControls = nil
|
||||
fullscreenControls.view?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
fullscreenControls.view?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
if let previousLayout = previousLayout, (previousLayout.inputHeight ?? 0.0).isZero, let inputHeight = layout.inputHeight, inputHeight > 44.0 {
|
||||
Queue.mainQueue().justDispatch {
|
||||
self.controller?.requestAttachmentMenuExpansion()
|
||||
@ -891,6 +898,8 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
self.requestLayout(transition: .immediate)
|
||||
case "web_app_request_safe_area":
|
||||
self.requestLayout(transition: .immediate)
|
||||
case "web_app_request_content_safe_area":
|
||||
self.requestLayout(transition: .immediate)
|
||||
case "web_app_request_theme":
|
||||
self.sendThemeChangedEvent()
|
||||
case "web_app_expand":
|
||||
@ -1370,13 +1379,24 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
case "web_app_add_to_home_screen":
|
||||
self.addToHomeScreen()
|
||||
case "web_app_check_home_screen":
|
||||
self.webView?.sendEvent(name: "home_screen_checked", data: "{status: \"unknown\"}")
|
||||
let data: JSON = ["status": "unknown"]
|
||||
self.webView?.sendEvent(name: "home_screen_checked", data: data.string)
|
||||
case "web_app_request_location":
|
||||
self.requestLocation()
|
||||
case "web_app_check_location":
|
||||
self.checkLocation()
|
||||
case "web_app_open_location_settings":
|
||||
break
|
||||
case "web_app_send_prepared_message":
|
||||
if let json = json, let id = json["id"] as? String {
|
||||
self.sendPreparedMessage(id: id)
|
||||
}
|
||||
case "web_app_request_emoji_status_access":
|
||||
self.requestEmojiStatusAccess()
|
||||
case "web_app_request_file_download":
|
||||
if let json = json, let url = json["url"] as? String, let fileName = json["file_name"] as? String {
|
||||
self.downloadFile(url: url, fileName: fileName)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1612,13 +1632,6 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
}
|
||||
|
||||
fileprivate func shareAccountContact() {
|
||||
if "".isEmpty, let controller = self.controller {
|
||||
let previewController = WebAppMessagePreviewScreen(context: controller.context, completion: { _ in })
|
||||
previewController.navigationPresentation = .flatModal
|
||||
controller.parentController()?.push(previewController)
|
||||
return
|
||||
}
|
||||
|
||||
guard let context = self.controller?.context, let botId = self.controller?.botId, let botName = self.controller?.botName else {
|
||||
return
|
||||
}
|
||||
@ -2120,68 +2133,147 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func setEmojiStatus(_ fileId: Int64, expirationDate: Int32? = nil) {
|
||||
fileprivate func sendPreparedMessage(id: String) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
|
||||
let botName = controller.botName
|
||||
if let _ = expirationDate {
|
||||
let _ = combineLatest(
|
||||
queue: Queue.mainQueue(),
|
||||
self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId]),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: controller.botId))
|
||||
).start(next: { [weak self] files, accountPeer, botPeer in
|
||||
guard let self, let accountPeer, let controller = self.controller else {
|
||||
let _ = (self.context.engine.messages.getPreparedInlineMessage(botId: controller.botId, id: id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak controller] preparedMessage in
|
||||
guard let self, let controller, let preparedMessage else {
|
||||
self?.webView?.sendEvent(name: "prepared_message_failed", data: "{error: \"MESSAGE_EXPIRED\"}")
|
||||
return
|
||||
}
|
||||
let previewController = WebAppMessagePreviewScreen(context: controller.context, botName: controller.botName, preparedMessage: preparedMessage, completion: { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
guard let file = files[fileId] else {
|
||||
self.webView?.sendEvent(name: "emoji_status_failed", data: "{error: \"SUGGESTED_EMOJI_INVALID\"}")
|
||||
return
|
||||
if result {
|
||||
self.webView?.sendEvent(name: "prepared_message_sent", data: nil)
|
||||
} else {
|
||||
self.webView?.sendEvent(name: "prepared_message_failed", data: "{error: \"USER_DECLINED\"}")
|
||||
}
|
||||
let confirmController = WebAppSetEmojiStatusScreen(
|
||||
context: self.context,
|
||||
botName: controller.botName,
|
||||
accountPeer: accountPeer,
|
||||
file: file,
|
||||
completion: { [weak self, weak controller] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if result {
|
||||
let _ = (self.context.engine.accountData.setEmojiStatus(file: file, expirationDate: expirationDate)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
self?.webView?.sendEvent(name: "emoji_status_set", data: nil)
|
||||
})
|
||||
//TODO:localize
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: self.presentationData,
|
||||
content: .sticker(context: context, file: file, loop: false, title: nil, text: "Your emoji status updated.", undoText: nil, customAction: nil),
|
||||
elevatedLayout: true,
|
||||
action: { action in
|
||||
if case .undo = action {
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
)
|
||||
controller?.present(resultController, in: .window(.root))
|
||||
} else {
|
||||
self.webView?.sendEvent(name: "emoji_status_failed", data: "{error: \"USER_DECLINED\"}")
|
||||
}
|
||||
}
|
||||
)
|
||||
controller.parentController()?.push(confirmController)
|
||||
})
|
||||
|
||||
|
||||
previewController.navigationPresentation = .flatModal
|
||||
controller.parentController()?.push(previewController)
|
||||
})
|
||||
}
|
||||
|
||||
fileprivate func downloadFile(url: String, fileName: String) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
var title: String?
|
||||
let photoExtensions = [".jpg", ".png", ".gif", ".tiff"]
|
||||
let videoExtensions = [".mp4", ".mov"]
|
||||
let lowercasedFilename = fileName.lowercased()
|
||||
for ext in photoExtensions {
|
||||
if lowercasedFilename.hasSuffix(ext) {
|
||||
title = "Download Photo"
|
||||
break
|
||||
}
|
||||
}
|
||||
if title == nil {
|
||||
for ext in videoExtensions {
|
||||
if lowercasedFilename.hasSuffix(ext) {
|
||||
title = "Download Video"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if title == nil {
|
||||
title = "Download Document"
|
||||
}
|
||||
|
||||
let _ = (FileDownload.getFileSize(url: url)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] fileSize in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
var fileSizeString = ""
|
||||
if let fileSize {
|
||||
fileSizeString = " (\(dataSizeString(fileSize, formatting: DataSizeStringFormatting(presentationData: self.presentationData))))"
|
||||
}
|
||||
|
||||
let text: String = "**\(controller.botName)** suggests you to download **\(fileName)**\(fileSizeString)."
|
||||
let alertController = standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: title, text: text, actions: [
|
||||
TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_Cancel, action: { [weak self] in
|
||||
self?.webView?.sendEvent(name: "file_download_requested", data: "{status: \"cancelled\"}")
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: "Download", action: { [weak self] in
|
||||
self?.startDownload(url: url, fileName: fileName, fileSize: fileSize)
|
||||
})
|
||||
], parseMarkdown: true)
|
||||
controller.present(alertController, in: .window(.root))
|
||||
})
|
||||
}
|
||||
|
||||
private var fileDownload: FileDownload?
|
||||
private weak var fileDownloadTooltip: UndoOverlayController?
|
||||
fileprivate func startDownload(url: String, fileName: String, fileSize: Int64?) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
self.webView?.sendEvent(name: "file_download_requested", data: "{status: \"downloading\"}")
|
||||
|
||||
self.fileDownload = FileDownload(
|
||||
from: URL(string: url)!,
|
||||
fileSize: fileSize,
|
||||
progressHandler: { [weak self] progress in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let text: String
|
||||
if let fileSize {
|
||||
let downloadedSize = Int64(Double(fileSize) * progress)
|
||||
text = "\(dataSizeString(downloadedSize, formatting: DataSizeStringFormatting(presentationData: self.presentationData))) / \(dataSizeString(fileSize, formatting: DataSizeStringFormatting(presentationData: self.presentationData)))"
|
||||
} else {
|
||||
text = "\(Int32(progress))%"
|
||||
}
|
||||
|
||||
self.fileDownloadTooltip?.content = .progress(
|
||||
progress: progress,
|
||||
title: fileName,
|
||||
text: text,
|
||||
undoText: "Cancel"
|
||||
)
|
||||
},
|
||||
completion: { resultUrl, _ in
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
let text: String
|
||||
if let fileSize {
|
||||
text = "0 KB / \(dataSizeString(fileSize, formatting: DataSizeStringFormatting(presentationData: self.presentationData)))"
|
||||
} else {
|
||||
text = "0%"
|
||||
}
|
||||
|
||||
let tooltipController = UndoOverlayController(
|
||||
presentationData: self.presentationData,
|
||||
content: .progress(
|
||||
progress: 0.0,
|
||||
title: fileName,
|
||||
text: text,
|
||||
undoText: "Cancel"
|
||||
),
|
||||
elevatedLayout: false,
|
||||
position: .top,
|
||||
action: { _ in
|
||||
return true
|
||||
}
|
||||
)
|
||||
controller.present(tooltipController, in: .window(.root))
|
||||
self.fileDownloadTooltip = tooltipController
|
||||
}
|
||||
|
||||
fileprivate func requestEmojiStatusAccess() {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
let _ = combineLatest(
|
||||
queue: Queue.mainQueue(),
|
||||
self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId]),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: controller.botId)),
|
||||
self.context.engine.stickers.loadedStickerPack(reference: .iconStatusEmoji, forceActualized: false)
|
||||
@ -2194,7 +2286,62 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
}
|
||||
}
|
||||
|> take(1)
|
||||
).start(next: { [weak self] files, accountPeer, botPeer, iconStatusEmoji in
|
||||
).start(next: { [weak self] accountPeer, botPeer, iconStatusEmoji in
|
||||
guard let self, let accountPeer, let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
let alertController = webAppEmojiStatusAlertController(
|
||||
context: self.context,
|
||||
accountPeer: accountPeer,
|
||||
botName: controller.botName,
|
||||
icons: iconStatusEmoji,
|
||||
completion: { [weak self] result in
|
||||
guard let self, let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
if result {
|
||||
let context = self.context
|
||||
let botId = controller.botId
|
||||
let _ = (context.engine.peers.toggleBotEmojiStatusAccess(peerId: botId, enabled: true)
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
self?.webView?.sendEvent(name: "emoji_status_access_requested", data: "{status: \"allowed\"}")
|
||||
})
|
||||
|
||||
//TODO:localize
|
||||
if let botPeer {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .invitedToVoiceChat(context: self.context, peer: botPeer, title: nil, text: "**\(controller.botName)** can now set your emoji status anytime.", action: "Undo", duration: 5.0),
|
||||
elevatedLayout: true,
|
||||
action: { action in
|
||||
if case .undo = action {
|
||||
let _ = (context.engine.peers.toggleBotEmojiStatusAccess(peerId: botId, enabled: false)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}
|
||||
return true
|
||||
}
|
||||
)
|
||||
controller.present(resultController, in: .window(.root))
|
||||
}
|
||||
} else {
|
||||
self.webView?.sendEvent(name: "emoji_status_access_requested", data: "{status: \"cancelled\"}")
|
||||
}
|
||||
}
|
||||
)
|
||||
controller.present(alertController, in: .window(.root))
|
||||
})
|
||||
}
|
||||
|
||||
fileprivate func setEmojiStatus(_ fileId: Int64, expirationDate: Int32? = nil) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
let _ = combineLatest(
|
||||
queue: Queue.mainQueue(),
|
||||
self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId]),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)),
|
||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: controller.botId))
|
||||
).start(next: { [weak self] files, accountPeer, botPeer in
|
||||
guard let self, let accountPeer, let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
@ -2202,12 +2349,11 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
self.webView?.sendEvent(name: "emoji_status_failed", data: "{error: \"SUGGESTED_EMOJI_INVALID\"}")
|
||||
return
|
||||
}
|
||||
let alertController = webAppEmojiStatusAlertController(
|
||||
let confirmController = WebAppSetEmojiStatusScreen(
|
||||
context: self.context,
|
||||
botName: controller.botName,
|
||||
accountPeer: accountPeer,
|
||||
botName: botName,
|
||||
icons: iconStatusEmoji,
|
||||
expirationDate: expirationDate,
|
||||
file: file,
|
||||
completion: { [weak self, weak controller] result in
|
||||
guard let self else {
|
||||
return
|
||||
@ -2218,26 +2364,24 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
self?.webView?.sendEvent(name: "emoji_status_set", data: nil)
|
||||
})
|
||||
//TODO:localize
|
||||
if let botPeer {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .invitedToVoiceChat(context: context, peer: botPeer, title: nil, text: "**\(botName)** can now set your emoji status anytime.", action: "Undo", duration: 5.0),
|
||||
elevatedLayout: true,
|
||||
action: { action in
|
||||
if case .undo = action {
|
||||
|
||||
}
|
||||
return true
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: self.presentationData,
|
||||
content: .sticker(context: context, file: file, loop: false, title: nil, text: "Your emoji status updated.", undoText: nil, customAction: nil),
|
||||
elevatedLayout: true,
|
||||
action: { action in
|
||||
if case .undo = action {
|
||||
|
||||
}
|
||||
)
|
||||
controller?.present(resultController, in: .window(.root))
|
||||
}
|
||||
return true
|
||||
}
|
||||
)
|
||||
controller?.present(resultController, in: .window(.root))
|
||||
} else {
|
||||
self.webView?.sendEvent(name: "emoji_status_failed", data: "{error: \"USER_DECLINED\"}")
|
||||
}
|
||||
}
|
||||
)
|
||||
controller.present(alertController, in: .window(.root))
|
||||
controller.parentController()?.push(confirmController)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,6 @@ func webAppEmojiStatusAlertController(
|
||||
accountPeer: EnginePeer,
|
||||
botName: String,
|
||||
icons: [TelegramMediaFile],
|
||||
expirationDate: Int32?,
|
||||
completion: @escaping (Bool) -> Void
|
||||
) -> AlertController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
@ -26,13 +26,19 @@ private final class SheetContent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
let context: AccountContext
|
||||
let botName: String
|
||||
let preparedMessage: PreparedInlineMessage
|
||||
let dismiss: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
botName: String,
|
||||
preparedMessage: PreparedInlineMessage,
|
||||
dismiss: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.botName = botName
|
||||
self.preparedMessage = preparedMessage
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
@ -225,11 +231,17 @@ private final class WebAppMessagePreviewSheetComponent: CombinedComponent {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
||||
private let context: AccountContext
|
||||
private let botName: String
|
||||
private let preparedMessage: PreparedInlineMessage
|
||||
|
||||
init(
|
||||
context: AccountContext
|
||||
context: AccountContext,
|
||||
botName: String,
|
||||
preparedMessage: PreparedInlineMessage
|
||||
) {
|
||||
self.context = context
|
||||
self.botName = botName
|
||||
self.preparedMessage = preparedMessage
|
||||
}
|
||||
|
||||
static func ==(lhs: WebAppMessagePreviewSheetComponent, rhs: WebAppMessagePreviewSheetComponent) -> Bool {
|
||||
@ -252,6 +264,8 @@ private final class WebAppMessagePreviewSheetComponent: CombinedComponent {
|
||||
component: SheetComponent<EnvironmentType>(
|
||||
content: AnyComponent<EnvironmentType>(SheetContent(
|
||||
context: context.component.context,
|
||||
botName: context.component.botName,
|
||||
preparedMessage: context.component.preparedMessage,
|
||||
dismiss: {
|
||||
animateOut.invoke(Action { _ in
|
||||
if let controller = controller() {
|
||||
@ -307,6 +321,8 @@ public final class WebAppMessagePreviewScreen: ViewControllerComponentContainer
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
botName: String,
|
||||
preparedMessage: PreparedInlineMessage,
|
||||
completion: @escaping (Bool) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
@ -315,7 +331,9 @@ public final class WebAppMessagePreviewScreen: ViewControllerComponentContainer
|
||||
super.init(
|
||||
context: context,
|
||||
component: WebAppMessagePreviewSheetComponent(
|
||||
context: context
|
||||
context: context,
|
||||
botName: botName,
|
||||
preparedMessage: preparedMessage
|
||||
),
|
||||
navigationBarAppearance: .none,
|
||||
statusBarStyle: .ignore,
|
||||
|
Loading…
x
Reference in New Issue
Block a user