mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 02:45:58 +00:00
Update API
This commit is contained in:
parent
751f4801d6
commit
f468cea13c
@ -303,6 +303,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-29248689] = { return Api.GlobalPrivacySettings.parse_globalPrivacySettings($0) }
|
dict[-29248689] = { return Api.GlobalPrivacySettings.parse_globalPrivacySettings($0) }
|
||||||
dict[1429932961] = { return Api.GroupCall.parse_groupCall($0) }
|
dict[1429932961] = { return Api.GroupCall.parse_groupCall($0) }
|
||||||
dict[2004925620] = { return Api.GroupCall.parse_groupCallDiscarded($0) }
|
dict[2004925620] = { return Api.GroupCall.parse_groupCallDiscarded($0) }
|
||||||
|
dict[-2018173984] = { return Api.GroupCallMessage.parse_groupCallMessage($0) }
|
||||||
dict[708691884] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) }
|
dict[708691884] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) }
|
||||||
dict[1735736008] = { return Api.GroupCallParticipantVideo.parse_groupCallParticipantVideo($0) }
|
dict[1735736008] = { return Api.GroupCallParticipantVideo.parse_groupCallParticipantVideo($0) }
|
||||||
dict[-592373577] = { return Api.GroupCallParticipantVideoSourceGroup.parse_groupCallParticipantVideoSourceGroup($0) }
|
dict[-592373577] = { return Api.GroupCallParticipantVideoSourceGroup.parse_groupCallParticipantVideoSourceGroup($0) }
|
||||||
@ -1112,7 +1113,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1535694705] = { return Api.Update.parse_updateGroupCallChainBlocks($0) }
|
dict[-1535694705] = { return Api.Update.parse_updateGroupCallChainBlocks($0) }
|
||||||
dict[192428418] = { return Api.Update.parse_updateGroupCallConnection($0) }
|
dict[192428418] = { return Api.Update.parse_updateGroupCallConnection($0) }
|
||||||
dict[-917002394] = { return Api.Update.parse_updateGroupCallEncryptedMessage($0) }
|
dict[-917002394] = { return Api.Update.parse_updateGroupCallEncryptedMessage($0) }
|
||||||
dict[-964095818] = { return Api.Update.parse_updateGroupCallMessage($0) }
|
dict[-667783411] = { return Api.Update.parse_updateGroupCallMessage($0) }
|
||||||
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
|
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
|
||||||
dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) }
|
dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) }
|
||||||
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }
|
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }
|
||||||
@ -1816,6 +1817,8 @@ public extension Api {
|
|||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.GroupCall:
|
case let _1 as Api.GroupCall:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
|
case let _1 as Api.GroupCallMessage:
|
||||||
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.GroupCallParticipant:
|
case let _1 as Api.GroupCallParticipant:
|
||||||
_1.serialize(buffer, boxed)
|
_1.serialize(buffer, boxed)
|
||||||
case let _1 as Api.GroupCallParticipantVideo:
|
case let _1 as Api.GroupCallParticipantVideo:
|
||||||
|
|||||||
@ -1,3 +1,313 @@
|
|||||||
|
public extension Api {
|
||||||
|
indirect enum InputFileLocation: TypeConstructorDescription {
|
||||||
|
case inputDocumentFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, thumbSize: String)
|
||||||
|
case inputEncryptedFileLocation(id: Int64, accessHash: Int64)
|
||||||
|
case inputFileLocation(volumeId: Int64, localId: Int32, secret: Int64, fileReference: Buffer)
|
||||||
|
case inputGroupCallStream(flags: Int32, call: Api.InputGroupCall, timeMs: Int64, scale: Int32, videoChannel: Int32?, videoQuality: Int32?)
|
||||||
|
case inputPeerPhotoFileLocation(flags: Int32, peer: Api.InputPeer, photoId: Int64)
|
||||||
|
case inputPhotoFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, thumbSize: String)
|
||||||
|
case inputPhotoLegacyFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, volumeId: Int64, localId: Int32, secret: Int64)
|
||||||
|
case inputSecureFileLocation(id: Int64, accessHash: Int64)
|
||||||
|
case inputStickerSetThumb(stickerset: Api.InputStickerSet, thumbVersion: Int32)
|
||||||
|
case inputTakeoutFileLocation
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputDocumentFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1160743548)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
||||||
|
serializeString(thumbSize, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputEncryptedFileLocation(let id, let accessHash):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-182231723)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputFileLocation(let volumeId, let localId, let secret, let fileReference):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-539317279)
|
||||||
|
}
|
||||||
|
serializeInt64(volumeId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(localId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(secret, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputGroupCallStream(let flags, let call, let timeMs, let scale, let videoChannel, let videoQuality):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(93890858)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
call.serialize(buffer, true)
|
||||||
|
serializeInt64(timeMs, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(scale, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(videoChannel!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(videoQuality!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
case .inputPeerPhotoFileLocation(let flags, let peer, let photoId):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(925204121)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
peer.serialize(buffer, true)
|
||||||
|
serializeInt64(photoId, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputPhotoFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1075322878)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
||||||
|
serializeString(thumbSize, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputPhotoLegacyFileLocation(let id, let accessHash, let fileReference, let volumeId, let localId, let secret):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-667654413)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(volumeId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(localId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(secret, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputSecureFileLocation(let id, let accessHash):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-876089816)
|
||||||
|
}
|
||||||
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputStickerSetThumb(let stickerset, let thumbVersion):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1652231205)
|
||||||
|
}
|
||||||
|
stickerset.serialize(buffer, true)
|
||||||
|
serializeInt32(thumbVersion, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputTakeoutFileLocation:
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(700340377)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputDocumentFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
||||||
|
return ("inputDocumentFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("thumbSize", thumbSize as Any)])
|
||||||
|
case .inputEncryptedFileLocation(let id, let accessHash):
|
||||||
|
return ("inputEncryptedFileLocation", [("id", id as Any), ("accessHash", accessHash as Any)])
|
||||||
|
case .inputFileLocation(let volumeId, let localId, let secret, let fileReference):
|
||||||
|
return ("inputFileLocation", [("volumeId", volumeId as Any), ("localId", localId as Any), ("secret", secret as Any), ("fileReference", fileReference as Any)])
|
||||||
|
case .inputGroupCallStream(let flags, let call, let timeMs, let scale, let videoChannel, let videoQuality):
|
||||||
|
return ("inputGroupCallStream", [("flags", flags as Any), ("call", call as Any), ("timeMs", timeMs as Any), ("scale", scale as Any), ("videoChannel", videoChannel as Any), ("videoQuality", videoQuality as Any)])
|
||||||
|
case .inputPeerPhotoFileLocation(let flags, let peer, let photoId):
|
||||||
|
return ("inputPeerPhotoFileLocation", [("flags", flags as Any), ("peer", peer as Any), ("photoId", photoId as Any)])
|
||||||
|
case .inputPhotoFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
||||||
|
return ("inputPhotoFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("thumbSize", thumbSize as Any)])
|
||||||
|
case .inputPhotoLegacyFileLocation(let id, let accessHash, let fileReference, let volumeId, let localId, let secret):
|
||||||
|
return ("inputPhotoLegacyFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("volumeId", volumeId as Any), ("localId", localId as Any), ("secret", secret as Any)])
|
||||||
|
case .inputSecureFileLocation(let id, let accessHash):
|
||||||
|
return ("inputSecureFileLocation", [("id", id as Any), ("accessHash", accessHash as Any)])
|
||||||
|
case .inputStickerSetThumb(let stickerset, let thumbVersion):
|
||||||
|
return ("inputStickerSetThumb", [("stickerset", stickerset as Any), ("thumbVersion", thumbVersion as Any)])
|
||||||
|
case .inputTakeoutFileLocation:
|
||||||
|
return ("inputTakeoutFileLocation", [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputDocumentFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputFileLocation.inputDocumentFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, thumbSize: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputEncryptedFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputFileLocation.inputEncryptedFileLocation(id: _1!, accessHash: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
var _3: Int64?
|
||||||
|
_3 = reader.readInt64()
|
||||||
|
var _4: Buffer?
|
||||||
|
_4 = parseBytes(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputFileLocation.inputFileLocation(volumeId: _1!, localId: _2!, secret: _3!, fileReference: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputGroupCallStream(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputGroupCall?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
||||||
|
}
|
||||||
|
var _3: Int64?
|
||||||
|
_3 = reader.readInt64()
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
var _5: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
||||||
|
var _6: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||||
|
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||||
|
return Api.InputFileLocation.inputGroupCallStream(flags: _1!, call: _2!, timeMs: _3!, scale: _4!, videoChannel: _5, videoQuality: _6)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPeerPhotoFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.InputPeer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputPeer
|
||||||
|
}
|
||||||
|
var _3: Int64?
|
||||||
|
_3 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.InputFileLocation.inputPeerPhotoFileLocation(flags: _1!, peer: _2!, photoId: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPhotoFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputFileLocation.inputPhotoFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, thumbSize: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputPhotoLegacyFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Buffer?
|
||||||
|
_3 = parseBytes(reader)
|
||||||
|
var _4: Int64?
|
||||||
|
_4 = reader.readInt64()
|
||||||
|
var _5: Int32?
|
||||||
|
_5 = reader.readInt32()
|
||||||
|
var _6: Int64?
|
||||||
|
_6 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
let _c6 = _6 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||||
|
return Api.InputFileLocation.inputPhotoLegacyFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, volumeId: _4!, localId: _5!, secret: _6!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputSecureFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Int64?
|
||||||
|
_1 = reader.readInt64()
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputFileLocation.inputSecureFileLocation(id: _1!, accessHash: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputStickerSetThumb(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
var _1: Api.InputStickerSet?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.InputStickerSet
|
||||||
|
}
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.InputFileLocation.inputStickerSetThumb(stickerset: _1!, thumbVersion: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputTakeoutFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
||||||
|
return Api.InputFileLocation.inputTakeoutFileLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
indirect enum InputFolderPeer: TypeConstructorDescription {
|
indirect enum InputFolderPeer: TypeConstructorDescription {
|
||||||
case inputFolderPeer(peer: Api.InputPeer, folderId: Int32)
|
case inputFolderPeer(peer: Api.InputPeer, folderId: Int32)
|
||||||
@ -630,681 +940,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
indirect enum InputMedia: TypeConstructorDescription {
|
|
||||||
case inputMediaContact(phoneNumber: String, firstName: String, lastName: String, vcard: String)
|
|
||||||
case inputMediaDice(emoticon: String)
|
|
||||||
case inputMediaDocument(flags: Int32, id: Api.InputDocument, videoCover: Api.InputPhoto?, videoTimestamp: Int32?, ttlSeconds: Int32?, query: String?)
|
|
||||||
case inputMediaDocumentExternal(flags: Int32, url: String, ttlSeconds: Int32?, videoCover: Api.InputPhoto?, videoTimestamp: Int32?)
|
|
||||||
case inputMediaEmpty
|
|
||||||
case inputMediaGame(id: Api.InputGame)
|
|
||||||
case inputMediaGeoLive(flags: Int32, geoPoint: Api.InputGeoPoint, heading: Int32?, period: Int32?, proximityNotificationRadius: Int32?)
|
|
||||||
case inputMediaGeoPoint(geoPoint: Api.InputGeoPoint)
|
|
||||||
case inputMediaInvoice(flags: Int32, title: String, description: String, photo: Api.InputWebDocument?, invoice: Api.Invoice, payload: Buffer, provider: String?, providerData: Api.DataJSON, startParam: String?, extendedMedia: Api.InputMedia?)
|
|
||||||
case inputMediaPaidMedia(flags: Int32, starsAmount: Int64, extendedMedia: [Api.InputMedia], payload: String?)
|
|
||||||
case inputMediaPhoto(flags: Int32, id: Api.InputPhoto, ttlSeconds: Int32?)
|
|
||||||
case inputMediaPhotoExternal(flags: Int32, url: String, ttlSeconds: Int32?)
|
|
||||||
case inputMediaPoll(flags: Int32, poll: Api.Poll, correctAnswers: [Buffer]?, solution: String?, solutionEntities: [Api.MessageEntity]?)
|
|
||||||
case inputMediaStory(peer: Api.InputPeer, id: Int32)
|
|
||||||
case inputMediaTodo(todo: Api.TodoList)
|
|
||||||
case inputMediaUploadedDocument(flags: Int32, file: Api.InputFile, thumb: Api.InputFile?, mimeType: String, attributes: [Api.DocumentAttribute], stickers: [Api.InputDocument]?, videoCover: Api.InputPhoto?, videoTimestamp: Int32?, ttlSeconds: Int32?)
|
|
||||||
case inputMediaUploadedPhoto(flags: Int32, file: Api.InputFile, stickers: [Api.InputDocument]?, ttlSeconds: Int32?)
|
|
||||||
case inputMediaVenue(geoPoint: Api.InputGeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String)
|
|
||||||
case inputMediaWebPage(flags: Int32, url: String)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-122978821)
|
|
||||||
}
|
|
||||||
serializeString(phoneNumber, buffer: buffer, boxed: false)
|
|
||||||
serializeString(firstName, buffer: buffer, boxed: false)
|
|
||||||
serializeString(lastName, buffer: buffer, boxed: false)
|
|
||||||
serializeString(vcard, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaDice(let emoticon):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-428884101)
|
|
||||||
}
|
|
||||||
serializeString(emoticon, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaDocument(let flags, let id, let videoCover, let videoTimestamp, let ttlSeconds, let query):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1468646731)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {videoCover!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt32(videoTimestamp!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(query!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds, let videoCover, let videoTimestamp):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(2006319353)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {videoCover!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(videoTimestamp!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaEmpty:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1771768449)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
case .inputMediaGame(let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-750828557)
|
|
||||||
}
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1759532989)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(heading!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(period!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(proximityNotificationRadius!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaGeoPoint(let geoPoint):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-104578748)
|
|
||||||
}
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1080028941)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
|
||||||
serializeString(description, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {photo!.serialize(buffer, true)}
|
|
||||||
invoice.serialize(buffer, true)
|
|
||||||
serializeBytes(payload, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(provider!, buffer: buffer, boxed: false)}
|
|
||||||
providerData.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {extendedMedia!.serialize(buffer, true)}
|
|
||||||
break
|
|
||||||
case .inputMediaPaidMedia(let flags, let starsAmount, let extendedMedia, let payload):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1005571194)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(starsAmount, buffer: buffer, boxed: false)
|
|
||||||
buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(extendedMedia.count))
|
|
||||||
for item in extendedMedia {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(payload!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1279654347)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
id.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-440664550)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(261416433)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
poll.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(correctAnswers!.count))
|
|
||||||
for item in correctAnswers! {
|
|
||||||
serializeBytes(item, buffer: buffer, boxed: false)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(solution!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(solutionEntities!.count))
|
|
||||||
for item in solutionEntities! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
break
|
|
||||||
case .inputMediaStory(let peer, let id):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1979852936)
|
|
||||||
}
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaTodo(let todo):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1614454818)
|
|
||||||
}
|
|
||||||
todo.serialize(buffer, true)
|
|
||||||
break
|
|
||||||
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let videoCover, let videoTimestamp, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(58495792)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
file.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 2) != 0 {thumb!.serialize(buffer, true)}
|
|
||||||
serializeString(mimeType, buffer: buffer, boxed: false)
|
|
||||||
buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(attributes.count))
|
|
||||||
for item in attributes {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(stickers!.count))
|
|
||||||
for item in stickers! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 6) != 0 {videoCover!.serialize(buffer, true)}
|
|
||||||
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(videoTimestamp!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(505969924)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
file.serialize(buffer, true)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(stickers!.count))
|
|
||||||
for item in stickers! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(ttlSeconds!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1052959727)
|
|
||||||
}
|
|
||||||
geoPoint.serialize(buffer, true)
|
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
|
||||||
serializeString(address, buffer: buffer, boxed: false)
|
|
||||||
serializeString(provider, buffer: buffer, boxed: false)
|
|
||||||
serializeString(venueId, buffer: buffer, boxed: false)
|
|
||||||
serializeString(venueType, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputMediaWebPage(let flags, let url):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1038383031)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(url, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputMediaContact(let phoneNumber, let firstName, let lastName, let vcard):
|
|
||||||
return ("inputMediaContact", [("phoneNumber", phoneNumber as Any), ("firstName", firstName as Any), ("lastName", lastName as Any), ("vcard", vcard as Any)])
|
|
||||||
case .inputMediaDice(let emoticon):
|
|
||||||
return ("inputMediaDice", [("emoticon", emoticon as Any)])
|
|
||||||
case .inputMediaDocument(let flags, let id, let videoCover, let videoTimestamp, let ttlSeconds, let query):
|
|
||||||
return ("inputMediaDocument", [("flags", flags as Any), ("id", id as Any), ("videoCover", videoCover as Any), ("videoTimestamp", videoTimestamp as Any), ("ttlSeconds", ttlSeconds as Any), ("query", query as Any)])
|
|
||||||
case .inputMediaDocumentExternal(let flags, let url, let ttlSeconds, let videoCover, let videoTimestamp):
|
|
||||||
return ("inputMediaDocumentExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any), ("videoCover", videoCover as Any), ("videoTimestamp", videoTimestamp as Any)])
|
|
||||||
case .inputMediaEmpty:
|
|
||||||
return ("inputMediaEmpty", [])
|
|
||||||
case .inputMediaGame(let id):
|
|
||||||
return ("inputMediaGame", [("id", id as Any)])
|
|
||||||
case .inputMediaGeoLive(let flags, let geoPoint, let heading, let period, let proximityNotificationRadius):
|
|
||||||
return ("inputMediaGeoLive", [("flags", flags as Any), ("geoPoint", geoPoint as Any), ("heading", heading as Any), ("period", period as Any), ("proximityNotificationRadius", proximityNotificationRadius as Any)])
|
|
||||||
case .inputMediaGeoPoint(let geoPoint):
|
|
||||||
return ("inputMediaGeoPoint", [("geoPoint", geoPoint as Any)])
|
|
||||||
case .inputMediaInvoice(let flags, let title, let description, let photo, let invoice, let payload, let provider, let providerData, let startParam, let extendedMedia):
|
|
||||||
return ("inputMediaInvoice", [("flags", flags as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("payload", payload as Any), ("provider", provider as Any), ("providerData", providerData as Any), ("startParam", startParam as Any), ("extendedMedia", extendedMedia as Any)])
|
|
||||||
case .inputMediaPaidMedia(let flags, let starsAmount, let extendedMedia, let payload):
|
|
||||||
return ("inputMediaPaidMedia", [("flags", flags as Any), ("starsAmount", starsAmount as Any), ("extendedMedia", extendedMedia as Any), ("payload", payload as Any)])
|
|
||||||
case .inputMediaPhoto(let flags, let id, let ttlSeconds):
|
|
||||||
return ("inputMediaPhoto", [("flags", flags as Any), ("id", id as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaPhotoExternal(let flags, let url, let ttlSeconds):
|
|
||||||
return ("inputMediaPhotoExternal", [("flags", flags as Any), ("url", url as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaPoll(let flags, let poll, let correctAnswers, let solution, let solutionEntities):
|
|
||||||
return ("inputMediaPoll", [("flags", flags as Any), ("poll", poll as Any), ("correctAnswers", correctAnswers as Any), ("solution", solution as Any), ("solutionEntities", solutionEntities as Any)])
|
|
||||||
case .inputMediaStory(let peer, let id):
|
|
||||||
return ("inputMediaStory", [("peer", peer as Any), ("id", id as Any)])
|
|
||||||
case .inputMediaTodo(let todo):
|
|
||||||
return ("inputMediaTodo", [("todo", todo as Any)])
|
|
||||||
case .inputMediaUploadedDocument(let flags, let file, let thumb, let mimeType, let attributes, let stickers, let videoCover, let videoTimestamp, let ttlSeconds):
|
|
||||||
return ("inputMediaUploadedDocument", [("flags", flags as Any), ("file", file as Any), ("thumb", thumb as Any), ("mimeType", mimeType as Any), ("attributes", attributes as Any), ("stickers", stickers as Any), ("videoCover", videoCover as Any), ("videoTimestamp", videoTimestamp as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaUploadedPhoto(let flags, let file, let stickers, let ttlSeconds):
|
|
||||||
return ("inputMediaUploadedPhoto", [("flags", flags as Any), ("file", file as Any), ("stickers", stickers as Any), ("ttlSeconds", ttlSeconds as Any)])
|
|
||||||
case .inputMediaVenue(let geoPoint, let title, let address, let provider, let venueId, let venueType):
|
|
||||||
return ("inputMediaVenue", [("geoPoint", geoPoint as Any), ("title", title as Any), ("address", address as Any), ("provider", provider as Any), ("venueId", venueId as Any), ("venueType", venueType as Any)])
|
|
||||||
case .inputMediaWebPage(let flags, let url):
|
|
||||||
return ("inputMediaWebPage", [("flags", flags as Any), ("url", url as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputMediaContact(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaContact(phoneNumber: _1!, firstName: _2!, lastName: _3!, vcard: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDice(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: String?
|
|
||||||
_1 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaDice(emoticon: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDocument(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputDocument?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputDocument
|
|
||||||
}
|
|
||||||
var _3: Api.InputPhoto?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_3 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
} }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 4) != 0 {_4 = reader.readInt32() }
|
|
||||||
var _5: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
|
||||||
var _6: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_6 = parseString(reader) }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 3) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 4) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
|
||||||
let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.InputMedia.inputMediaDocument(flags: _1!, id: _2!, videoCover: _3, videoTimestamp: _4, ttlSeconds: _5, query: _6)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaDocumentExternal(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
var _4: Api.InputPhoto?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_4 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
} }
|
|
||||||
var _5: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputMedia.inputMediaDocumentExternal(flags: _1!, url: _2!, ttlSeconds: _3, videoCover: _4, videoTimestamp: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaEmpty(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
return Api.InputMedia.inputMediaEmpty
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGame(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGame?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGame
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaGame(id: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGeoLive(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {_3 = reader.readInt32() }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
|
||||||
var _5: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputMedia.inputMediaGeoLive(flags: _1!, geoPoint: _2!, heading: _3, period: _4, proximityNotificationRadius: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaGeoPoint(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaGeoPoint(geoPoint: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaInvoice(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: Api.InputWebDocument?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_4 = Api.parse(reader, signature: signature) as? Api.InputWebDocument
|
|
||||||
} }
|
|
||||||
var _5: Api.Invoice?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_5 = Api.parse(reader, signature: signature) as? Api.Invoice
|
|
||||||
}
|
|
||||||
var _6: Buffer?
|
|
||||||
_6 = parseBytes(reader)
|
|
||||||
var _7: String?
|
|
||||||
if Int(_1!) & Int(1 << 3) != 0 {_7 = parseString(reader) }
|
|
||||||
var _8: Api.DataJSON?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_8 = Api.parse(reader, signature: signature) as? Api.DataJSON
|
|
||||||
}
|
|
||||||
var _9: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_9 = parseString(reader) }
|
|
||||||
var _10: Api.InputMedia?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_10 = Api.parse(reader, signature: signature) as? Api.InputMedia
|
|
||||||
} }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = _6 != nil
|
|
||||||
let _c7 = (Int(_1!) & Int(1 << 3) == 0) || _7 != nil
|
|
||||||
let _c8 = _8 != nil
|
|
||||||
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
|
|
||||||
let _c10 = (Int(_1!) & Int(1 << 2) == 0) || _10 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
|
|
||||||
return Api.InputMedia.inputMediaInvoice(flags: _1!, title: _2!, description: _3!, photo: _4, invoice: _5!, payload: _6!, provider: _7, providerData: _8!, startParam: _9, extendedMedia: _10)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPaidMedia(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: [Api.InputMedia]?
|
|
||||||
if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputMedia.self)
|
|
||||||
}
|
|
||||||
var _4: String?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaPaidMedia(flags: _1!, starsAmount: _2!, extendedMedia: _3!, payload: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPhoto(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputPhoto?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
}
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputMedia.inputMediaPhoto(flags: _1!, id: _2!, ttlSeconds: _3)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPhotoExternal(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputMedia.inputMediaPhotoExternal(flags: _1!, url: _2!, ttlSeconds: _3)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaPoll(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.Poll?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.Poll
|
|
||||||
}
|
|
||||||
var _3: [Buffer]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: -1255641564, elementType: Buffer.self)
|
|
||||||
} }
|
|
||||||
var _4: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
|
||||||
var _5: [Api.MessageEntity]?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
|
||||||
} }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
|
||||||
return Api.InputMedia.inputMediaPoll(flags: _1!, poll: _2!, correctAnswers: _3, solution: _4, solutionEntities: _5)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaStory(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputPeer?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputPeer
|
|
||||||
}
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputMedia.inputMediaStory(peer: _1!, id: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaTodo(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.TodoList?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.TodoList
|
|
||||||
}
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
if _c1 {
|
|
||||||
return Api.InputMedia.inputMediaTodo(todo: _1!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaUploadedDocument(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputFile?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
}
|
|
||||||
var _3: Api.InputFile?
|
|
||||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_3 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
} }
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
var _5: [Api.DocumentAttribute]?
|
|
||||||
if let _ = reader.readInt32() {
|
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.DocumentAttribute.self)
|
|
||||||
}
|
|
||||||
var _6: [Api.InputDocument]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
|
||||||
} }
|
|
||||||
var _7: Api.InputPhoto?
|
|
||||||
if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
|
|
||||||
_7 = Api.parse(reader, signature: signature) as? Api.InputPhoto
|
|
||||||
} }
|
|
||||||
var _8: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 7) != 0 {_8 = reader.readInt32() }
|
|
||||||
var _9: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_9 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 2) == 0) || _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
|
||||||
let _c7 = (Int(_1!) & Int(1 << 6) == 0) || _7 != nil
|
|
||||||
let _c8 = (Int(_1!) & Int(1 << 7) == 0) || _8 != nil
|
|
||||||
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
|
|
||||||
return Api.InputMedia.inputMediaUploadedDocument(flags: _1!, file: _2!, thumb: _3, mimeType: _4!, attributes: _5!, stickers: _6, videoCover: _7, videoTimestamp: _8, ttlSeconds: _9)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaUploadedPhoto(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputFile?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputFile
|
|
||||||
}
|
|
||||||
var _3: [Api.InputDocument]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputDocument.self)
|
|
||||||
} }
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputMedia.inputMediaUploadedPhoto(flags: _1!, file: _2!, stickers: _3, ttlSeconds: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaVenue(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Api.InputGeoPoint?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputGeoPoint
|
|
||||||
}
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: String?
|
|
||||||
_3 = parseString(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
var _5: String?
|
|
||||||
_5 = parseString(reader)
|
|
||||||
var _6: String?
|
|
||||||
_6 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.InputMedia.inputMediaVenue(geoPoint: _1!, title: _2!, address: _3!, provider: _4!, venueId: _5!, venueType: _6!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputMediaWebPage(_ reader: BufferReader) -> InputMedia? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputMedia.inputMediaWebPage(flags: _1!, url: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,675 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum KeyboardButtonRow: TypeConstructorDescription {
|
||||||
|
case keyboardButtonRow(buttons: [Api.KeyboardButton])
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .keyboardButtonRow(let buttons):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(2002815875)
|
||||||
|
}
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(buttons.count))
|
||||||
|
for item in buttons {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .keyboardButtonRow(let buttons):
|
||||||
|
return ("keyboardButtonRow", [("buttons", buttons as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_keyboardButtonRow(_ reader: BufferReader) -> KeyboardButtonRow? {
|
||||||
|
var _1: [Api.KeyboardButton]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.KeyboardButton.self)
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.KeyboardButtonRow.keyboardButtonRow(buttons: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum LabeledPrice: TypeConstructorDescription {
|
||||||
|
case labeledPrice(label: String, amount: Int64)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .labeledPrice(let label, let amount):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-886477832)
|
||||||
|
}
|
||||||
|
serializeString(label, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(amount, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .labeledPrice(let label, let amount):
|
||||||
|
return ("labeledPrice", [("label", label as Any), ("amount", amount as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_labeledPrice(_ reader: BufferReader) -> LabeledPrice? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.LabeledPrice.labeledPrice(label: _1!, amount: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum LangPackDifference: TypeConstructorDescription {
|
||||||
|
case langPackDifference(langCode: String, fromVersion: Int32, version: Int32, strings: [Api.LangPackString])
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .langPackDifference(let langCode, let fromVersion, let version, let strings):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-209337866)
|
||||||
|
}
|
||||||
|
serializeString(langCode, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(fromVersion, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(version, buffer: buffer, boxed: false)
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(strings.count))
|
||||||
|
for item in strings {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .langPackDifference(let langCode, let fromVersion, let version, let strings):
|
||||||
|
return ("langPackDifference", [("langCode", langCode as Any), ("fromVersion", fromVersion as Any), ("version", version as Any), ("strings", strings as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_langPackDifference(_ reader: BufferReader) -> LangPackDifference? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
var _2: Int32?
|
||||||
|
_2 = reader.readInt32()
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
var _4: [Api.LangPackString]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.LangPackString.self)
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.LangPackDifference.langPackDifference(langCode: _1!, fromVersion: _2!, version: _3!, strings: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum LangPackLanguage: TypeConstructorDescription {
|
||||||
|
case langPackLanguage(flags: Int32, name: String, nativeName: String, langCode: String, baseLangCode: String?, pluralCode: String, stringsCount: Int32, translatedCount: Int32, translationsUrl: String)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount, let translationsUrl):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-288727837)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(name, buffer: buffer, boxed: false)
|
||||||
|
serializeString(nativeName, buffer: buffer, boxed: false)
|
||||||
|
serializeString(langCode, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(baseLangCode!, buffer: buffer, boxed: false)}
|
||||||
|
serializeString(pluralCode, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(stringsCount, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(translatedCount, buffer: buffer, boxed: false)
|
||||||
|
serializeString(translationsUrl, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .langPackLanguage(let flags, let name, let nativeName, let langCode, let baseLangCode, let pluralCode, let stringsCount, let translatedCount, let translationsUrl):
|
||||||
|
return ("langPackLanguage", [("flags", flags as Any), ("name", name as Any), ("nativeName", nativeName as Any), ("langCode", langCode as Any), ("baseLangCode", baseLangCode as Any), ("pluralCode", pluralCode as Any), ("stringsCount", stringsCount as Any), ("translatedCount", translatedCount as Any), ("translationsUrl", translationsUrl as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_langPackLanguage(_ reader: BufferReader) -> LangPackLanguage? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
var _5: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_5 = parseString(reader) }
|
||||||
|
var _6: String?
|
||||||
|
_6 = parseString(reader)
|
||||||
|
var _7: Int32?
|
||||||
|
_7 = reader.readInt32()
|
||||||
|
var _8: Int32?
|
||||||
|
_8 = reader.readInt32()
|
||||||
|
var _9: String?
|
||||||
|
_9 = parseString(reader)
|
||||||
|
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.LangPackLanguage.langPackLanguage(flags: _1!, name: _2!, nativeName: _3!, langCode: _4!, baseLangCode: _5, pluralCode: _6!, stringsCount: _7!, translatedCount: _8!, translationsUrl: _9!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum LangPackString: TypeConstructorDescription {
|
||||||
|
case langPackString(key: String, value: String)
|
||||||
|
case langPackStringDeleted(key: String)
|
||||||
|
case langPackStringPluralized(flags: Int32, key: String, zeroValue: String?, oneValue: String?, twoValue: String?, fewValue: String?, manyValue: String?, otherValue: String)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .langPackString(let key, let value):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-892239370)
|
||||||
|
}
|
||||||
|
serializeString(key, buffer: buffer, boxed: false)
|
||||||
|
serializeString(value, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .langPackStringDeleted(let key):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(695856818)
|
||||||
|
}
|
||||||
|
serializeString(key, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .langPackStringPluralized(let flags, let key, let zeroValue, let oneValue, let twoValue, let fewValue, let manyValue, let otherValue):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1816636575)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(key, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeString(zeroValue!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(oneValue!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeString(twoValue!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 3) != 0 {serializeString(fewValue!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 4) != 0 {serializeString(manyValue!, buffer: buffer, boxed: false)}
|
||||||
|
serializeString(otherValue, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .langPackString(let key, let value):
|
||||||
|
return ("langPackString", [("key", key as Any), ("value", value as Any)])
|
||||||
|
case .langPackStringDeleted(let key):
|
||||||
|
return ("langPackStringDeleted", [("key", key as Any)])
|
||||||
|
case .langPackStringPluralized(let flags, let key, let zeroValue, let oneValue, let twoValue, let fewValue, let manyValue, let otherValue):
|
||||||
|
return ("langPackStringPluralized", [("flags", flags as Any), ("key", key as Any), ("zeroValue", zeroValue as Any), ("oneValue", oneValue as Any), ("twoValue", twoValue as Any), ("fewValue", fewValue as Any), ("manyValue", manyValue as Any), ("otherValue", otherValue as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_langPackString(_ reader: BufferReader) -> LangPackString? {
|
||||||
|
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.LangPackString.langPackString(key: _1!, value: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_langPackStringDeleted(_ reader: BufferReader) -> LangPackString? {
|
||||||
|
var _1: String?
|
||||||
|
_1 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
if _c1 {
|
||||||
|
return Api.LangPackString.langPackStringDeleted(key: _1!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_langPackStringPluralized(_ reader: BufferReader) -> LangPackString? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: String?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||||
|
var _4: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||||
|
var _5: String?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_5 = parseString(reader) }
|
||||||
|
var _6: String?
|
||||||
|
if Int(_1!) & Int(1 << 3) != 0 {_6 = parseString(reader) }
|
||||||
|
var _7: String?
|
||||||
|
if Int(_1!) & Int(1 << 4) != 0 {_7 = parseString(reader) }
|
||||||
|
var _8: String?
|
||||||
|
_8 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
|
||||||
|
let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil
|
||||||
|
let _c7 = (Int(_1!) & Int(1 << 4) == 0) || _7 != nil
|
||||||
|
let _c8 = _8 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
|
||||||
|
return Api.LangPackString.langPackStringPluralized(flags: _1!, key: _2!, zeroValue: _3, oneValue: _4, twoValue: _5, fewValue: _6, manyValue: _7, otherValue: _8!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum MaskCoords: TypeConstructorDescription {
|
||||||
|
case maskCoords(n: Int32, x: Double, y: Double, zoom: Double)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .maskCoords(let n, let x, let y, let zoom):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1361650766)
|
||||||
|
}
|
||||||
|
serializeInt32(n, buffer: buffer, boxed: false)
|
||||||
|
serializeDouble(x, buffer: buffer, boxed: false)
|
||||||
|
serializeDouble(y, buffer: buffer, boxed: false)
|
||||||
|
serializeDouble(zoom, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .maskCoords(let n, let x, let y, let zoom):
|
||||||
|
return ("maskCoords", [("n", n as Any), ("x", x as Any), ("y", y as Any), ("zoom", zoom as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_maskCoords(_ reader: BufferReader) -> MaskCoords? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Double?
|
||||||
|
_2 = reader.readDouble()
|
||||||
|
var _3: Double?
|
||||||
|
_3 = reader.readDouble()
|
||||||
|
var _4: Double?
|
||||||
|
_4 = reader.readDouble()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.MaskCoords.maskCoords(n: _1!, x: _2!, y: _3!, zoom: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public extension Api {
|
||||||
|
indirect enum MediaArea: TypeConstructorDescription {
|
||||||
|
case inputMediaAreaChannelPost(coordinates: Api.MediaAreaCoordinates, channel: Api.InputChannel, msgId: Int32)
|
||||||
|
case inputMediaAreaVenue(coordinates: Api.MediaAreaCoordinates, queryId: Int64, resultId: String)
|
||||||
|
case mediaAreaChannelPost(coordinates: Api.MediaAreaCoordinates, channelId: Int64, msgId: Int32)
|
||||||
|
case mediaAreaGeoPoint(flags: Int32, coordinates: Api.MediaAreaCoordinates, geo: Api.GeoPoint, address: Api.GeoPointAddress?)
|
||||||
|
case mediaAreaStarGift(coordinates: Api.MediaAreaCoordinates, slug: String)
|
||||||
|
case mediaAreaSuggestedReaction(flags: Int32, coordinates: Api.MediaAreaCoordinates, reaction: Api.Reaction)
|
||||||
|
case mediaAreaUrl(coordinates: Api.MediaAreaCoordinates, url: String)
|
||||||
|
case mediaAreaVenue(coordinates: Api.MediaAreaCoordinates, geo: Api.GeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String)
|
||||||
|
case mediaAreaWeather(coordinates: Api.MediaAreaCoordinates, emoji: String, temperatureC: Double, color: Int32)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputMediaAreaChannelPost(let coordinates, let channel, let msgId):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(577893055)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
channel.serialize(buffer, true)
|
||||||
|
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .inputMediaAreaVenue(let coordinates, let queryId, let resultId):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1300094593)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
serializeInt64(queryId, buffer: buffer, boxed: false)
|
||||||
|
serializeString(resultId, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .mediaAreaChannelPost(let coordinates, let channelId, let msgId):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1996756655)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
serializeInt64(channelId, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .mediaAreaGeoPoint(let flags, let coordinates, let geo, let address):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-891992787)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
geo.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {address!.serialize(buffer, true)}
|
||||||
|
break
|
||||||
|
case .mediaAreaStarGift(let coordinates, let slug):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1468491885)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
serializeString(slug, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .mediaAreaSuggestedReaction(let flags, let coordinates, let reaction):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(340088945)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
reaction.serialize(buffer, true)
|
||||||
|
break
|
||||||
|
case .mediaAreaUrl(let coordinates, let url):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(926421125)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
serializeString(url, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .mediaAreaVenue(let coordinates, let geo, let title, let address, let provider, let venueId, let venueType):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-1098720356)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
geo.serialize(buffer, true)
|
||||||
|
serializeString(title, buffer: buffer, boxed: false)
|
||||||
|
serializeString(address, buffer: buffer, boxed: false)
|
||||||
|
serializeString(provider, buffer: buffer, boxed: false)
|
||||||
|
serializeString(venueId, buffer: buffer, boxed: false)
|
||||||
|
serializeString(venueType, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
case .mediaAreaWeather(let coordinates, let emoji, let temperatureC, let color):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1235637404)
|
||||||
|
}
|
||||||
|
coordinates.serialize(buffer, true)
|
||||||
|
serializeString(emoji, buffer: buffer, boxed: false)
|
||||||
|
serializeDouble(temperatureC, buffer: buffer, boxed: false)
|
||||||
|
serializeInt32(color, buffer: buffer, boxed: false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputMediaAreaChannelPost(let coordinates, let channel, let msgId):
|
||||||
|
return ("inputMediaAreaChannelPost", [("coordinates", coordinates as Any), ("channel", channel as Any), ("msgId", msgId as Any)])
|
||||||
|
case .inputMediaAreaVenue(let coordinates, let queryId, let resultId):
|
||||||
|
return ("inputMediaAreaVenue", [("coordinates", coordinates as Any), ("queryId", queryId as Any), ("resultId", resultId as Any)])
|
||||||
|
case .mediaAreaChannelPost(let coordinates, let channelId, let msgId):
|
||||||
|
return ("mediaAreaChannelPost", [("coordinates", coordinates as Any), ("channelId", channelId as Any), ("msgId", msgId as Any)])
|
||||||
|
case .mediaAreaGeoPoint(let flags, let coordinates, let geo, let address):
|
||||||
|
return ("mediaAreaGeoPoint", [("flags", flags as Any), ("coordinates", coordinates as Any), ("geo", geo as Any), ("address", address as Any)])
|
||||||
|
case .mediaAreaStarGift(let coordinates, let slug):
|
||||||
|
return ("mediaAreaStarGift", [("coordinates", coordinates as Any), ("slug", slug as Any)])
|
||||||
|
case .mediaAreaSuggestedReaction(let flags, let coordinates, let reaction):
|
||||||
|
return ("mediaAreaSuggestedReaction", [("flags", flags as Any), ("coordinates", coordinates as Any), ("reaction", reaction as Any)])
|
||||||
|
case .mediaAreaUrl(let coordinates, let url):
|
||||||
|
return ("mediaAreaUrl", [("coordinates", coordinates as Any), ("url", url as Any)])
|
||||||
|
case .mediaAreaVenue(let coordinates, let geo, let title, let address, let provider, let venueId, let venueType):
|
||||||
|
return ("mediaAreaVenue", [("coordinates", coordinates as Any), ("geo", geo as Any), ("title", title as Any), ("address", address as Any), ("provider", provider as Any), ("venueId", venueId as Any), ("venueType", venueType as Any)])
|
||||||
|
case .mediaAreaWeather(let coordinates, let emoji, let temperatureC, let color):
|
||||||
|
return ("mediaAreaWeather", [("coordinates", coordinates as Any), ("emoji", emoji as Any), ("temperatureC", temperatureC as Any), ("color", color as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputMediaAreaChannelPost(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: Api.InputChannel?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.InputChannel
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.MediaArea.inputMediaAreaChannelPost(coordinates: _1!, channel: _2!, msgId: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_inputMediaAreaVenue(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.MediaArea.inputMediaAreaVenue(coordinates: _1!, queryId: _2!, resultId: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaChannelPost(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: Int64?
|
||||||
|
_2 = reader.readInt64()
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.MediaArea.mediaAreaChannelPost(coordinates: _1!, channelId: _2!, msgId: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaGeoPoint(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _3: Api.GeoPoint?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.GeoPoint
|
||||||
|
}
|
||||||
|
var _4: Api.GeoPointAddress?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_4 = Api.parse(reader, signature: signature) as? Api.GeoPointAddress
|
||||||
|
} }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.MediaArea.mediaAreaGeoPoint(flags: _1!, coordinates: _2!, geo: _3!, address: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaStarGift(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.MediaArea.mediaAreaStarGift(coordinates: _1!, slug: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaSuggestedReaction(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _3: Api.Reaction?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_3 = Api.parse(reader, signature: signature) as? Api.Reaction
|
||||||
|
}
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
if _c1 && _c2 && _c3 {
|
||||||
|
return Api.MediaArea.mediaAreaSuggestedReaction(flags: _1!, coordinates: _2!, reaction: _3!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaUrl(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
if _c1 && _c2 {
|
||||||
|
return Api.MediaArea.mediaAreaUrl(coordinates: _1!, url: _2!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaVenue(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: Api.GeoPoint?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.GeoPoint
|
||||||
|
}
|
||||||
|
var _3: String?
|
||||||
|
_3 = parseString(reader)
|
||||||
|
var _4: String?
|
||||||
|
_4 = parseString(reader)
|
||||||
|
var _5: String?
|
||||||
|
_5 = parseString(reader)
|
||||||
|
var _6: String?
|
||||||
|
_6 = parseString(reader)
|
||||||
|
var _7: String?
|
||||||
|
_7 = parseString(reader)
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
let _c6 = _6 != nil
|
||||||
|
let _c7 = _7 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||||
|
return Api.MediaArea.mediaAreaVenue(coordinates: _1!, geo: _2!, title: _3!, address: _4!, provider: _5!, venueId: _6!, venueType: _7!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static func parse_mediaAreaWeather(_ reader: BufferReader) -> MediaArea? {
|
||||||
|
var _1: Api.MediaAreaCoordinates?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates
|
||||||
|
}
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: Double?
|
||||||
|
_3 = reader.readDouble()
|
||||||
|
var _4: Int32?
|
||||||
|
_4 = reader.readInt32()
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.MediaArea.mediaAreaWeather(coordinates: _1!, emoji: _2!, temperatureC: _3!, color: _4!)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum MediaAreaCoordinates: TypeConstructorDescription {
|
enum MediaAreaCoordinates: TypeConstructorDescription {
|
||||||
case mediaAreaCoordinates(flags: Int32, x: Double, y: Double, w: Double, h: Double, rotation: Double, radius: Double?)
|
case mediaAreaCoordinates(flags: Int32, x: Double, y: Double, w: Double, h: Double, rotation: Double, radius: Double?)
|
||||||
|
|||||||
@ -608,7 +608,7 @@ public extension Api {
|
|||||||
case updateGroupCallChainBlocks(call: Api.InputGroupCall, subChainId: Int32, blocks: [Buffer], nextOffset: Int32)
|
case updateGroupCallChainBlocks(call: Api.InputGroupCall, subChainId: Int32, blocks: [Buffer], nextOffset: Int32)
|
||||||
case updateGroupCallConnection(flags: Int32, params: Api.DataJSON)
|
case updateGroupCallConnection(flags: Int32, params: Api.DataJSON)
|
||||||
case updateGroupCallEncryptedMessage(call: Api.InputGroupCall, fromId: Api.Peer, encryptedMessage: Buffer)
|
case updateGroupCallEncryptedMessage(call: Api.InputGroupCall, fromId: Api.Peer, encryptedMessage: Buffer)
|
||||||
case updateGroupCallMessage(flags: Int32, call: Api.InputGroupCall, fromId: Api.Peer, randomId: Int64, message: Api.TextWithEntities, paidMessageStars: Int64?)
|
case updateGroupCallMessage(call: Api.InputGroupCall, message: Api.GroupCallMessage)
|
||||||
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
|
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
|
||||||
case updateInlineBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, msgId: Api.InputBotInlineMessageID, chatInstance: Int64, data: Buffer?, gameShortName: String?)
|
case updateInlineBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, msgId: Api.InputBotInlineMessageID, chatInstance: Int64, data: Buffer?, gameShortName: String?)
|
||||||
case updateLangPack(difference: Api.LangPackDifference)
|
case updateLangPack(difference: Api.LangPackDifference)
|
||||||
@ -1307,16 +1307,12 @@ public extension Api {
|
|||||||
fromId.serialize(buffer, true)
|
fromId.serialize(buffer, true)
|
||||||
serializeBytes(encryptedMessage, buffer: buffer, boxed: false)
|
serializeBytes(encryptedMessage, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
case .updateGroupCallMessage(let flags, let call, let fromId, let randomId, let message, let paidMessageStars):
|
case .updateGroupCallMessage(let call, let message):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-964095818)
|
buffer.appendInt32(-667783411)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
call.serialize(buffer, true)
|
call.serialize(buffer, true)
|
||||||
fromId.serialize(buffer, true)
|
|
||||||
serializeInt64(randomId, buffer: buffer, boxed: false)
|
|
||||||
message.serialize(buffer, true)
|
message.serialize(buffer, true)
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(paidMessageStars!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
break
|
||||||
case .updateGroupCallParticipants(let call, let participants, let version):
|
case .updateGroupCallParticipants(let call, let participants, let version):
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -2120,8 +2116,8 @@ public extension Api {
|
|||||||
return ("updateGroupCallConnection", [("flags", flags as Any), ("params", params as Any)])
|
return ("updateGroupCallConnection", [("flags", flags as Any), ("params", params as Any)])
|
||||||
case .updateGroupCallEncryptedMessage(let call, let fromId, let encryptedMessage):
|
case .updateGroupCallEncryptedMessage(let call, let fromId, let encryptedMessage):
|
||||||
return ("updateGroupCallEncryptedMessage", [("call", call as Any), ("fromId", fromId as Any), ("encryptedMessage", encryptedMessage as Any)])
|
return ("updateGroupCallEncryptedMessage", [("call", call as Any), ("fromId", fromId as Any), ("encryptedMessage", encryptedMessage as Any)])
|
||||||
case .updateGroupCallMessage(let flags, let call, let fromId, let randomId, let message, let paidMessageStars):
|
case .updateGroupCallMessage(let call, let message):
|
||||||
return ("updateGroupCallMessage", [("flags", flags as Any), ("call", call as Any), ("fromId", fromId as Any), ("randomId", randomId as Any), ("message", message as Any), ("paidMessageStars", paidMessageStars as Any)])
|
return ("updateGroupCallMessage", [("call", call as Any), ("message", message as Any)])
|
||||||
case .updateGroupCallParticipants(let call, let participants, let version):
|
case .updateGroupCallParticipants(let call, let participants, let version):
|
||||||
return ("updateGroupCallParticipants", [("call", call as Any), ("participants", participants as Any), ("version", version as Any)])
|
return ("updateGroupCallParticipants", [("call", call as Any), ("participants", participants as Any), ("version", version as Any)])
|
||||||
case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName):
|
case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName):
|
||||||
@ -3595,32 +3591,18 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static func parse_updateGroupCallMessage(_ reader: BufferReader) -> Update? {
|
public static func parse_updateGroupCallMessage(_ reader: BufferReader) -> Update? {
|
||||||
var _1: Int32?
|
var _1: Api.InputGroupCall?
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputGroupCall?
|
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
_1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
||||||
}
|
}
|
||||||
var _3: Api.Peer?
|
var _2: Api.GroupCallMessage?
|
||||||
if let signature = reader.readInt32() {
|
if let signature = reader.readInt32() {
|
||||||
_3 = Api.parse(reader, signature: signature) as? Api.Peer
|
_2 = Api.parse(reader, signature: signature) as? Api.GroupCallMessage
|
||||||
}
|
}
|
||||||
var _4: Int64?
|
|
||||||
_4 = reader.readInt64()
|
|
||||||
var _5: Api.TextWithEntities?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_5 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
|
||||||
}
|
|
||||||
var _6: Int64?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt64() }
|
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
if _c1 && _c2 {
|
||||||
let _c4 = _4 != nil
|
return Api.Update.updateGroupCallMessage(call: _1!, message: _2!)
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.Update.updateGroupCallMessage(flags: _1!, call: _2!, fromId: _3!, randomId: _4!, message: _5!, paidMessageStars: _6)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -1328,6 +1328,66 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api {
|
||||||
|
enum GroupCallMessage: TypeConstructorDescription {
|
||||||
|
case groupCallMessage(flags: Int32, fromId: Api.Peer, date: Int32, randomId: Int64, message: Api.TextWithEntities, paidMessageStars: Int64?)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .groupCallMessage(let flags, let fromId, let date, let randomId, let message, let paidMessageStars):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(-2018173984)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
fromId.serialize(buffer, true)
|
||||||
|
serializeInt32(date, buffer: buffer, boxed: false)
|
||||||
|
serializeInt64(randomId, buffer: buffer, boxed: false)
|
||||||
|
message.serialize(buffer, true)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(paidMessageStars!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .groupCallMessage(let flags, let fromId, let date, let randomId, let message, let paidMessageStars):
|
||||||
|
return ("groupCallMessage", [("flags", flags as Any), ("fromId", fromId as Any), ("date", date as Any), ("randomId", randomId as Any), ("message", message as Any), ("paidMessageStars", paidMessageStars as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_groupCallMessage(_ reader: BufferReader) -> GroupCallMessage? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: Api.Peer?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
}
|
||||||
|
var _3: Int32?
|
||||||
|
_3 = reader.readInt32()
|
||||||
|
var _4: Int64?
|
||||||
|
_4 = reader.readInt64()
|
||||||
|
var _5: Api.TextWithEntities?
|
||||||
|
if let signature = reader.readInt32() {
|
||||||
|
_5 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
|
||||||
|
}
|
||||||
|
var _6: Int64?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt64() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = _4 != nil
|
||||||
|
let _c5 = _5 != nil
|
||||||
|
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||||
|
return Api.GroupCallMessage.groupCallMessage(flags: _1!, fromId: _2!, date: _3!, randomId: _4!, message: _5!, paidMessageStars: _6)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum GroupCallParticipant: TypeConstructorDescription {
|
enum GroupCallParticipant: TypeConstructorDescription {
|
||||||
case groupCallParticipant(flags: Int32, peer: Api.Peer, date: Int32, activeDate: Int32?, source: Int32, volume: Int32?, about: String?, raiseHandRating: Int64?, video: Api.GroupCallParticipantVideo?, presentation: Api.GroupCallParticipantVideo?, paidStarsTotal: Int64?)
|
case groupCallParticipant(flags: Int32, peer: Api.Peer, date: Int32, activeDate: Int32?, source: Int32, volume: Int32?, about: String?, raiseHandRating: Int64?, video: Api.GroupCallParticipantVideo?, presentation: Api.GroupCallParticipantVideo?, paidStarsTotal: Int64?)
|
||||||
@ -1410,57 +1470,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum GroupCallParticipantVideo: TypeConstructorDescription {
|
|
||||||
case groupCallParticipantVideo(flags: Int32, endpoint: String, sourceGroups: [Api.GroupCallParticipantVideoSourceGroup], audioSource: Int32?)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .groupCallParticipantVideo(let flags, let endpoint, let sourceGroups, let audioSource):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1735736008)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(endpoint, buffer: buffer, boxed: false)
|
|
||||||
buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(sourceGroups.count))
|
|
||||||
for item in sourceGroups {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(audioSource!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .groupCallParticipantVideo(let flags, let endpoint, let sourceGroups, let audioSource):
|
|
||||||
return ("groupCallParticipantVideo", [("flags", flags as Any), ("endpoint", endpoint as Any), ("sourceGroups", sourceGroups as Any), ("audioSource", audioSource as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_groupCallParticipantVideo(_ reader: BufferReader) -> GroupCallParticipantVideo? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: [Api.GroupCallParticipantVideoSourceGroup]?
|
|
||||||
if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipantVideoSourceGroup.self)
|
|
||||||
}
|
|
||||||
var _4: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.GroupCallParticipantVideo.groupCallParticipantVideo(flags: _1!, endpoint: _2!, sourceGroups: _3!, audioSource: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,57 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum GroupCallParticipantVideo: TypeConstructorDescription {
|
||||||
|
case groupCallParticipantVideo(flags: Int32, endpoint: String, sourceGroups: [Api.GroupCallParticipantVideoSourceGroup], audioSource: Int32?)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .groupCallParticipantVideo(let flags, let endpoint, let sourceGroups, let audioSource):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(1735736008)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(endpoint, buffer: buffer, boxed: false)
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(sourceGroups.count))
|
||||||
|
for item in sourceGroups {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(audioSource!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .groupCallParticipantVideo(let flags, let endpoint, let sourceGroups, let audioSource):
|
||||||
|
return ("groupCallParticipantVideo", [("flags", flags as Any), ("endpoint", endpoint as Any), ("sourceGroups", sourceGroups as Any), ("audioSource", audioSource as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_groupCallParticipantVideo(_ reader: BufferReader) -> GroupCallParticipantVideo? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: [Api.GroupCallParticipantVideoSourceGroup]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipantVideoSourceGroup.self)
|
||||||
|
}
|
||||||
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = reader.readInt32() }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.GroupCallParticipantVideo.groupCallParticipantVideo(flags: _1!, endpoint: _2!, sourceGroups: _3!, audioSource: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum GroupCallParticipantVideoSourceGroup: TypeConstructorDescription {
|
enum GroupCallParticipantVideoSourceGroup: TypeConstructorDescription {
|
||||||
case groupCallParticipantVideoSourceGroup(semantics: String, sources: [Int32])
|
case groupCallParticipantVideoSourceGroup(semantics: String, sources: [Int32])
|
||||||
@ -1192,57 +1246,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
enum InputBusinessChatLink: TypeConstructorDescription {
|
|
||||||
case inputBusinessChatLink(flags: Int32, message: String, entities: [Api.MessageEntity]?, title: String?)
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputBusinessChatLink(let flags, let message, let entities, let title):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(292003751)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
serializeString(message, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
|
||||||
buffer.appendInt32(Int32(entities!.count))
|
|
||||||
for item in entities! {
|
|
||||||
item.serialize(buffer, true)
|
|
||||||
}}
|
|
||||||
if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputBusinessChatLink(let flags, let message, let entities, let title):
|
|
||||||
return ("inputBusinessChatLink", [("flags", flags as Any), ("message", message as Any), ("entities", entities as Any), ("title", title as Any)])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputBusinessChatLink(_ reader: BufferReader) -> InputBusinessChatLink? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: String?
|
|
||||||
_2 = parseString(reader)
|
|
||||||
var _3: [Api.MessageEntity]?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
|
||||||
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
|
||||||
} }
|
|
||||||
var _4: String?
|
|
||||||
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
|
||||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputBusinessChatLink.inputBusinessChatLink(flags: _1!, message: _2!, entities: _3, title: _4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,57 @@
|
|||||||
|
public extension Api {
|
||||||
|
enum InputBusinessChatLink: TypeConstructorDescription {
|
||||||
|
case inputBusinessChatLink(flags: Int32, message: String, entities: [Api.MessageEntity]?, title: String?)
|
||||||
|
|
||||||
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
|
switch self {
|
||||||
|
case .inputBusinessChatLink(let flags, let message, let entities, let title):
|
||||||
|
if boxed {
|
||||||
|
buffer.appendInt32(292003751)
|
||||||
|
}
|
||||||
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
|
serializeString(message, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(entities!.count))
|
||||||
|
for item in entities! {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}}
|
||||||
|
if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
|
switch self {
|
||||||
|
case .inputBusinessChatLink(let flags, let message, let entities, let title):
|
||||||
|
return ("inputBusinessChatLink", [("flags", flags as Any), ("message", message as Any), ("entities", entities as Any), ("title", title as Any)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func parse_inputBusinessChatLink(_ reader: BufferReader) -> InputBusinessChatLink? {
|
||||||
|
var _1: Int32?
|
||||||
|
_1 = reader.readInt32()
|
||||||
|
var _2: String?
|
||||||
|
_2 = parseString(reader)
|
||||||
|
var _3: [Api.MessageEntity]?
|
||||||
|
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||||
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||||
|
} }
|
||||||
|
var _4: String?
|
||||||
|
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
|
||||||
|
let _c1 = _1 != nil
|
||||||
|
let _c2 = _2 != nil
|
||||||
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
|
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.InputBusinessChatLink.inputBusinessChatLink(flags: _1!, message: _2!, entities: _3, title: _4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum InputBusinessGreetingMessage: TypeConstructorDescription {
|
enum InputBusinessGreetingMessage: TypeConstructorDescription {
|
||||||
case inputBusinessGreetingMessage(shortcutId: Int32, recipients: Api.InputBusinessRecipients, noActivityDays: Int32)
|
case inputBusinessGreetingMessage(shortcutId: Int32, recipients: Api.InputBusinessRecipients, noActivityDays: Int32)
|
||||||
@ -992,313 +1046,3 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public extension Api {
|
|
||||||
indirect enum InputFileLocation: TypeConstructorDescription {
|
|
||||||
case inputDocumentFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, thumbSize: String)
|
|
||||||
case inputEncryptedFileLocation(id: Int64, accessHash: Int64)
|
|
||||||
case inputFileLocation(volumeId: Int64, localId: Int32, secret: Int64, fileReference: Buffer)
|
|
||||||
case inputGroupCallStream(flags: Int32, call: Api.InputGroupCall, timeMs: Int64, scale: Int32, videoChannel: Int32?, videoQuality: Int32?)
|
|
||||||
case inputPeerPhotoFileLocation(flags: Int32, peer: Api.InputPeer, photoId: Int64)
|
|
||||||
case inputPhotoFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, thumbSize: String)
|
|
||||||
case inputPhotoLegacyFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, volumeId: Int64, localId: Int32, secret: Int64)
|
|
||||||
case inputSecureFileLocation(id: Int64, accessHash: Int64)
|
|
||||||
case inputStickerSetThumb(stickerset: Api.InputStickerSet, thumbVersion: Int32)
|
|
||||||
case inputTakeoutFileLocation
|
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
|
||||||
switch self {
|
|
||||||
case .inputDocumentFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1160743548)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
|
||||||
serializeString(thumbSize, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputEncryptedFileLocation(let id, let accessHash):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-182231723)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputFileLocation(let volumeId, let localId, let secret, let fileReference):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-539317279)
|
|
||||||
}
|
|
||||||
serializeInt64(volumeId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(localId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(secret, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputGroupCallStream(let flags, let call, let timeMs, let scale, let videoChannel, let videoQuality):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(93890858)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
call.serialize(buffer, true)
|
|
||||||
serializeInt64(timeMs, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(scale, buffer: buffer, boxed: false)
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(videoChannel!, buffer: buffer, boxed: false)}
|
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(videoQuality!, buffer: buffer, boxed: false)}
|
|
||||||
break
|
|
||||||
case .inputPeerPhotoFileLocation(let flags, let peer, let photoId):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(925204121)
|
|
||||||
}
|
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
|
||||||
peer.serialize(buffer, true)
|
|
||||||
serializeInt64(photoId, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputPhotoFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(1075322878)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
|
||||||
serializeString(thumbSize, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputPhotoLegacyFileLocation(let id, let accessHash, let fileReference, let volumeId, let localId, let secret):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-667654413)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
serializeBytes(fileReference, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(volumeId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt32(localId, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(secret, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputSecureFileLocation(let id, let accessHash):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-876089816)
|
|
||||||
}
|
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
|
||||||
serializeInt64(accessHash, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputStickerSetThumb(let stickerset, let thumbVersion):
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(-1652231205)
|
|
||||||
}
|
|
||||||
stickerset.serialize(buffer, true)
|
|
||||||
serializeInt32(thumbVersion, buffer: buffer, boxed: false)
|
|
||||||
break
|
|
||||||
case .inputTakeoutFileLocation:
|
|
||||||
if boxed {
|
|
||||||
buffer.appendInt32(700340377)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
|
||||||
switch self {
|
|
||||||
case .inputDocumentFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
|
||||||
return ("inputDocumentFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("thumbSize", thumbSize as Any)])
|
|
||||||
case .inputEncryptedFileLocation(let id, let accessHash):
|
|
||||||
return ("inputEncryptedFileLocation", [("id", id as Any), ("accessHash", accessHash as Any)])
|
|
||||||
case .inputFileLocation(let volumeId, let localId, let secret, let fileReference):
|
|
||||||
return ("inputFileLocation", [("volumeId", volumeId as Any), ("localId", localId as Any), ("secret", secret as Any), ("fileReference", fileReference as Any)])
|
|
||||||
case .inputGroupCallStream(let flags, let call, let timeMs, let scale, let videoChannel, let videoQuality):
|
|
||||||
return ("inputGroupCallStream", [("flags", flags as Any), ("call", call as Any), ("timeMs", timeMs as Any), ("scale", scale as Any), ("videoChannel", videoChannel as Any), ("videoQuality", videoQuality as Any)])
|
|
||||||
case .inputPeerPhotoFileLocation(let flags, let peer, let photoId):
|
|
||||||
return ("inputPeerPhotoFileLocation", [("flags", flags as Any), ("peer", peer as Any), ("photoId", photoId as Any)])
|
|
||||||
case .inputPhotoFileLocation(let id, let accessHash, let fileReference, let thumbSize):
|
|
||||||
return ("inputPhotoFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("thumbSize", thumbSize as Any)])
|
|
||||||
case .inputPhotoLegacyFileLocation(let id, let accessHash, let fileReference, let volumeId, let localId, let secret):
|
|
||||||
return ("inputPhotoLegacyFileLocation", [("id", id as Any), ("accessHash", accessHash as Any), ("fileReference", fileReference as Any), ("volumeId", volumeId as Any), ("localId", localId as Any), ("secret", secret as Any)])
|
|
||||||
case .inputSecureFileLocation(let id, let accessHash):
|
|
||||||
return ("inputSecureFileLocation", [("id", id as Any), ("accessHash", accessHash as Any)])
|
|
||||||
case .inputStickerSetThumb(let stickerset, let thumbVersion):
|
|
||||||
return ("inputStickerSetThumb", [("stickerset", stickerset as Any), ("thumbVersion", thumbVersion as Any)])
|
|
||||||
case .inputTakeoutFileLocation:
|
|
||||||
return ("inputTakeoutFileLocation", [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func parse_inputDocumentFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputFileLocation.inputDocumentFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, thumbSize: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputEncryptedFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputFileLocation.inputEncryptedFileLocation(id: _1!, accessHash: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
var _3: Int64?
|
|
||||||
_3 = reader.readInt64()
|
|
||||||
var _4: Buffer?
|
|
||||||
_4 = parseBytes(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputFileLocation.inputFileLocation(volumeId: _1!, localId: _2!, secret: _3!, fileReference: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputGroupCallStream(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputGroupCall?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
|
|
||||||
}
|
|
||||||
var _3: Int64?
|
|
||||||
_3 = reader.readInt64()
|
|
||||||
var _4: Int32?
|
|
||||||
_4 = reader.readInt32()
|
|
||||||
var _5: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
|
||||||
var _6: Int32?
|
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt32() }
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
|
||||||
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.InputFileLocation.inputGroupCallStream(flags: _1!, call: _2!, timeMs: _3!, scale: _4!, videoChannel: _5, videoQuality: _6)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPeerPhotoFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int32?
|
|
||||||
_1 = reader.readInt32()
|
|
||||||
var _2: Api.InputPeer?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_2 = Api.parse(reader, signature: signature) as? Api.InputPeer
|
|
||||||
}
|
|
||||||
var _3: Int64?
|
|
||||||
_3 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
if _c1 && _c2 && _c3 {
|
|
||||||
return Api.InputFileLocation.inputPeerPhotoFileLocation(flags: _1!, peer: _2!, photoId: _3!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPhotoFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
var _4: String?
|
|
||||||
_4 = parseString(reader)
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 {
|
|
||||||
return Api.InputFileLocation.inputPhotoFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, thumbSize: _4!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputPhotoLegacyFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
var _3: Buffer?
|
|
||||||
_3 = parseBytes(reader)
|
|
||||||
var _4: Int64?
|
|
||||||
_4 = reader.readInt64()
|
|
||||||
var _5: Int32?
|
|
||||||
_5 = reader.readInt32()
|
|
||||||
var _6: Int64?
|
|
||||||
_6 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
let _c3 = _3 != nil
|
|
||||||
let _c4 = _4 != nil
|
|
||||||
let _c5 = _5 != nil
|
|
||||||
let _c6 = _6 != nil
|
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
|
||||||
return Api.InputFileLocation.inputPhotoLegacyFileLocation(id: _1!, accessHash: _2!, fileReference: _3!, volumeId: _4!, localId: _5!, secret: _6!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputSecureFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Int64?
|
|
||||||
_1 = reader.readInt64()
|
|
||||||
var _2: Int64?
|
|
||||||
_2 = reader.readInt64()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputFileLocation.inputSecureFileLocation(id: _1!, accessHash: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputStickerSetThumb(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
var _1: Api.InputStickerSet?
|
|
||||||
if let signature = reader.readInt32() {
|
|
||||||
_1 = Api.parse(reader, signature: signature) as? Api.InputStickerSet
|
|
||||||
}
|
|
||||||
var _2: Int32?
|
|
||||||
_2 = reader.readInt32()
|
|
||||||
let _c1 = _1 != nil
|
|
||||||
let _c2 = _2 != nil
|
|
||||||
if _c1 && _c2 {
|
|
||||||
return Api.InputFileLocation.inputStickerSetThumb(stickerset: _1!, thumbVersion: _2!)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static func parse_inputTakeoutFileLocation(_ reader: BufferReader) -> InputFileLocation? {
|
|
||||||
return Api.InputFileLocation.inputTakeoutFileLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -492,10 +492,6 @@ public final class MediaStreamVideoComponent: Component {
|
|||||||
} else if !self.hadVideo {
|
} else if !self.hadVideo {
|
||||||
aspect = 16.0 / 9
|
aspect = 16.0 / 9
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
aspect = 9.0 / 16.0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if component.isFullscreen || !component.addInset {
|
if component.isFullscreen || !component.addInset {
|
||||||
videoSize = CGSize(width: aspect * 100.0, height: 100.0).aspectFitted(.init(width: availableSize.width - videoInset * 2, height: availableSize.height))
|
videoSize = CGSize(width: aspect * 100.0, height: 100.0).aspectFitted(.init(width: availableSize.width - videoInset * 2, height: availableSize.height))
|
||||||
|
|||||||
@ -930,11 +930,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
if let data = accountContext.currentAppConfiguration.with({ $0 }).data, let value = data["group_call_message_ttl"] as? Double {
|
if let data = accountContext.currentAppConfiguration.with({ $0 }).data, let value = data["group_call_message_ttl"] as? Double {
|
||||||
messageLifetime = Int32(value)
|
messageLifetime = Int32(value)
|
||||||
}
|
}
|
||||||
|
if isStream {
|
||||||
|
messageLifetime = Int32.max
|
||||||
|
}
|
||||||
self.messagesContext = accountContext.engine.messages.groupCallMessages(
|
self.messagesContext = accountContext.engine.messages.groupCallMessages(
|
||||||
callId: initialCall.description.id,
|
callId: initialCall.description.id,
|
||||||
reference: .id(id: initialCall.description.id, accessHash: initialCall.description.accessHash),
|
reference: .id(id: initialCall.description.id, accessHash: initialCall.description.accessHash),
|
||||||
e2eContext: self.e2eContext,
|
e2eContext: self.e2eContext,
|
||||||
messageLifetime: messageLifetime
|
messageLifetime: messageLifetime,
|
||||||
|
isLiveStream: isStream
|
||||||
)
|
)
|
||||||
self.messagesStatePromise.set(self.messagesContext!.state)
|
self.messagesStatePromise.set(self.messagesContext!.state)
|
||||||
}
|
}
|
||||||
@ -4032,9 +4036,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func sendMessage(randomId: Int64? = nil, text: String, entities: [MessageTextEntity]) {
|
public func sendMessage(randomId: Int64? = nil, text: String, entities: [MessageTextEntity], paidStars: Int64?) {
|
||||||
if let messagesContext = self.messagesContext {
|
if let messagesContext = self.messagesContext {
|
||||||
messagesContext.send(fromId: self.joinAsPeerId, randomId: randomId, text: text, entities: entities)
|
messagesContext.send(fromId: self.joinAsPeerId, randomId: randomId, text: text, entities: entities, paidStars: paidStars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1415,7 +1415,7 @@ final class VideoChatScreenComponent: Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let entities = generateTextEntities(text.string, enabledTypes: [.mention, .hashtag], currentEntities: generateChatInputTextEntities(text))
|
let entities = generateTextEntities(text.string, enabledTypes: [.mention, .hashtag], currentEntities: generateChatInputTextEntities(text))
|
||||||
call.sendMessage(randomId: randomId, text: text.string, entities: entities)
|
call.sendMessage(randomId: randomId, text: text.string, entities: entities, paidStars: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
inputPanelView.clearSendMessageInput(updateState: true)
|
inputPanelView.clearSendMessageInput(updateState: true)
|
||||||
@ -3572,6 +3572,7 @@ final class VideoChatScreenComponent: Component {
|
|||||||
},
|
},
|
||||||
timeoutAction: nil,
|
timeoutAction: nil,
|
||||||
forwardAction: nil,
|
forwardAction: nil,
|
||||||
|
paidMessageAction: nil,
|
||||||
moreAction: nil,
|
moreAction: nil,
|
||||||
presentCaptionPositionTooltip: nil,
|
presentCaptionPositionTooltip: nil,
|
||||||
presentVoiceMessagesUnavailableTooltip: nil,
|
presentVoiceMessagesUnavailableTooltip: nil,
|
||||||
@ -3833,7 +3834,7 @@ final class VideoChatScreenComponent: Component {
|
|||||||
guard case let .group(groupCall) = self.currentCall, let call = groupCall as? PresentationGroupCallImpl else {
|
guard case let .group(groupCall) = self.currentCall, let call = groupCall as? PresentationGroupCallImpl else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
call.sendMessage(text: text, entities: entities)
|
call.sendMessage(text: text, entities: entities, paidStars: nil)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -118,7 +118,7 @@ enum AccountStateMutationOperation {
|
|||||||
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
|
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
|
||||||
case UpdateGroupCall(peerId: PeerId?, call: Api.GroupCall)
|
case UpdateGroupCall(peerId: PeerId?, call: Api.GroupCall)
|
||||||
case UpdateGroupCallChainBlocks(id: Int64, accessHash: Int64, subChainId: Int32, blocks: [Data], nextOffset: Int32)
|
case UpdateGroupCallChainBlocks(id: Int64, accessHash: Int64, subChainId: Int32, blocks: [Data], nextOffset: Int32)
|
||||||
case UpdateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities)
|
case UpdateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities, date: Int32, paidMessageStars: Int64?)
|
||||||
case UpdateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data)
|
case UpdateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data)
|
||||||
case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?)
|
case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?)
|
||||||
case UpdateAttachMenuBots
|
case UpdateAttachMenuBots
|
||||||
@ -411,8 +411,8 @@ struct AccountMutableState {
|
|||||||
self.addOperation(.UpdateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks, nextOffset: nextOffset))
|
self.addOperation(.UpdateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks, nextOffset: nextOffset))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func updateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities) {
|
mutating func updateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities, date: Int32, paidMessageStars: Int64?) {
|
||||||
self.addOperation(.UpdateGroupCallMessage(id: id, authorId: authorId, randomId: randomId, text: text))
|
self.addOperation(.UpdateGroupCallMessage(id: id, authorId: authorId, randomId: randomId, text: text, date: date, paidMessageStars: paidMessageStars))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func updateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) {
|
mutating func updateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) {
|
||||||
|
|||||||
@ -202,10 +202,10 @@ public enum CreateForumChannelTopicError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func _internal_createForumChannelTopic(account: Account, peerId: PeerId, title: String, iconColor: Int32, iconFileId: Int64?) -> Signal<Int64, CreateForumChannelTopicError> {
|
func _internal_createForumChannelTopic(account: Account, peerId: PeerId, title: String, iconColor: Int32, iconFileId: Int64?) -> Signal<Int64, CreateForumChannelTopicError> {
|
||||||
return _internal_createForumChannelTopic(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: peerId, title: title, iconColor: iconColor, iconFileId: iconFileId)
|
return _internal_createForumChannelTopic(postbox: account.postbox, network: account.network, stateManager: account.stateManager, accountPeerId: account.peerId, peerId: peerId, title: title, iconColor: iconColor, iconFileId: iconFileId, isTitleMissing: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_createForumChannelTopic(postbox: Postbox, network: Network, stateManager: AccountStateManager, accountPeerId: PeerId, peerId: PeerId, title: String, iconColor: Int32, iconFileId: Int64?) -> Signal<Int64, CreateForumChannelTopicError> {
|
func _internal_createForumChannelTopic(postbox: Postbox, network: Network, stateManager: AccountStateManager, accountPeerId: PeerId, peerId: PeerId, title: String, iconColor: Int32, iconFileId: Int64?, isTitleMissing: Bool) -> Signal<Int64, CreateForumChannelTopicError> {
|
||||||
return postbox.transaction { transaction -> Peer? in
|
return postbox.transaction { transaction -> Peer? in
|
||||||
return transaction.getPeer(peerId)
|
return transaction.getPeer(peerId)
|
||||||
}
|
}
|
||||||
@ -222,6 +222,9 @@ func _internal_createForumChannelTopic(postbox: Postbox, network: Network, state
|
|||||||
flags |= (1 << 3)
|
flags |= (1 << 3)
|
||||||
}
|
}
|
||||||
flags |= (1 << 0)
|
flags |= (1 << 0)
|
||||||
|
if isTitleMissing {
|
||||||
|
flags |= (1 << 4)
|
||||||
|
}
|
||||||
return network.request(Api.functions.messages.createForumTopic(
|
return network.request(Api.functions.messages.createForumTopic(
|
||||||
flags: flags,
|
flags: flags,
|
||||||
peer: inputPeer,
|
peer: inputPeer,
|
||||||
|
|||||||
@ -1683,9 +1683,12 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||||||
if case let .inputGroupCall(id, accessHash) = call {
|
if case let .inputGroupCall(id, accessHash) = call {
|
||||||
updatedState.updateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks.map { $0.makeData() }, nextOffset: nextOffset)
|
updatedState.updateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks.map { $0.makeData() }, nextOffset: nextOffset)
|
||||||
}
|
}
|
||||||
case let .updateGroupCallMessage(_, call, fromId, randomId, message, _):
|
case let .updateGroupCallMessage(call, message):
|
||||||
if case let .inputGroupCall(id, _) = call {
|
if case let .inputGroupCall(id, _) = call {
|
||||||
updatedState.updateGroupCallMessage(id: id, authorId: fromId.peerId, randomId: randomId, text: message)
|
switch message {
|
||||||
|
case let .groupCallMessage(_, fromId, date, randomId, message, paidMessageStars):
|
||||||
|
updatedState.updateGroupCallMessage(id: id, authorId: fromId.peerId, randomId: randomId, text: message, date: date, paidMessageStars: paidMessageStars)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case let .updateGroupCallEncryptedMessage(call, fromId, encryptedMessage):
|
case let .updateGroupCallEncryptedMessage(call, fromId, encryptedMessage):
|
||||||
if case let .inputGroupCall(id, _) = call {
|
if case let .inputGroupCall(id, _) = call {
|
||||||
@ -4879,10 +4882,10 @@ func replayFinalState(
|
|||||||
callId,
|
callId,
|
||||||
.state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version))
|
.state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version))
|
||||||
))
|
))
|
||||||
case let .UpdateGroupCallMessage(callId, authorId, randomId, text):
|
case let .UpdateGroupCallMessage(callId, authorId, randomId, text, date, paidMessageStars):
|
||||||
switch text {
|
switch text {
|
||||||
case let .textWithEntities(text, entities):
|
case let .textWithEntities(text, entities):
|
||||||
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newPlaintextMessage(authorId: authorId, randomId: randomId, text: text, entities: messageTextEntitiesFromApiEntities(entities))))
|
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newPlaintextMessage(authorId: authorId, randomId: randomId, text: text, entities: messageTextEntitiesFromApiEntities(entities), timestamp: date, paidMessageStars: paidMessageStars)))
|
||||||
}
|
}
|
||||||
case let .UpdateGroupCallOpaqueMessage(callId, authorId, data):
|
case let .UpdateGroupCallOpaqueMessage(callId, authorId, data):
|
||||||
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newOpaqueMessage(authorId: authorId, data: data)))
|
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newOpaqueMessage(authorId: authorId, data: data)))
|
||||||
|
|||||||
@ -488,15 +488,21 @@ public final class PendingMessageManager {
|
|||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
strongSelf.newTopicDisposables[messagePeerId] = disposable
|
strongSelf.newTopicDisposables[messagePeerId] = disposable
|
||||||
|
|
||||||
|
var topicName = "New Thread"
|
||||||
|
if !message.text.isEmpty {
|
||||||
|
topicName = String(message.text.prefix(16))
|
||||||
|
}
|
||||||
|
|
||||||
disposable.set(_internal_createForumChannelTopic(
|
disposable.set(_internal_createForumChannelTopic(
|
||||||
postbox: strongSelf.postbox,
|
postbox: strongSelf.postbox,
|
||||||
network: strongSelf.network,
|
network: strongSelf.network,
|
||||||
stateManager: strongSelf.stateManager,
|
stateManager: strongSelf.stateManager,
|
||||||
accountPeerId: strongSelf.accountPeerId,
|
accountPeerId: strongSelf.accountPeerId,
|
||||||
peerId: message.id.peerId,
|
peerId: message.id.peerId,
|
||||||
title: "New Thread",
|
title: topicName,
|
||||||
iconColor: 0,
|
iconColor: 0,
|
||||||
iconFileId: nil
|
iconFileId: nil,
|
||||||
|
isTitleMissing: true
|
||||||
).startStrict(next: { [weak strongSelf] topicId in
|
).startStrict(next: { [weak strongSelf] topicId in
|
||||||
guard let strongSelf else {
|
guard let strongSelf else {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -3460,7 +3460,7 @@ func _internal_refreshInlineGroupCall(account: Account, messageId: MessageId) ->
|
|||||||
|
|
||||||
struct GroupCallMessageUpdate {
|
struct GroupCallMessageUpdate {
|
||||||
enum Update {
|
enum Update {
|
||||||
case newPlaintextMessage(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity])
|
case newPlaintextMessage(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity], timestamp: Int32, paidMessageStars: Int64?)
|
||||||
case newOpaqueMessage(authorId: PeerId, data: Data)
|
case newOpaqueMessage(authorId: PeerId, data: Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3680,14 +3680,16 @@ public final class GroupCallMessagesContext {
|
|||||||
public let entities: [MessageTextEntity]
|
public let entities: [MessageTextEntity]
|
||||||
public let date: Int32
|
public let date: Int32
|
||||||
public let lifetime: Int32
|
public let lifetime: Int32
|
||||||
|
public let paidStars: Int64?
|
||||||
|
|
||||||
public init(id: Int64, author: EnginePeer?, text: String, entities: [MessageTextEntity], date: Int32, lifetime: Int32) {
|
public init(id: Int64, author: EnginePeer?, text: String, entities: [MessageTextEntity], date: Int32, lifetime: Int32, paidStars: Int64?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.author = author
|
self.author = author
|
||||||
self.text = text
|
self.text = text
|
||||||
self.entities = entities
|
self.entities = entities
|
||||||
self.date = date
|
self.date = date
|
||||||
self.lifetime = lifetime
|
self.lifetime = lifetime
|
||||||
|
self.paidStars = paidStars
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
||||||
@ -3712,6 +3714,9 @@ public final class GroupCallMessagesContext {
|
|||||||
if lhs.lifetime != rhs.lifetime {
|
if lhs.lifetime != rhs.lifetime {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.paidStars != rhs.paidStars {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3726,6 +3731,7 @@ public final class GroupCallMessagesContext {
|
|||||||
|
|
||||||
private final class Impl {
|
private final class Impl {
|
||||||
private let messageLifetime: Int32
|
private let messageLifetime: Int32
|
||||||
|
private let isLiveStream: Bool
|
||||||
|
|
||||||
let queue: Queue
|
let queue: Queue
|
||||||
let account: Account
|
let account: Account
|
||||||
@ -3747,13 +3753,14 @@ public final class GroupCallMessagesContext {
|
|||||||
|
|
||||||
private var messageLifeTimer: SwiftSignalKit.Timer?
|
private var messageLifeTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32) {
|
init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32, isLiveStream: Bool) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.account = account
|
self.account = account
|
||||||
self.callId = callId
|
self.callId = callId
|
||||||
self.reference = reference
|
self.reference = reference
|
||||||
self.e2eContext = e2eContext
|
self.e2eContext = e2eContext
|
||||||
self.messageLifetime = messageLifetime
|
self.messageLifetime = messageLifetime
|
||||||
|
self.isLiveStream = isLiveStream
|
||||||
|
|
||||||
self.state = State(messages: [])
|
self.state = State(messages: [])
|
||||||
self.stateValue.set(self.state)
|
self.stateValue.set(self.state)
|
||||||
@ -3764,16 +3771,16 @@ public final class GroupCallMessagesContext {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent())
|
let currentTime = Int32(CFAbsoluteTimeGetCurrent())
|
||||||
var addedMessages: [(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity])] = []
|
var addedMessages: [(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity], timestamp: Int32, paidMessageStars: Int64?)] = []
|
||||||
var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = []
|
var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = []
|
||||||
for update in updates {
|
for update in updates {
|
||||||
if update.callId != self.callId {
|
if update.callId != self.callId {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch update.update {
|
switch update.update {
|
||||||
case let .newPlaintextMessage(authorId, randomId, text, entities):
|
case let .newPlaintextMessage(authorId, randomId, text, entities, timestamp, paidMessageStars):
|
||||||
if authorId != self.account.peerId {
|
if authorId != self.account.peerId {
|
||||||
addedMessages.append((authorId, randomId, text, entities))
|
addedMessages.append((authorId, randomId, text, entities, timestamp, paidMessageStars))
|
||||||
}
|
}
|
||||||
case let .newOpaqueMessage(authorId, data):
|
case let .newOpaqueMessage(authorId, data):
|
||||||
if authorId != self.account.peerId {
|
if authorId != self.account.peerId {
|
||||||
@ -3783,6 +3790,9 @@ public final class GroupCallMessagesContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !addedMessages.isEmpty || !addedOpaqueMessages.isEmpty {
|
if !addedMessages.isEmpty || !addedOpaqueMessages.isEmpty {
|
||||||
|
let messageLifetime = self.messageLifetime
|
||||||
|
let isLiveStream = self.isLiveStream
|
||||||
|
|
||||||
let _ = (self.account.postbox.transaction { transaction -> [Message] in
|
let _ = (self.account.postbox.transaction { transaction -> [Message] in
|
||||||
var messages: [Message] = []
|
var messages: [Message] = []
|
||||||
if let e2eContext = self.e2eContext {
|
if let e2eContext = self.e2eContext {
|
||||||
@ -3814,7 +3824,8 @@ public final class GroupCallMessagesContext {
|
|||||||
text: text,
|
text: text,
|
||||||
entities: entities,
|
entities: entities,
|
||||||
date: currentTime,
|
date: currentTime,
|
||||||
lifetime: self.messageLifetime
|
lifetime: messageLifetime,
|
||||||
|
paidStars: nil
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3822,13 +3833,22 @@ public final class GroupCallMessagesContext {
|
|||||||
if self.processedIds.contains(addedMessage.randomId) {
|
if self.processedIds.contains(addedMessage.randomId) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lifetime: Int32
|
||||||
|
if isLiveStream {
|
||||||
|
lifetime = Int32(GroupCallMessagesContext.getStarAmountParamMapping(value: addedMessage.paidMessageStars ?? 0).period)
|
||||||
|
} else {
|
||||||
|
lifetime = self.messageLifetime
|
||||||
|
}
|
||||||
|
|
||||||
messages.append(Message(
|
messages.append(Message(
|
||||||
id: addedMessage.randomId,
|
id: addedMessage.randomId,
|
||||||
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
|
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
|
||||||
text: addedMessage.text,
|
text: addedMessage.text,
|
||||||
entities: addedMessage.entities,
|
entities: addedMessage.entities,
|
||||||
date: currentTime,
|
date: addedMessage.timestamp,
|
||||||
lifetime: self.messageLifetime
|
lifetime: lifetime,
|
||||||
|
paidStars: addedMessage.paidMessageStars
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3871,7 +3891,7 @@ public final class GroupCallMessagesContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(fromId: EnginePeer.Id, randomId requestedRandomId: Int64?, text: String, entities: [MessageTextEntity]) {
|
func send(fromId: EnginePeer.Id, randomId requestedRandomId: Int64?, text: String, entities: [MessageTextEntity], paidStars: Int64?) {
|
||||||
let _ = (self.account.postbox.transaction { transaction -> Peer? in
|
let _ = (self.account.postbox.transaction { transaction -> Peer? in
|
||||||
return transaction.getPeer(fromId)
|
return transaction.getPeer(fromId)
|
||||||
}
|
}
|
||||||
@ -3888,6 +3908,14 @@ public final class GroupCallMessagesContext {
|
|||||||
} else {
|
} else {
|
||||||
arc4random_buf(&randomId, 8)
|
arc4random_buf(&randomId, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lifetime: Int32
|
||||||
|
if isLiveStream {
|
||||||
|
lifetime = Int32(GroupCallMessagesContext.getStarAmountParamMapping(value: paidStars ?? 0).period)
|
||||||
|
} else {
|
||||||
|
lifetime = self.messageLifetime
|
||||||
|
}
|
||||||
|
|
||||||
var state = self.state
|
var state = self.state
|
||||||
state.messages.append(Message(
|
state.messages.append(Message(
|
||||||
id: randomId,
|
id: randomId,
|
||||||
@ -3895,10 +3923,18 @@ public final class GroupCallMessagesContext {
|
|||||||
text: text,
|
text: text,
|
||||||
entities: entities,
|
entities: entities,
|
||||||
date: currentTime,
|
date: currentTime,
|
||||||
lifetime: self.messageLifetime
|
lifetime: lifetime,
|
||||||
|
paidStars: paidStars
|
||||||
))
|
))
|
||||||
self.state = state
|
self.state = state
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
var paidStars = paidStars
|
||||||
|
if "".isEmpty {
|
||||||
|
paidStars = nil
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
self.processedIds.insert(randomId)
|
self.processedIds.insert(randomId)
|
||||||
|
|
||||||
if let e2eContext = self.e2eContext, let messageData = serializeGroupCallMessage(randomId: randomId, text: text, entities: entities) {
|
if let e2eContext = self.e2eContext, let messageData = serializeGroupCallMessage(randomId: randomId, text: text, entities: entities) {
|
||||||
@ -3921,6 +3957,10 @@ public final class GroupCallMessagesContext {
|
|||||||
} else {
|
} else {
|
||||||
arc4random_buf(&randomId, 8)
|
arc4random_buf(&randomId, 8)
|
||||||
}
|
}
|
||||||
|
var flags: Int32 = 0
|
||||||
|
if paidStars != nil {
|
||||||
|
flags |= 1 << 0
|
||||||
|
}
|
||||||
self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallMessage(
|
self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallMessage(
|
||||||
flags: 0,
|
flags: 0,
|
||||||
call: self.reference.apiInputGroupCall,
|
call: self.reference.apiInputGroupCall,
|
||||||
@ -3929,7 +3969,7 @@ public final class GroupCallMessagesContext {
|
|||||||
text: text,
|
text: text,
|
||||||
entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())
|
entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())
|
||||||
),
|
),
|
||||||
allowPaidStars: nil
|
allowPaidStars: paidStars
|
||||||
)).startStrict())
|
)).startStrict())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -3945,17 +3985,42 @@ public final class GroupCallMessagesContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32) {
|
init(account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32, isLiveStream: Bool) {
|
||||||
let queue = Queue(name: "GroupCallMessagesContext")
|
let queue = Queue(name: "GroupCallMessagesContext")
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||||
return Impl(queue: queue, account: account, callId: callId, reference: reference, e2eContext: e2eContext, messageLifetime: messageLifetime)
|
return Impl(queue: queue, account: account, callId: callId, reference: reference, e2eContext: e2eContext, messageLifetime: messageLifetime, isLiveStream: isLiveStream)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func send(fromId: EnginePeer.Id, randomId: Int64?, text: String, entities: [MessageTextEntity]) {
|
public func send(fromId: EnginePeer.Id, randomId: Int64?, text: String, entities: [MessageTextEntity], paidStars: Int64?) {
|
||||||
self.impl.with { impl in
|
self.impl.with { impl in
|
||||||
impl.send(fromId: fromId, randomId: randomId, text: text, entities: entities)
|
impl.send(fromId: fromId, randomId: randomId, text: text, entities: entities, paidStars: paidStars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func getStarAmountParamMapping(value: Int64) -> (period: Int, maxLength: Int, emojiCount: Int) {
|
||||||
|
if value >= 10000 {
|
||||||
|
return (3600, 400, 20)
|
||||||
|
}
|
||||||
|
if value >= 2000 {
|
||||||
|
return (1800, 280, 10)
|
||||||
|
}
|
||||||
|
if value >= 500 {
|
||||||
|
return (900, 200, 7)
|
||||||
|
}
|
||||||
|
if value >= 250 {
|
||||||
|
return (600, 150, 4)
|
||||||
|
}
|
||||||
|
if value >= 100 {
|
||||||
|
return (300, 110, 3)
|
||||||
|
}
|
||||||
|
if value >= 50 {
|
||||||
|
return (120, 80, 2)
|
||||||
|
}
|
||||||
|
if value >= 10 {
|
||||||
|
return (60, 60, 1)
|
||||||
|
}
|
||||||
|
return (30, 30, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1648,8 +1648,8 @@ public extension TelegramEngine {
|
|||||||
return _internal_refreshGlobalPostSearchState(account: self.account)
|
return _internal_refreshGlobalPostSearchState(account: self.account)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func groupCallMessages(callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32) -> GroupCallMessagesContext {
|
public func groupCallMessages(callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32, isLiveStream: Bool) -> GroupCallMessagesContext {
|
||||||
return GroupCallMessagesContext(account: self.account, callId: callId, reference: reference, e2eContext: e2eContext, messageLifetime: messageLifetime)
|
return GroupCallMessagesContext(account: self.account, callId: callId, reference: reference, e2eContext: e2eContext, messageLifetime: messageLifetime, isLiveStream: isLiveStream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -135,13 +135,16 @@ private final class BalanceComponent: CombinedComponent {
|
|||||||
private final class BadgeComponent: Component {
|
private final class BadgeComponent: Component {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let title: String
|
let title: String
|
||||||
|
let color: UIColor
|
||||||
|
|
||||||
init(
|
init(
|
||||||
theme: PresentationTheme,
|
theme: PresentationTheme,
|
||||||
title: String
|
title: String,
|
||||||
|
color: UIColor
|
||||||
) {
|
) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.title = title
|
self.title = title
|
||||||
|
self.color = color
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: BadgeComponent, rhs: BadgeComponent) -> Bool {
|
static func ==(lhs: BadgeComponent, rhs: BadgeComponent) -> Bool {
|
||||||
@ -151,6 +154,9 @@ private final class BadgeComponent: Component {
|
|||||||
if lhs.title != rhs.title {
|
if lhs.title != rhs.title {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.color != rhs.color {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +248,7 @@ private final class BadgeComponent: Component {
|
|||||||
self.badgeIcon.image = UIImage(bundleImageName: "Premium/SendStarsStarSliderIcon")?.withRenderingMode(.alwaysTemplate)
|
self.badgeIcon.image = UIImage(bundleImageName: "Premium/SendStarsStarSliderIcon")?.withRenderingMode(.alwaysTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previousComponent = self.component
|
||||||
self.component = component
|
self.component = component
|
||||||
self.badgeIcon.tintColor = .white
|
self.badgeIcon.tintColor = .white
|
||||||
|
|
||||||
@ -268,12 +275,12 @@ private final class BadgeComponent: Component {
|
|||||||
let size = badgeSize
|
let size = badgeSize
|
||||||
transition.setFrame(view: self.badgeLabel, frame: CGRect(origin: CGPoint(x: 14.0 + floorToScreenPixels((badgeFullSize.width - badgeLabelSize.width) / 2.0), y: 5.0), size: badgeLabelSize))
|
transition.setFrame(view: self.badgeLabel, frame: CGRect(origin: CGPoint(x: 14.0 + floorToScreenPixels((badgeFullSize.width - badgeLabelSize.width) / 2.0), y: 5.0), size: badgeLabelSize))
|
||||||
|
|
||||||
if self.previousAvailableSize != availableSize {
|
if self.previousAvailableSize != availableSize || previousComponent?.color != component.color {
|
||||||
self.previousAvailableSize = availableSize
|
self.previousAvailableSize = availableSize
|
||||||
|
|
||||||
let activeColors: [UIColor] = [
|
let activeColors: [UIColor] = [
|
||||||
UIColor(rgb: 0xFFAB03),
|
component.color,
|
||||||
UIColor(rgb: 0xFFCB37)
|
component.color
|
||||||
]
|
]
|
||||||
|
|
||||||
var locations: [CGFloat] = []
|
var locations: [CGFloat] = []
|
||||||
@ -421,7 +428,7 @@ private final class PeerBadgeComponent: Component {
|
|||||||
let contentSize = CGSize(width: iconSize.width + titleSpacing + titleSize.width, height: titleSize.height)
|
let contentSize = CGSize(width: iconSize.width + titleSpacing + titleSize.width, height: titleSize.height)
|
||||||
let size = CGSize(width: contentSize.width + sideInset * 2.0, height: contentSize.height + 3.0 * 2.0)
|
let size = CGSize(width: contentSize.width + sideInset * 2.0, height: contentSize.height + 3.0 * 2.0)
|
||||||
|
|
||||||
self.backgroundMaskLayer.backgroundColor = component.theme.list.plainBackgroundColor.cgColor
|
self.backgroundMaskLayer.backgroundColor = component.theme.overallDarkAppearance ? component.theme.list.blocksBackgroundColor.cgColor : component.theme.list.plainBackgroundColor.cgColor
|
||||||
self.backgroundLayer.backgroundColor = UIColor(rgb: 0xFFB10D).cgColor
|
self.backgroundLayer.backgroundColor = UIColor(rgb: 0xFFB10D).cgColor
|
||||||
|
|
||||||
let backgroundFrame = CGRect(origin: CGPoint(), size: size)
|
let backgroundFrame = CGRect(origin: CGPoint(), size: size)
|
||||||
@ -599,17 +606,20 @@ private final class SliderBackgroundComponent: Component {
|
|||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
let value: CGFloat
|
let value: CGFloat
|
||||||
let topCutoff: CGFloat?
|
let topCutoff: CGFloat?
|
||||||
|
let color: UIColor
|
||||||
|
|
||||||
init(
|
init(
|
||||||
theme: PresentationTheme,
|
theme: PresentationTheme,
|
||||||
strings: PresentationStrings,
|
strings: PresentationStrings,
|
||||||
value: CGFloat,
|
value: CGFloat,
|
||||||
topCutoff: CGFloat?
|
topCutoff: CGFloat?,
|
||||||
|
color: UIColor
|
||||||
) {
|
) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.value = value
|
self.value = value
|
||||||
self.topCutoff = topCutoff
|
self.topCutoff = topCutoff
|
||||||
|
self.color = color
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: SliderBackgroundComponent, rhs: SliderBackgroundComponent) -> Bool {
|
static func ==(lhs: SliderBackgroundComponent, rhs: SliderBackgroundComponent) -> Bool {
|
||||||
@ -625,6 +635,9 @@ private final class SliderBackgroundComponent: Component {
|
|||||||
if lhs.topCutoff != rhs.topCutoff {
|
if lhs.topCutoff != rhs.topCutoff {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.color != rhs.color {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +705,7 @@ private final class SliderBackgroundComponent: Component {
|
|||||||
|
|
||||||
func update(component: SliderBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
func update(component: SliderBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
self.sliderBackground.backgroundColor = component.theme.list.itemPrimaryTextColor.withMultipliedAlpha(component.theme.overallDarkAppearance ? 0.2 : 0.07)
|
self.sliderBackground.backgroundColor = component.theme.list.itemPrimaryTextColor.withMultipliedAlpha(component.theme.overallDarkAppearance ? 0.2 : 0.07)
|
||||||
self.sliderForeground.backgroundColor = UIColor(rgb: 0xFFB10D)
|
self.sliderForeground.backgroundColor = component.color
|
||||||
self.topForegroundLine.backgroundColor = component.theme.list.plainBackgroundColor.cgColor
|
self.topForegroundLine.backgroundColor = component.theme.list.plainBackgroundColor.cgColor
|
||||||
self.topBackgroundLine.backgroundColor = component.theme.list.plainBackgroundColor.cgColor
|
self.topBackgroundLine.backgroundColor = component.theme.list.plainBackgroundColor.cgColor
|
||||||
|
|
||||||
@ -1429,6 +1442,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case let .react(reactData):
|
case let .react(reactData):
|
||||||
targetPeerId = reactData.peer.id
|
targetPeerId = reactData.peer.id
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
targetPeerId = liveStreamMessageData.peer.id
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = (context.engine.payments.starsTopUpOptions()
|
let _ = (context.engine.payments.starsTopUpOptions()
|
||||||
@ -1502,6 +1517,11 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
self.currentMyPeer = nil
|
||||||
|
self.amount = Amount(realValue: 50, maxRealValue: liveStreamMessageData.maxAmount, maxSliderValue: 999, isLogarithmic: true)
|
||||||
|
|
||||||
|
self.privacyPeer = .account
|
||||||
}
|
}
|
||||||
|
|
||||||
if let starsContext = component.context.starsContext {
|
if let starsContext = component.context.starsContext {
|
||||||
@ -1559,6 +1579,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case let .react(reactData):
|
case let .react(reactData):
|
||||||
maxAmount = reactData.maxAmount
|
maxAmount = reactData.maxAmount
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
maxAmount = liveStreamMessageData.maxAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
self.amount = self.amount.withSliderValue(value)
|
self.amount = self.amount.withSliderValue(value)
|
||||||
@ -1612,6 +1634,7 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
var topCutoffFraction: CGFloat?
|
var topCutoffFraction: CGFloat?
|
||||||
|
|
||||||
var topCount: Int?
|
var topCount: Int?
|
||||||
|
var sliderColor: UIColor = UIColor(rgb: 0xFFB10D)
|
||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case let .react(reactData):
|
case let .react(reactData):
|
||||||
let topOthersCount: Int? = reactData.topPeers.filter({ !$0.isMy }).max(by: { $0.count < $1.count })?.count
|
let topOthersCount: Int? = reactData.topPeers.filter({ !$0.isMy }).max(by: { $0.count < $1.count })?.count
|
||||||
@ -1638,6 +1661,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
} else {
|
} else {
|
||||||
self.isPastTopCutoff = nil
|
self.isPastTopCutoff = nil
|
||||||
}
|
}
|
||||||
|
case .liveStreamMessage:
|
||||||
|
sliderColor = getLiveStreamStarAmountColorMapping(value: Int64(self.amount.realValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.sliderBackground.update(
|
let _ = self.sliderBackground.update(
|
||||||
@ -1646,7 +1671,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
strings: environment.strings,
|
strings: environment.strings,
|
||||||
value: progressFraction,
|
value: progressFraction,
|
||||||
topCutoff: topCutoffFraction
|
topCutoff: topCutoffFraction,
|
||||||
|
color: sliderColor
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: sliderBackgroundFrame.size
|
containerSize: sliderBackgroundFrame.size
|
||||||
@ -1666,7 +1692,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(BadgeComponent(
|
component: AnyComponent(BadgeComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
title: "\(self.amount.realValue)"
|
title: "\(self.amount.realValue)",
|
||||||
|
color: sliderColor
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 200.0, height: 200.0)
|
containerSize: CGSize(width: 200.0, height: 200.0)
|
||||||
@ -1761,6 +1788,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
transition.setFrame(view: peerSelectorButtonView, frame: peerSelectorButtonFrame)
|
transition.setFrame(view: peerSelectorButtonView, frame: peerSelectorButtonFrame)
|
||||||
peerSelectorButtonView.isHidden = sendAsPeers.count <= 1
|
peerSelectorButtonView.isHidden = sendAsPeers.count <= 1
|
||||||
}
|
}
|
||||||
|
case .liveStreamMessage:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if themeUpdated {
|
if themeUpdated {
|
||||||
@ -1812,6 +1841,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
case let .react(reactData):
|
case let .react(reactData):
|
||||||
let currentMyPeer = self.currentMyPeer ?? reactData.myPeer
|
let currentMyPeer = self.currentMyPeer ?? reactData.myPeer
|
||||||
subtitleText = environment.strings.SendStarReactions_SubtitleFrom(currentMyPeer.compactDisplayTitle).string
|
subtitleText = environment.strings.SendStarReactions_SubtitleFrom(currentMyPeer.compactDisplayTitle).string
|
||||||
|
case .liveStreamMessage:
|
||||||
|
subtitleText = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var subtitleSize: CGSize?
|
var subtitleSize: CGSize?
|
||||||
@ -1830,6 +1861,9 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case .react:
|
case .react:
|
||||||
titleText = environment.strings.SendStarReactions_Title
|
titleText = environment.strings.SendStarReactions_Title
|
||||||
|
case .liveStreamMessage:
|
||||||
|
//TODO:localize
|
||||||
|
titleText = "Highlight and Pin"
|
||||||
}
|
}
|
||||||
|
|
||||||
let titleSize = title.update(
|
let titleSize = title.update(
|
||||||
@ -1877,6 +1911,9 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
} else {
|
} else {
|
||||||
text = environment.strings.SendStarReactions_TextGeneric(reactData.peer.debugDisplayTitle).string
|
text = environment.strings.SendStarReactions_TextGeneric(reactData.peer.debugDisplayTitle).string
|
||||||
}
|
}
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
//TODO:localize
|
||||||
|
text = "Highlight and pin a message\nby adding Stars for **\(liveStreamMessageData.peer.displayTitle(strings: environment.strings, displayOrder: .firstLast))**."
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)
|
let body = MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor)
|
||||||
@ -2242,6 +2279,8 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentHeight += anonymousContentsSize.height + 27.0
|
contentHeight += anonymousContentsSize.height + 27.0
|
||||||
|
case .liveStreamMessage:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
initialContentHeight = contentHeight
|
initialContentHeight = contentHeight
|
||||||
@ -2254,11 +2293,14 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case .react:
|
case .react:
|
||||||
buttonString = environment.strings.SendStarReactions_SendButtonTitle("\(self.amount.realValue)").string
|
buttonString = environment.strings.SendStarReactions_SendButtonTitle("\(self.amount.realValue)").string
|
||||||
|
case .liveStreamMessage:
|
||||||
|
//TODO:localize
|
||||||
|
buttonString = "Add # \(self.amount.realValue)"
|
||||||
}
|
}
|
||||||
let buttonAttributedString = NSMutableAttributedString(string: buttonString, font: Font.semibold(17.0), textColor: .white, paragraphAlignment: .center)
|
let buttonAttributedString = NSMutableAttributedString(string: buttonString, font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
|
||||||
if let range = buttonAttributedString.string.range(of: "#"), let starImage = self.cachedStarImage?.0 {
|
if let range = buttonAttributedString.string.range(of: "#"), let starImage = self.cachedStarImage?.0 {
|
||||||
buttonAttributedString.addAttribute(.attachment, value: starImage, range: NSRange(range, in: buttonAttributedString.string))
|
buttonAttributedString.addAttribute(.attachment, value: starImage, range: NSRange(range, in: buttonAttributedString.string))
|
||||||
buttonAttributedString.addAttribute(.foregroundColor, value: UIColor(rgb: 0xffffff), range: NSRange(range, in: buttonAttributedString.string))
|
buttonAttributedString.addAttribute(.foregroundColor, value: environment.theme.list.itemCheckColors.foregroundColor, range: NSRange(range, in: buttonAttributedString.string))
|
||||||
buttonAttributedString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: buttonAttributedString.string))
|
buttonAttributedString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: buttonAttributedString.string))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2300,6 +2342,9 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
switch component.initialData.subjectInitialData {
|
switch component.initialData.subjectInitialData {
|
||||||
case let .react(reactData):
|
case let .react(reactData):
|
||||||
purchasePurpose = .reactions(peerId: reactData.peer.id, requiredStars: Int64(self.amount.realValue))
|
purchasePurpose = .reactions(peerId: reactData.peer.id, requiredStars: Int64(self.amount.realValue))
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
//TODO:localize
|
||||||
|
purchasePurpose = .reactions(peerId: liveStreamMessageData.peer.id, requiredStars: Int64(self.amount.realValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
let purchaseScreen = component.context.sharedContext.makeStarsPurchaseScreen(context: component.context, starsContext: starsContext, options: options, purpose: purchasePurpose, targetPeerId: nil, completion: { result in
|
let purchaseScreen = component.context.sharedContext.makeStarsPurchaseScreen(context: component.context, starsContext: starsContext, options: options, purpose: purchasePurpose, targetPeerId: nil, completion: { result in
|
||||||
@ -2343,6 +2388,13 @@ private final class ChatSendStarsScreenComponent: Component {
|
|||||||
sourceView: badgeView.badgeIcon
|
sourceView: badgeView.badgeIcon
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
case let .liveStreamMessage(liveStreamMessageData):
|
||||||
|
liveStreamMessageData.completion(
|
||||||
|
Int64(self.amount.realValue),
|
||||||
|
ChatSendStarsScreen.TransitionOut(
|
||||||
|
sourceView: badgeView.badgeIcon
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
self.environment?.controller()?.dismiss()
|
self.environment?.controller()?.dismiss()
|
||||||
}
|
}
|
||||||
@ -2486,7 +2538,20 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class LiveStreamMessage {
|
||||||
|
let peer: EnginePeer
|
||||||
|
let maxAmount: Int
|
||||||
|
let completion: (Int64, ChatSendStarsScreen.TransitionOut) -> Void
|
||||||
|
|
||||||
|
init(peer: EnginePeer, maxAmount: Int, completion: @escaping (Int64, ChatSendStarsScreen.TransitionOut) -> Void) {
|
||||||
|
self.peer = peer
|
||||||
|
self.maxAmount = maxAmount
|
||||||
|
self.completion = completion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case react(React)
|
case react(React)
|
||||||
|
case liveStreamMessage(LiveStreamMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class InitialData {
|
public final class InitialData {
|
||||||
@ -2565,15 +2630,15 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
|
|||||||
private var didPlayAppearAnimation: Bool = false
|
private var didPlayAppearAnimation: Bool = false
|
||||||
private var isDismissed: Bool = false
|
private var isDismissed: Bool = false
|
||||||
|
|
||||||
private var presenceDisposable: Disposable?
|
public init(context: AccountContext, initialData: InitialData, theme: PresentationTheme? = nil) {
|
||||||
|
|
||||||
public init(context: AccountContext, initialData: InitialData) {
|
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
super.init(context: context, component: ChatSendStarsScreenComponent(
|
super.init(context: context, component: ChatSendStarsScreenComponent(
|
||||||
context: context,
|
context: context,
|
||||||
initialData: initialData
|
initialData: initialData
|
||||||
), navigationBarAppearance: .none)
|
), navigationBarAppearance: .none, theme: theme.flatMap {
|
||||||
|
return .custom($0)
|
||||||
|
} ?? .default)
|
||||||
|
|
||||||
self.statusBar.statusBarStyle = .Ignore
|
self.statusBar.statusBarStyle = .Ignore
|
||||||
self.navigationPresentation = .flatModal
|
self.navigationPresentation = .flatModal
|
||||||
@ -2585,7 +2650,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.presenceDisposable?.dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func viewDidAppear(_ animated: Bool) {
|
override public func viewDidAppear(_ animated: Bool) {
|
||||||
@ -2739,6 +2803,45 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func initialDataLiveStreamMessage(context: AccountContext, peerId: EnginePeer.Id, completion: @escaping (Int64, TransitionOut) -> Void) -> Signal<InitialData?, NoError> {
|
||||||
|
let balance: Signal<StarsAmount?, NoError>
|
||||||
|
if let starsContext = context.starsContext {
|
||||||
|
balance = starsContext.state
|
||||||
|
|> map { state in
|
||||||
|
return state?.balance
|
||||||
|
}
|
||||||
|
|> take(1)
|
||||||
|
} else {
|
||||||
|
balance = .single(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxAmount = 10000
|
||||||
|
if let data = context.currentAppConfiguration.with({ $0 }).data, let value = data["stars_live_stream_pin_amount_max"] as? Double {
|
||||||
|
maxAmount = Int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return combineLatest(
|
||||||
|
context.engine.data.get(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
|
||||||
|
),
|
||||||
|
balance
|
||||||
|
)
|
||||||
|
|> map { peer, balance -> InitialData? in
|
||||||
|
guard let peer else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return InitialData(
|
||||||
|
subjectInitialData: .liveStreamMessage(SubjectInitialData.LiveStreamMessage(
|
||||||
|
peer: peer,
|
||||||
|
maxAmount: maxAmount,
|
||||||
|
completion: completion
|
||||||
|
)),
|
||||||
|
balance: balance
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override public func dismiss(completion: (() -> Void)? = nil) {
|
override public func dismiss(completion: (() -> Void)? = nil) {
|
||||||
if !self.isDismissed {
|
if !self.isDismissed {
|
||||||
self.isDismissed = true
|
self.isDismissed = true
|
||||||
@ -3138,3 +3241,25 @@ final class HeaderContextReferenceContentSource: ContextReferenceContentSource {
|
|||||||
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds, actionsPosition: self.actionsOnTop ? .top : .bottom)
|
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds, actionsPosition: self.actionsOnTop ? .top : .bottom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getLiveStreamStarAmountColorMapping(value: Int64) -> UIColor {
|
||||||
|
if value >= 10000 {
|
||||||
|
return UIColor(rgb: 0x7C8695)
|
||||||
|
}
|
||||||
|
if value >= 2000 {
|
||||||
|
return UIColor(rgb: 0xE6514E)
|
||||||
|
}
|
||||||
|
if value >= 500 {
|
||||||
|
return UIColor(rgb: 0xEE7E20)
|
||||||
|
}
|
||||||
|
if value >= 250 {
|
||||||
|
return UIColor(rgb: 0xE4A20A)
|
||||||
|
}
|
||||||
|
if value >= 100 {
|
||||||
|
return UIColor(rgb: 0x5AB03D)
|
||||||
|
}
|
||||||
|
if value >= 50 {
|
||||||
|
return UIColor(rgb: 0x3E9CDF)
|
||||||
|
}
|
||||||
|
return UIColor(rgb: 0x985FDC)
|
||||||
|
}
|
||||||
|
|||||||
@ -261,6 +261,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
|
|||||||
}
|
}
|
||||||
} : nil,
|
} : nil,
|
||||||
forwardAction: nil,
|
forwardAction: nil,
|
||||||
|
paidMessageAction: nil,
|
||||||
moreAction: nil,
|
moreAction: nil,
|
||||||
presentCaptionPositionTooltip: { [weak self] sourceView in
|
presentCaptionPositionTooltip: { [weak self] sourceView in
|
||||||
if let self {
|
if let self {
|
||||||
|
|||||||
@ -1453,6 +1453,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
controller.presentTimeoutSetup(sourceView: view, gesture: gesture)
|
controller.presentTimeoutSetup(sourceView: view, gesture: gesture)
|
||||||
},
|
},
|
||||||
forwardAction: nil,
|
forwardAction: nil,
|
||||||
|
paidMessageAction: nil,
|
||||||
moreAction: nil,
|
moreAction: nil,
|
||||||
presentCaptionPositionTooltip: nil,
|
presentCaptionPositionTooltip: nil,
|
||||||
presentVoiceMessagesUnavailableTooltip: nil,
|
presentVoiceMessagesUnavailableTooltip: nil,
|
||||||
|
|||||||
@ -275,6 +275,7 @@ final class StoryPreviewComponent: Component {
|
|||||||
inputModeAction: nil,
|
inputModeAction: nil,
|
||||||
timeoutAction: nil,
|
timeoutAction: nil,
|
||||||
forwardAction: {},
|
forwardAction: {},
|
||||||
|
paidMessageAction: nil,
|
||||||
moreAction: { _, _ in },
|
moreAction: { _, _ in },
|
||||||
presentCaptionPositionTooltip: nil,
|
presentCaptionPositionTooltip: nil,
|
||||||
presentVoiceMessagesUnavailableTooltip: nil,
|
presentVoiceMessagesUnavailableTooltip: nil,
|
||||||
|
|||||||
@ -261,6 +261,8 @@ public final class MessageInputActionButtonComponent: Component {
|
|||||||
private var backgroundView: GlassBackgroundView?
|
private var backgroundView: GlassBackgroundView?
|
||||||
private let sendIconView: UIImageView
|
private let sendIconView: UIImageView
|
||||||
private var reactionHeartView: UIImageView?
|
private var reactionHeartView: UIImageView?
|
||||||
|
private var starsIconView: UIImageView?
|
||||||
|
private var starsTextView: ComponentView<Empty>?
|
||||||
private var moreButton: MoreHeaderButton?
|
private var moreButton: MoreHeaderButton?
|
||||||
private var animation: ComponentView<Empty>?
|
private var animation: ComponentView<Empty>?
|
||||||
private var reactionIconView: ReactionIconView?
|
private var reactionIconView: ReactionIconView?
|
||||||
@ -684,6 +686,42 @@ public final class MessageInputActionButtonComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if case let .stars(amount) = component.mode {
|
||||||
|
let _ = amount
|
||||||
|
var starsTransition = transition
|
||||||
|
|
||||||
|
let starsIconView: UIImageView
|
||||||
|
if let current = self.starsIconView {
|
||||||
|
starsIconView = current
|
||||||
|
} else {
|
||||||
|
starsTransition = starsTransition.withAnimation(.none)
|
||||||
|
starsIconView = UIImageView()
|
||||||
|
self.starsIconView = starsIconView
|
||||||
|
starsIconView.image = UIImage(bundleImageName: "Premium/Stars/ButtonStar")?.withRenderingMode(.alwaysTemplate)
|
||||||
|
starsIconView.tintColor = .white
|
||||||
|
self.addSubview(starsIconView)
|
||||||
|
|
||||||
|
if !transition.animation.isImmediate {
|
||||||
|
starsIconView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.18)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let image = starsIconView.image {
|
||||||
|
let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - image.size.width) * 0.5), y: floorToScreenPixels((availableSize.height - image.size.height) * 0.5)), size: image.size)
|
||||||
|
starsTransition.setPosition(view: starsIconView, position: iconFrame.center)
|
||||||
|
starsTransition.setBounds(view: starsIconView, bounds: CGRect(origin: CGPoint(), size: iconFrame.size))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let starsIconView = self.starsIconView {
|
||||||
|
self.starsIconView = nil
|
||||||
|
starsIconView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
if let starsTextView = self.starsTextView {
|
||||||
|
self.starsTextView = nil
|
||||||
|
starsTextView.view?.removeFromSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transition.setFrame(view: self.button.view, frame: CGRect(origin: .zero, size: availableSize))
|
transition.setFrame(view: self.button.view, frame: CGRect(origin: .zero, size: availableSize))
|
||||||
transition.setFrame(view: self.containerNode.view, frame: CGRect(origin: .zero, size: availableSize))
|
transition.setFrame(view: self.containerNode.view, frame: CGRect(origin: .zero, size: availableSize))
|
||||||
transition.setFrame(view: self.referenceNode.view, frame: CGRect(origin: .zero, size: availableSize))
|
transition.setFrame(view: self.referenceNode.view, frame: CGRect(origin: .zero, size: availableSize))
|
||||||
|
|||||||
@ -201,6 +201,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
public let inputModeAction: (() -> Void)?
|
public let inputModeAction: (() -> Void)?
|
||||||
public let timeoutAction: ((UIView, ContextGesture?) -> Void)?
|
public let timeoutAction: ((UIView, ContextGesture?) -> Void)?
|
||||||
public let forwardAction: (() -> Void)?
|
public let forwardAction: (() -> Void)?
|
||||||
|
public let paidMessageAction: (() -> Void)?
|
||||||
public let moreAction: ((UIView, ContextGesture?) -> Void)?
|
public let moreAction: ((UIView, ContextGesture?) -> Void)?
|
||||||
public let presentCaptionPositionTooltip: ((UIView) -> Void)?
|
public let presentCaptionPositionTooltip: ((UIView) -> Void)?
|
||||||
public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?
|
public let presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?
|
||||||
@ -260,6 +261,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
inputModeAction: (() -> Void)?,
|
inputModeAction: (() -> Void)?,
|
||||||
timeoutAction: ((UIView, ContextGesture?) -> Void)?,
|
timeoutAction: ((UIView, ContextGesture?) -> Void)?,
|
||||||
forwardAction: (() -> Void)?,
|
forwardAction: (() -> Void)?,
|
||||||
|
paidMessageAction: (() -> Void)?,
|
||||||
moreAction: ((UIView, ContextGesture?) -> Void)?,
|
moreAction: ((UIView, ContextGesture?) -> Void)?,
|
||||||
presentCaptionPositionTooltip: ((UIView) -> Void)?,
|
presentCaptionPositionTooltip: ((UIView) -> Void)?,
|
||||||
presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?,
|
presentVoiceMessagesUnavailableTooltip: ((UIView) -> Void)?,
|
||||||
@ -318,6 +320,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
self.inputModeAction = inputModeAction
|
self.inputModeAction = inputModeAction
|
||||||
self.timeoutAction = timeoutAction
|
self.timeoutAction = timeoutAction
|
||||||
self.forwardAction = forwardAction
|
self.forwardAction = forwardAction
|
||||||
|
self.paidMessageAction = paidMessageAction
|
||||||
self.moreAction = moreAction
|
self.moreAction = moreAction
|
||||||
self.presentCaptionPositionTooltip = presentCaptionPositionTooltip
|
self.presentCaptionPositionTooltip = presentCaptionPositionTooltip
|
||||||
self.presentVoiceMessagesUnavailableTooltip = presentVoiceMessagesUnavailableTooltip
|
self.presentVoiceMessagesUnavailableTooltip = presentVoiceMessagesUnavailableTooltip
|
||||||
@ -501,6 +504,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
private let inputActionButton = ComponentView<Empty>()
|
private let inputActionButton = ComponentView<Empty>()
|
||||||
private let likeButton = ComponentView<Empty>()
|
private let likeButton = ComponentView<Empty>()
|
||||||
private let stickerButton = ComponentView<Empty>()
|
private let stickerButton = ComponentView<Empty>()
|
||||||
|
private var paidMessageButton: ComponentView<Empty>?
|
||||||
private let timeoutButton = ComponentView<Empty>()
|
private let timeoutButton = ComponentView<Empty>()
|
||||||
|
|
||||||
private var mediaRecordingVibrancyContainer: UIView
|
private var mediaRecordingVibrancyContainer: UIView
|
||||||
@ -816,6 +820,11 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
if component.bottomInset <= 32.0 && !component.forceIsEditing && !component.hideKeyboard && !self.textFieldExternalState.isEditing {
|
if component.bottomInset <= 32.0 && !component.forceIsEditing && !component.hideKeyboard && !self.textFieldExternalState.isEditing {
|
||||||
textFieldSideInset += 18.0
|
textFieldSideInset += 18.0
|
||||||
insets.right += 18.0
|
insets.right += 18.0
|
||||||
|
} else {
|
||||||
|
#if DEBUG
|
||||||
|
textFieldSideInset += 8.0
|
||||||
|
insets.right += 8.0
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 40.0 + 8.0)
|
var mediaInsets = UIEdgeInsets(top: insets.top, left: textFieldSideInset, bottom: insets.bottom, right: 40.0 + 8.0)
|
||||||
@ -1078,6 +1087,10 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
} else if isEditing || component.style == .editor || component.style == .media {
|
} else if isEditing || component.style == .editor || component.style == .media {
|
||||||
fieldBackgroundFrame = fieldFrame
|
fieldBackgroundFrame = fieldFrame
|
||||||
} else {
|
} else {
|
||||||
|
#if DEBUG
|
||||||
|
fieldBackgroundFrame = fieldFrame
|
||||||
|
fieldBackgroundFrame.size.width += 16.0
|
||||||
|
#else
|
||||||
if component.forwardAction != nil && component.likeAction != nil {
|
if component.forwardAction != nil && component.likeAction != nil {
|
||||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - insets.right - 49.0, height: textFieldSize.height))
|
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - insets.right - 49.0, height: textFieldSize.height))
|
||||||
} else if component.forwardAction != nil {
|
} else if component.forwardAction != nil {
|
||||||
@ -1085,6 +1098,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
} else {
|
} else {
|
||||||
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - 50.0, height: textFieldSize.height))
|
fieldBackgroundFrame = CGRect(origin: CGPoint(x: mediaInsets.left, y: insets.top), size: CGSize(width: availableSize.width - mediaInsets.left - 50.0, height: textFieldSize.height))
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
let rawFieldBackgroundFrame = fieldBackgroundFrame
|
let rawFieldBackgroundFrame = fieldBackgroundFrame
|
||||||
@ -1103,7 +1117,7 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
self.fieldBackgroundTint.isHidden = true
|
self.fieldBackgroundTint.isHidden = true
|
||||||
}
|
}
|
||||||
if let fieldGlassBackgroundView = self.fieldGlassBackgroundView {
|
if let fieldGlassBackgroundView = self.fieldGlassBackgroundView {
|
||||||
fieldGlassBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: baseFieldHeight * 0.5, isDark: true, tintColor: component.style == .story ? .init(kind: .panel, color: defaultDarkPresentationTheme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) : .init(kind: .custom, color: UIColor(rgb: 0x25272e, alpha: 0.72)), transition: transition)
|
fieldGlassBackgroundView.update(size: fieldBackgroundFrame.size, cornerRadius: baseFieldHeight * 0.5, isDark: true, tintColor: component.style == .story ? .init(kind: .panel, color: defaultDarkPresentationTheme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) : .init(kind: .custom, color: UIColor(rgb: 0x25272e, alpha: 0.72)), isInteractive: true, transition: transition)
|
||||||
transition.setFrame(view: fieldGlassBackgroundView, frame: fieldBackgroundFrame)
|
transition.setFrame(view: fieldGlassBackgroundView, frame: fieldBackgroundFrame)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1552,22 +1566,35 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
if case .story = component.style {
|
if case .story = component.style {
|
||||||
inputActionButtonAvailableSize = CGSize(width: 40.0, height: 40.0)
|
inputActionButtonAvailableSize = CGSize(width: 40.0, height: 40.0)
|
||||||
}
|
}
|
||||||
if hasMediaEditing {
|
|
||||||
inputActionButtonMode = .send
|
if let storyItem = component.storyItem, case .liveStream = storyItem.media {
|
||||||
} else {
|
|
||||||
if self.textFieldExternalState.hasText {
|
if self.textFieldExternalState.hasText {
|
||||||
if let sendPaidMessageStars = component.sendPaidMessageStars, !"".isEmpty {
|
if let sendPaidMessageStars = component.sendPaidMessageStars, !"".isEmpty {
|
||||||
inputActionButtonMode = .stars(sendPaidMessageStars.value)
|
inputActionButtonMode = .stars(sendPaidMessageStars.value)
|
||||||
} else {
|
} else {
|
||||||
inputActionButtonMode = .send
|
inputActionButtonMode = .send
|
||||||
}
|
}
|
||||||
} else if !isEditing && component.forwardAction != nil {
|
|
||||||
inputActionButtonMode = .forward
|
|
||||||
} else {
|
} else {
|
||||||
if component.areVoiceMessagesAvailable {
|
inputActionButtonMode = .stars(123)
|
||||||
inputActionButtonMode = self.currentMediaInputIsVoice ? .voiceInput : .videoInput
|
}
|
||||||
|
} else {
|
||||||
|
if hasMediaEditing {
|
||||||
|
inputActionButtonMode = .send
|
||||||
|
} else {
|
||||||
|
if self.textFieldExternalState.hasText {
|
||||||
|
if let sendPaidMessageStars = component.sendPaidMessageStars, !"".isEmpty {
|
||||||
|
inputActionButtonMode = .stars(sendPaidMessageStars.value)
|
||||||
|
} else {
|
||||||
|
inputActionButtonMode = .send
|
||||||
|
}
|
||||||
|
} else if !isEditing && component.forwardAction != nil {
|
||||||
|
inputActionButtonMode = .forward
|
||||||
} else {
|
} else {
|
||||||
inputActionButtonMode = .unavailableVoiceInput
|
if component.areVoiceMessagesAvailable {
|
||||||
|
inputActionButtonMode = self.currentMediaInputIsVoice ? .voiceInput : .videoInput
|
||||||
|
} else {
|
||||||
|
inputActionButtonMode = .unavailableVoiceInput
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1803,6 +1830,13 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
if isEditing {
|
if isEditing {
|
||||||
inputModeVisible = true
|
inputModeVisible = true
|
||||||
}
|
}
|
||||||
|
var isLiveStream = false
|
||||||
|
if let storyItem = component.storyItem, case .liveStream = storyItem.media {
|
||||||
|
isLiveStream = true
|
||||||
|
}
|
||||||
|
if isLiveStream && component.sendPaidMessageStars == nil {
|
||||||
|
inputModeVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
let animationName: String
|
let animationName: String
|
||||||
var animationPlay = false
|
var animationPlay = false
|
||||||
@ -1900,6 +1934,58 @@ public final class MessageInputPanelComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let _ = component.paidMessageAction {
|
||||||
|
let paidMessageButton: ComponentView<Empty>
|
||||||
|
var paidMessageButtonTransition = transition
|
||||||
|
if let current = self.paidMessageButton {
|
||||||
|
paidMessageButton = current
|
||||||
|
} else {
|
||||||
|
paidMessageButton = ComponentView()
|
||||||
|
self.paidMessageButton = paidMessageButton
|
||||||
|
paidMessageButtonTransition = paidMessageButtonTransition.withAnimation(.none)
|
||||||
|
}
|
||||||
|
|
||||||
|
let paidMessageButtonSize = paidMessageButton.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(Button(
|
||||||
|
content: AnyComponent(BundleIconComponent(
|
||||||
|
name: "Chat/Input/Text/AccessoryIconSuggestPost",
|
||||||
|
tintColor: defaultDarkPresentationTheme.chat.inputPanel.inputControlColor
|
||||||
|
)),
|
||||||
|
action: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.component?.paidMessageAction?()
|
||||||
|
}
|
||||||
|
).minSize(CGSize(width: 32.0, height: 32.0))),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 32.0, height: 32.0)
|
||||||
|
)
|
||||||
|
if let paidMessageButtonView = paidMessageButton.view as? Button.View {
|
||||||
|
if paidMessageButtonView.superview == nil {
|
||||||
|
paidMessageButtonView.alpha = 0.0
|
||||||
|
self.addSubview(paidMessageButtonView)
|
||||||
|
}
|
||||||
|
let paidMessageButtonFrame = CGRect(origin: CGPoint(x: fieldIconNextX - paidMessageButtonSize.width, y: fieldBackgroundFrame.maxY - 4.0 - paidMessageButtonSize.height), size: paidMessageButtonSize)
|
||||||
|
transition.setPosition(view: paidMessageButtonView, position: paidMessageButtonFrame.center)
|
||||||
|
transition.setBounds(view: paidMessageButtonView, bounds: CGRect(origin: CGPoint(), size: paidMessageButtonFrame.size))
|
||||||
|
|
||||||
|
transition.setAlpha(view: paidMessageButtonView, alpha: 1.0)
|
||||||
|
|
||||||
|
fieldIconNextX -= paidMessageButtonSize.width + 2.0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let paidMessageButton = self.paidMessageButton {
|
||||||
|
self.paidMessageButton = nil
|
||||||
|
if let paidMessageButtonView = paidMessageButton.view {
|
||||||
|
transition.setAlpha(view: paidMessageButtonView, alpha: 0.0, completion: { [weak paidMessageButtonView] _ in
|
||||||
|
paidMessageButtonView?.removeFromSuperview()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let accentColor = component.theme.chat.inputPanel.panelControlAccentColor
|
let accentColor = component.theme.chat.inputPanel.panelControlAccentColor
|
||||||
if let timeoutAction = component.timeoutAction, let timeoutValue = component.timeoutValue {
|
if let timeoutAction = component.timeoutAction, let timeoutValue = component.timeoutValue {
|
||||||
let timeoutButtonSize = self.timeoutButton.update(
|
let timeoutButtonSize = self.timeoutButton.update(
|
||||||
|
|||||||
@ -102,6 +102,11 @@ swift_library(
|
|||||||
"//submodules/DirectMediaImageCache",
|
"//submodules/DirectMediaImageCache",
|
||||||
"//submodules/PromptUI",
|
"//submodules/PromptUI",
|
||||||
"//submodules/TelegramCallsUI",
|
"//submodules/TelegramCallsUI",
|
||||||
|
"//submodules/TelegramUI/Components/AsyncListComponent",
|
||||||
|
"//submodules/Components/MultilineTextWithEntitiesComponent",
|
||||||
|
"//submodules/Components/MultilineTextComponent",
|
||||||
|
"//submodules/TelegramUI/Components/Chat/ChatSendStarsScreen",
|
||||||
|
"//submodules/TelegramUI/Components/GlassBackgroundComponent",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
|||||||
@ -68,6 +68,7 @@ public final class StoryContentItem: Equatable {
|
|||||||
public let externalState: ExternalState
|
public let externalState: ExternalState
|
||||||
public let sharedState: SharedState
|
public let sharedState: SharedState
|
||||||
public let theme: PresentationTheme
|
public let theme: PresentationTheme
|
||||||
|
public let containerInsets: UIEdgeInsets
|
||||||
public let presentationProgressUpdated: (Double, Bool, Bool) -> Void
|
public let presentationProgressUpdated: (Double, Bool, Bool) -> Void
|
||||||
public let markAsSeen: (StoryId) -> Void
|
public let markAsSeen: (StoryId) -> Void
|
||||||
|
|
||||||
@ -75,12 +76,14 @@ public final class StoryContentItem: Equatable {
|
|||||||
externalState: ExternalState,
|
externalState: ExternalState,
|
||||||
sharedState: SharedState,
|
sharedState: SharedState,
|
||||||
theme: PresentationTheme,
|
theme: PresentationTheme,
|
||||||
|
containerInsets: UIEdgeInsets,
|
||||||
presentationProgressUpdated: @escaping (Double, Bool, Bool) -> Void,
|
presentationProgressUpdated: @escaping (Double, Bool, Bool) -> Void,
|
||||||
markAsSeen: @escaping (StoryId) -> Void
|
markAsSeen: @escaping (StoryId) -> Void
|
||||||
) {
|
) {
|
||||||
self.externalState = externalState
|
self.externalState = externalState
|
||||||
self.sharedState = sharedState
|
self.sharedState = sharedState
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.containerInsets = containerInsets
|
||||||
self.presentationProgressUpdated = presentationProgressUpdated
|
self.presentationProgressUpdated = presentationProgressUpdated
|
||||||
self.markAsSeen = markAsSeen
|
self.markAsSeen = markAsSeen
|
||||||
}
|
}
|
||||||
@ -95,6 +98,9 @@ public final class StoryContentItem: Equatable {
|
|||||||
if lhs.theme !== rhs.theme {
|
if lhs.theme !== rhs.theme {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.containerInsets != rhs.containerInsets {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,849 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import ComponentFlow
|
||||||
|
import MultilineTextComponent
|
||||||
|
import AccountContext
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramCallsUI
|
||||||
|
import AsyncListComponent
|
||||||
|
import AvatarNode
|
||||||
|
import MultilineTextWithEntitiesComponent
|
||||||
|
import GlassBackgroundComponent
|
||||||
|
import MultilineTextComponent
|
||||||
|
|
||||||
|
private final class MessageItemComponent: Component {
|
||||||
|
let context: AccountContext
|
||||||
|
let strings: PresentationStrings
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let message: GroupCallMessagesContext.Message
|
||||||
|
|
||||||
|
init(context: AccountContext, strings: PresentationStrings, theme: PresentationTheme, message: GroupCallMessagesContext.Message) {
|
||||||
|
self.context = context
|
||||||
|
self.strings = strings
|
||||||
|
self.theme = theme
|
||||||
|
self.message = message
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: MessageItemComponent, rhs: MessageItemComponent) -> Bool {
|
||||||
|
if lhs === rhs {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.strings !== rhs.strings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.message != rhs.message {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final class View: UIView {
|
||||||
|
private let contentContainer: UIView
|
||||||
|
private var avatarNode: AvatarNode?
|
||||||
|
private let text = ComponentView<Empty>()
|
||||||
|
private var backgroundView: UIImageView?
|
||||||
|
|
||||||
|
private var component: MessageItemComponent?
|
||||||
|
private weak var state: EmptyComponentState?
|
||||||
|
private var isUpdating: Bool = false
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
self.contentContainer = UIView()
|
||||||
|
self.contentContainer.transform = CGAffineTransformMakeRotation(-CGFloat.pi)
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.addSubview(self.contentContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
}
|
||||||
|
|
||||||
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if !self.bounds.contains(point) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = super.hitTest(point, with: event) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: MessageItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.isUpdating = true
|
||||||
|
defer {
|
||||||
|
self.isUpdating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
self.component = component
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
let insets = UIEdgeInsets(top: 8.0, left: 20.0, bottom: 8.0, right: 20.0)
|
||||||
|
let avatarSize: CGFloat = 24.0
|
||||||
|
let avatarSpacing: CGFloat = 6.0
|
||||||
|
|
||||||
|
let textString = NSMutableAttributedString()
|
||||||
|
textString.append(NSAttributedString(string: component.message.author?.displayTitle(strings: component.strings, displayOrder: .firstLast) ?? " ", font: Font.semibold(15.0), textColor: UIColor(white: 0.9, alpha: 1.0)))
|
||||||
|
textString.append(NSAttributedString(string: " ", font: Font.semibold(15.0), textColor: UIColor(white: 0.9, alpha: 1.0)))
|
||||||
|
textString.append(NSAttributedString(string: component.message.text, font: Font.regular(15.0), textColor: UIColor(white: 1.0, alpha: 1.0)))
|
||||||
|
|
||||||
|
let textSize = self.text.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(MultilineTextWithEntitiesComponent(
|
||||||
|
context: component.context,
|
||||||
|
animationCache: component.context.animationCache,
|
||||||
|
animationRenderer: component.context.animationRenderer,
|
||||||
|
placeholderColor: .gray,
|
||||||
|
text: .plain(textString),
|
||||||
|
maximumNumberOfLines: 0
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: availableSize.width - insets.left - insets.right - avatarSize - avatarSpacing, height: 100000.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
let size = CGSize(width: availableSize.width, height: insets.top + textSize.height + insets.bottom)
|
||||||
|
|
||||||
|
let avatarFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top - 4.0), size: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
do {
|
||||||
|
let avatarNode: AvatarNode
|
||||||
|
if let current = self.avatarNode {
|
||||||
|
avatarNode = current
|
||||||
|
} else {
|
||||||
|
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 10.0))
|
||||||
|
self.avatarNode = avatarNode
|
||||||
|
self.contentContainer.addSubview(avatarNode.view)
|
||||||
|
}
|
||||||
|
transition.setFrame(view: avatarNode.view, frame: avatarFrame)
|
||||||
|
avatarNode.updateSize(size: avatarFrame.size)
|
||||||
|
if let peer = component.message.author {
|
||||||
|
if peer.smallProfileImage != nil {
|
||||||
|
avatarNode.setPeerV2(context: component.context, theme: component.theme, peer: peer, displayDimensions: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
} else {
|
||||||
|
avatarNode.setPeer(context: component.context, theme: component.theme, peer: peer, displayDimensions: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
avatarNode.setCustomLetters([" "])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let textFrame = CGRect(origin: CGPoint(x: insets.left + avatarSize + avatarSpacing, y: insets.top), size: textSize)
|
||||||
|
if let textView = self.text.view {
|
||||||
|
if textView.superview == nil {
|
||||||
|
textView.layer.anchorPoint = CGPoint()
|
||||||
|
self.contentContainer.addSubview(textView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: textView, position: textFrame.origin)
|
||||||
|
textView.bounds = CGRect(origin: CGPoint(), size: textFrame.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let paidStars = component.message.paidStars {
|
||||||
|
let backgroundView: UIImageView
|
||||||
|
if let current = self.backgroundView {
|
||||||
|
backgroundView = current
|
||||||
|
} else {
|
||||||
|
backgroundView = UIImageView()
|
||||||
|
self.backgroundView = backgroundView
|
||||||
|
self.contentContainer.insertSubview(backgroundView, at: 0)
|
||||||
|
backgroundView.image = generateStretchableFilledCircleImage(diameter: 28.0, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||||
|
}
|
||||||
|
let backgroundFrame = CGRect(origin: CGPoint(x: 16.0, y: 2.0), size: CGSize(width: textFrame.maxX + 8.0 - 16.0, height: textFrame.maxY + 3.0))
|
||||||
|
transition.setFrame(view: backgroundView, frame: backgroundFrame)
|
||||||
|
backgroundView.tintColor = getStarAmountColorMapping(value: paidStars)
|
||||||
|
} else if let backgroundView = self.backgroundView {
|
||||||
|
self.backgroundView = nil
|
||||||
|
backgroundView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentFrame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
transition.setPosition(view: self.contentContainer, position: contentFrame.center)
|
||||||
|
transition.setBounds(view: self.contentContainer, bounds: CGRect(origin: CGPoint(), size: contentFrame.size))
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeView() -> View {
|
||||||
|
return View(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getStarAmountColorMapping(value: Int64) -> UIColor {
|
||||||
|
if value >= 10000 {
|
||||||
|
return UIColor(rgb: 0x7C8695)
|
||||||
|
}
|
||||||
|
if value >= 2000 {
|
||||||
|
return UIColor(rgb: 0xE6514E)
|
||||||
|
}
|
||||||
|
if value >= 500 {
|
||||||
|
return UIColor(rgb: 0xEE7E20)
|
||||||
|
}
|
||||||
|
if value >= 250 {
|
||||||
|
return UIColor(rgb: 0xE4A20A)
|
||||||
|
}
|
||||||
|
if value >= 100 {
|
||||||
|
return UIColor(rgb: 0x5AB03D)
|
||||||
|
}
|
||||||
|
if value >= 50 {
|
||||||
|
return UIColor(rgb: 0x3E9CDF)
|
||||||
|
}
|
||||||
|
return UIColor(rgb: 0x985FDC)
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class PinnedBarMessageComponent: Component {
|
||||||
|
let context: AccountContext
|
||||||
|
let strings: PresentationStrings
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let message: GroupCallMessagesContext.Message
|
||||||
|
|
||||||
|
init(context: AccountContext, strings: PresentationStrings, theme: PresentationTheme, message: GroupCallMessagesContext.Message) {
|
||||||
|
self.context = context
|
||||||
|
self.strings = strings
|
||||||
|
self.theme = theme
|
||||||
|
self.message = message
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: PinnedBarMessageComponent, rhs: PinnedBarMessageComponent) -> Bool {
|
||||||
|
if lhs === rhs {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.strings !== rhs.strings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.message != rhs.message {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final class View: UIView {
|
||||||
|
private let backgroundView: UIImageView
|
||||||
|
private let foregroundClippingView: UIView
|
||||||
|
private let foregroundView: UIImageView
|
||||||
|
|
||||||
|
private var avatarNode: AvatarNode?
|
||||||
|
private let title = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private var component: PinnedBarMessageComponent?
|
||||||
|
private weak var state: EmptyComponentState?
|
||||||
|
private var isUpdating: Bool = false
|
||||||
|
|
||||||
|
private var updateTimer: Foundation.Timer?
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
self.backgroundView = UIImageView()
|
||||||
|
self.foregroundClippingView = UIView()
|
||||||
|
self.foregroundClippingView.clipsToBounds = true
|
||||||
|
self.foregroundView = UIImageView()
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.addSubview(self.backgroundView)
|
||||||
|
|
||||||
|
self.foregroundClippingView.addSubview(self.foregroundView)
|
||||||
|
self.addSubview(self.foregroundClippingView)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.updateTimer?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if !self.bounds.contains(point) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = super.hitTest(point, with: event) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: PinnedBarMessageComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.isUpdating = true
|
||||||
|
defer {
|
||||||
|
self.isUpdating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.updateTimer == nil {
|
||||||
|
self.updateTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 1.0 / 30.0, repeats: true, block: { [weak self] _ in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !self.isUpdating {
|
||||||
|
self.state?.updated(transition: .immediate, isLocal: true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.component = component
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
let itemHeight: CGFloat = 32.0
|
||||||
|
let avatarInset: CGFloat = 4.0
|
||||||
|
let avatarSize: CGFloat = 24.0
|
||||||
|
let avatarSpacing: CGFloat = 6.0
|
||||||
|
let rightInset: CGFloat = 10.0
|
||||||
|
|
||||||
|
let titleSize = self.title.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(string: component.message.author?.displayTitle(strings: component.strings, displayOrder: .firstLast) ?? " ", font: Font.semibold(15.0), textColor: .white))
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 1000.0, height: itemHeight)
|
||||||
|
)
|
||||||
|
|
||||||
|
let size = CGSize(width: avatarInset + avatarSize + avatarSpacing + titleSize.width + rightInset, height: itemHeight)
|
||||||
|
|
||||||
|
if self.backgroundView.image == nil {
|
||||||
|
self.backgroundView.image = generateStretchableFilledCircleImage(diameter: itemHeight, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||||
|
self.foregroundView.image = self.backgroundView.image
|
||||||
|
}
|
||||||
|
|
||||||
|
let baseColor = getStarAmountColorMapping(value: component.message.paidStars ?? 0)
|
||||||
|
self.backgroundView.tintColor = baseColor.withMultipliedBrightnessBy(0.7)
|
||||||
|
self.foregroundView.tintColor = baseColor
|
||||||
|
|
||||||
|
let timestamp = CFAbsoluteTimeGetCurrent()
|
||||||
|
let currentDuration = max(0.0, timestamp - Double(component.message.date))
|
||||||
|
let timeFraction: CGFloat = 1.0 - min(1.0, currentDuration / Double(component.message.lifetime))
|
||||||
|
|
||||||
|
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
|
transition.setFrame(view: self.foregroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
|
transition.setFrame(view: self.foregroundClippingView, frame: CGRect(origin: CGPoint(), size: CGSize(width: floorToScreenPixels(size.width * timeFraction), height: size.height)))
|
||||||
|
|
||||||
|
let avatarFrame = CGRect(origin: CGPoint(x: avatarInset, y: floor((itemHeight - avatarSize) * 0.5)), size: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
do {
|
||||||
|
let avatarNode: AvatarNode
|
||||||
|
if let current = self.avatarNode {
|
||||||
|
avatarNode = current
|
||||||
|
} else {
|
||||||
|
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 10.0))
|
||||||
|
self.avatarNode = avatarNode
|
||||||
|
self.addSubview(avatarNode.view)
|
||||||
|
}
|
||||||
|
transition.setFrame(view: avatarNode.view, frame: avatarFrame)
|
||||||
|
avatarNode.updateSize(size: avatarFrame.size)
|
||||||
|
if let peer = component.message.author {
|
||||||
|
if peer.smallProfileImage != nil {
|
||||||
|
avatarNode.setPeerV2(context: component.context, theme: component.theme, peer: peer, displayDimensions: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
} else {
|
||||||
|
avatarNode.setPeer(context: component.context, theme: component.theme, peer: peer, displayDimensions: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
avatarNode.setCustomLetters([" "])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let titleFrame = CGRect(origin: CGPoint(x: avatarInset + avatarSize + avatarSpacing, y: floor((itemHeight - titleSize.height) * 0.5)), size: titleSize)
|
||||||
|
if let titleView = self.title.view {
|
||||||
|
if titleView.superview == nil {
|
||||||
|
titleView.layer.anchorPoint = CGPoint()
|
||||||
|
self.addSubview(titleView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: titleView, position: titleFrame.origin)
|
||||||
|
titleView.bounds = CGRect(origin: CGPoint(), size: titleFrame.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeView() -> View {
|
||||||
|
return View(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class PinnedBarComponent: Component {
|
||||||
|
let context: AccountContext
|
||||||
|
let strings: PresentationStrings
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let isExpanded: Bool
|
||||||
|
let messages: [GroupCallMessagesContext.Message]
|
||||||
|
let toggleExpandedAction: () -> Void
|
||||||
|
|
||||||
|
init(context: AccountContext, strings: PresentationStrings, theme: PresentationTheme, isExpanded: Bool, messages: [GroupCallMessagesContext.Message], toggleExpandedAction: @escaping () -> Void) {
|
||||||
|
self.context = context
|
||||||
|
self.strings = strings
|
||||||
|
self.theme = theme
|
||||||
|
self.isExpanded = isExpanded
|
||||||
|
self.messages = messages
|
||||||
|
self.toggleExpandedAction = toggleExpandedAction
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: PinnedBarComponent, rhs: PinnedBarComponent) -> Bool {
|
||||||
|
if lhs === rhs {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.strings !== rhs.strings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isExpanded != rhs.isExpanded {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.messages != rhs.messages {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final class View: UIView {
|
||||||
|
private let listContainer: UIView
|
||||||
|
private let listState = AsyncListComponent.ExternalState()
|
||||||
|
private let list = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private let toggleButtonBackground: GlassBackgroundView
|
||||||
|
private let toggleButton: HighlightTrackingButton
|
||||||
|
private let toggleButtonIcon: UIImageView
|
||||||
|
|
||||||
|
private var component: PinnedBarComponent?
|
||||||
|
private weak var state: EmptyComponentState?
|
||||||
|
private var isUpdating: Bool = false
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
self.listContainer = UIView()
|
||||||
|
self.listContainer.clipsToBounds = true
|
||||||
|
|
||||||
|
self.toggleButtonBackground = GlassBackgroundView()
|
||||||
|
self.toggleButton = HighlightTrackingButton()
|
||||||
|
self.toggleButtonIcon = UIImageView()
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.addSubview(self.listContainer)
|
||||||
|
|
||||||
|
self.toggleButtonBackground.contentView.addSubview(self.toggleButtonIcon)
|
||||||
|
self.toggleButtonBackground.contentView.addSubview(self.toggleButton)
|
||||||
|
self.addSubview(self.toggleButtonBackground)
|
||||||
|
|
||||||
|
self.toggleButton.addTarget(self, action: #selector(self.toggleButtonPressed), for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func toggleButtonPressed() {
|
||||||
|
guard let component = self.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
component.toggleExpandedAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if !self.bounds.contains(point) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = super.hitTest(point, with: event) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: PinnedBarComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.isUpdating = true
|
||||||
|
defer {
|
||||||
|
self.isUpdating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
self.component = component
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
let itemHeight: CGFloat = 32.0
|
||||||
|
|
||||||
|
let insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0)
|
||||||
|
|
||||||
|
let size = CGSize(width: availableSize.width, height: insets.top + itemHeight + insets.bottom)
|
||||||
|
|
||||||
|
let toggleButtonFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: CGSize(width: itemHeight, height: itemHeight))
|
||||||
|
transition.setFrame(view: self.toggleButtonBackground, frame: toggleButtonFrame)
|
||||||
|
self.toggleButtonBackground.update(size: toggleButtonFrame.size, cornerRadius: toggleButtonFrame.height * 0.5, isDark: true, tintColor: .init(kind: .panel, color: component.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), isInteractive: true, transition: transition)
|
||||||
|
transition.setFrame(view: self.toggleButton, frame: CGRect(origin: CGPoint(), size: toggleButtonFrame.size))
|
||||||
|
if self.toggleButtonIcon.image == nil {
|
||||||
|
self.toggleButtonIcon.image = UIImage(bundleImageName: "Chat/Context Menu/ReactionExpandArrow")?.withRenderingMode(.alwaysTemplate)
|
||||||
|
self.toggleButtonIcon.tintColor = .white
|
||||||
|
}
|
||||||
|
if let image = self.toggleButtonIcon.image {
|
||||||
|
var iconFrame = image.size.centered(in: CGRect(origin: CGPoint(), size: toggleButtonFrame.size))
|
||||||
|
iconFrame.origin.y += 1.0
|
||||||
|
transition.setTransform(view: self.toggleButtonIcon, transform: CATransform3DMakeRotation((!component.isExpanded) ? CGFloat.pi : 0.0, 0.0, 0.0, 1.0))
|
||||||
|
transition.setPosition(view: self.toggleButtonIcon, position: iconFrame.center)
|
||||||
|
transition.setBounds(view: self.toggleButtonIcon, bounds: CGRect(origin: CGPoint(), size: iconFrame.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
var listItems: [AnyComponentWithIdentity<Empty>] = []
|
||||||
|
for message in component.messages {
|
||||||
|
if let author = message.author {
|
||||||
|
listItems.append(AnyComponentWithIdentity(id: author.id, component: AnyComponent(PinnedBarMessageComponent(
|
||||||
|
context: component.context,
|
||||||
|
strings: component.strings,
|
||||||
|
theme: component.theme,
|
||||||
|
message: message
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let listInsets = UIEdgeInsets(top: 0.0, left: 5.0, bottom: 0.0, right: 5.0 + 20.0)
|
||||||
|
let listFrame = CGRect(origin: CGPoint(x: toggleButtonFrame.maxX, y: 0.0), size: CGSize(width: size.width - toggleButtonFrame.maxX, height: size.height))
|
||||||
|
let _ = self.list.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(AsyncListComponent(
|
||||||
|
externalState: self.listState,
|
||||||
|
items: listItems,
|
||||||
|
itemSetId: AnyHashable(0),
|
||||||
|
direction: .horizontal,
|
||||||
|
insets: listInsets
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: listFrame.size
|
||||||
|
)
|
||||||
|
if let listView = self.list.view {
|
||||||
|
if listView.superview == nil {
|
||||||
|
self.listContainer.addSubview(listView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: listView, position: CGRect(origin: CGPoint(), size: listFrame.size).center)
|
||||||
|
transition.setBounds(view: listView, bounds: CGRect(origin: CGPoint(), size: listFrame.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.setFrame(view: self.listContainer, frame: listFrame)
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeView() -> View {
|
||||||
|
return View(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class StoryContentLiveChatComponent: Component {
|
||||||
|
let context: AccountContext
|
||||||
|
let strings: PresentationStrings
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let call: PresentationGroupCall
|
||||||
|
let insets: UIEdgeInsets
|
||||||
|
|
||||||
|
init(
|
||||||
|
context: AccountContext,
|
||||||
|
strings: PresentationStrings,
|
||||||
|
theme: PresentationTheme,
|
||||||
|
call: PresentationGroupCall,
|
||||||
|
insets: UIEdgeInsets
|
||||||
|
) {
|
||||||
|
self.context = context
|
||||||
|
self.strings = strings
|
||||||
|
self.theme = theme
|
||||||
|
self.call = call
|
||||||
|
self.insets = insets
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: StoryContentLiveChatComponent, rhs: StoryContentLiveChatComponent) -> Bool {
|
||||||
|
if lhs.context !== rhs.context {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.strings !== rhs.strings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.call !== rhs.call {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.insets != rhs.insets {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final class View: UIView {
|
||||||
|
private let listContainer: UIView
|
||||||
|
private let listMaskContainer: UIView
|
||||||
|
private let maskGradientView: UIImageView
|
||||||
|
|
||||||
|
private let pinnedBar = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private let listState = AsyncListComponent.ExternalState()
|
||||||
|
private let list = ComponentView<Empty>()
|
||||||
|
private let listShadowView: UIView
|
||||||
|
|
||||||
|
private var component: StoryContentLiveChatComponent?
|
||||||
|
private weak var state: EmptyComponentState?
|
||||||
|
private var isUpdating: Bool = false
|
||||||
|
|
||||||
|
private var messagesState: GroupCallMessagesContext.State?
|
||||||
|
private var stateDisposable: Disposable?
|
||||||
|
|
||||||
|
private var isChatExpanded: Bool = false
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
self.listContainer = UIView()
|
||||||
|
|
||||||
|
self.listMaskContainer = UIView()
|
||||||
|
self.listContainer.mask = self.listMaskContainer
|
||||||
|
|
||||||
|
self.maskGradientView = UIImageView()
|
||||||
|
do {
|
||||||
|
let height: CGFloat = 40.0
|
||||||
|
let baseGradientAlpha: CGFloat = 1.0
|
||||||
|
let numSteps = 8
|
||||||
|
let firstStep = 0
|
||||||
|
let firstLocation = 0.0
|
||||||
|
let colors = (0 ..< numSteps).map { i -> UIColor in
|
||||||
|
if i < firstStep {
|
||||||
|
return UIColor(white: 1.0, alpha: 1.0)
|
||||||
|
} else {
|
||||||
|
let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1)
|
||||||
|
let value: CGFloat = 1.0 - bezierPoint(0.42, 0.0, 0.58, 1.0, step)
|
||||||
|
return UIColor(white: 1.0, alpha: baseGradientAlpha * value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let locations = (0 ..< numSteps).map { i -> CGFloat in
|
||||||
|
if i < firstStep {
|
||||||
|
return 0.0
|
||||||
|
} else {
|
||||||
|
let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1)
|
||||||
|
return (firstLocation + (1.0 - firstLocation) * step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = generateGradientImage(size: CGSize(width: 8.0, height: height), colors: colors.reversed(), locations: locations.reversed().map { 1.0 - $0 })!
|
||||||
|
self.maskGradientView.image = generateImage(CGSize(width: image.size.width, height: image.size.height * 2.0), rotatedContext: { size, context in
|
||||||
|
UIGraphicsPushContext(context)
|
||||||
|
defer {
|
||||||
|
UIGraphicsPopContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
|
|
||||||
|
image.draw(in: CGRect(origin: CGPoint(), size: image.size))
|
||||||
|
|
||||||
|
let bottomFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - image.size.height), size: image.size)
|
||||||
|
context.translateBy(x: bottomFrame.midX, y: bottomFrame.midY)
|
||||||
|
context.scaleBy(x: 1.0, y: -1.0)
|
||||||
|
context.translateBy(x: -bottomFrame.midX, y: -bottomFrame.midY)
|
||||||
|
|
||||||
|
image.draw(in: bottomFrame)
|
||||||
|
})!.stretchableImage(withLeftCapWidth: 0, topCapHeight: Int(height - 1.0))
|
||||||
|
}
|
||||||
|
self.listMaskContainer.addSubview(self.maskGradientView)
|
||||||
|
|
||||||
|
self.listShadowView = UIView()
|
||||||
|
self.listShadowView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.addSubview(self.listShadowView)
|
||||||
|
self.addSubview(self.listContainer)
|
||||||
|
|
||||||
|
self.isChatExpanded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.stateDisposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if !self.bounds.contains(point) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let result = super.hitTest(point, with: event) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: StoryContentLiveChatComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.isUpdating = true
|
||||||
|
defer {
|
||||||
|
self.isUpdating = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.component?.call !== component.call {
|
||||||
|
self.stateDisposable?.dispose()
|
||||||
|
if let call = component.call as? PresentationGroupCallImpl {
|
||||||
|
self.stateDisposable = (call.messagesState
|
||||||
|
|> deliverOnMainQueue).startStrict(next: { [weak self] state in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var updateTransition: ComponentTransition = .easeInOut(duration: 0.2)
|
||||||
|
if self.messagesState == nil {
|
||||||
|
updateTransition = .immediate
|
||||||
|
}
|
||||||
|
self.messagesState = state
|
||||||
|
if !self.isUpdating {
|
||||||
|
self.state?.updated(transition: updateTransition)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.component = component
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
var listItems: [AnyComponentWithIdentity<Empty>] = []
|
||||||
|
var topMessageByPeerId: [EnginePeer.Id: GroupCallMessagesContext.Message] = [:]
|
||||||
|
if let messagesState = self.messagesState {
|
||||||
|
for message in messagesState.messages.reversed() {
|
||||||
|
listItems.append(AnyComponentWithIdentity(id: message.id, component: AnyComponent(MessageItemComponent(
|
||||||
|
context: component.context,
|
||||||
|
strings: component.strings,
|
||||||
|
theme: component.theme,
|
||||||
|
message: message
|
||||||
|
))))
|
||||||
|
|
||||||
|
if let author = message.author, let paidStars = message.paidStars {
|
||||||
|
if let current = topMessageByPeerId[author.id] {
|
||||||
|
if let currentPaidStars = current.paidStars, currentPaidStars < paidStars {
|
||||||
|
topMessageByPeerId[author.id] = message
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
topMessageByPeerId[author.id] = message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let topMessages: [GroupCallMessagesContext.Message] = topMessageByPeerId.values.sorted(by: { lhs, rhs in
|
||||||
|
let lhsValue = lhs.paidStars ?? 0
|
||||||
|
let rhsValue = rhs.paidStars ?? 0
|
||||||
|
if lhsValue != rhsValue {
|
||||||
|
return lhsValue > rhsValue
|
||||||
|
}
|
||||||
|
return lhs.date > rhs.date
|
||||||
|
})
|
||||||
|
|
||||||
|
let pinnedBarSize = self.pinnedBar.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(PinnedBarComponent(
|
||||||
|
context: component.context,
|
||||||
|
strings: component.strings,
|
||||||
|
theme: component.theme,
|
||||||
|
isExpanded: self.isChatExpanded,
|
||||||
|
messages: topMessages,
|
||||||
|
toggleExpandedAction: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.isChatExpanded = !self.isChatExpanded
|
||||||
|
if !self.isUpdating {
|
||||||
|
self.state?.updated(transition: .spring(duration: 0.4))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
let pinnedBarFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - component.insets.bottom - pinnedBarSize.height), size: pinnedBarSize)
|
||||||
|
if let pinnedBarView = self.pinnedBar.view {
|
||||||
|
if pinnedBarView.superview == nil {
|
||||||
|
self.addSubview(pinnedBarView)
|
||||||
|
}
|
||||||
|
transition.setFrame(view: pinnedBarView, frame: pinnedBarFrame)
|
||||||
|
transition.setAlpha(view: pinnedBarView, alpha: (listItems.isEmpty && topMessages.isEmpty) ? 0.0 : 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var listInsets = UIEdgeInsets(top: availableSize.height - pinnedBarFrame.minY, left: component.insets.right, bottom: component.insets.top, right: component.insets.left)
|
||||||
|
listInsets.top += 4.0
|
||||||
|
let _ = self.list.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(AsyncListComponent(
|
||||||
|
externalState: self.listState,
|
||||||
|
items: listItems,
|
||||||
|
itemSetId: AnyHashable(0),
|
||||||
|
direction: .vertical,
|
||||||
|
insets: listInsets
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
let listFrame = CGRect(origin: CGPoint(), size: availableSize)
|
||||||
|
if let listView = self.list.view {
|
||||||
|
if listView.superview == nil {
|
||||||
|
listView.transform = CGAffineTransformMakeRotation(CGFloat.pi)
|
||||||
|
self.listContainer.addSubview(listView)
|
||||||
|
}
|
||||||
|
transition.setPosition(view: listView, position: listFrame.offsetBy(dx: 0.0, dy: self.isChatExpanded ? 0.0 : listFrame.height).center)
|
||||||
|
transition.setBounds(view: listView, bounds: CGRect(origin: CGPoint(), size: listFrame.size))
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.setFrame(view: self.listContainer, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||||
|
transition.setFrame(view: self.listMaskContainer, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||||
|
|
||||||
|
let maskTopInset: CGFloat = component.insets.top - 20.0
|
||||||
|
let maskBottomInset: CGFloat = availableSize.height - pinnedBarFrame.minY - 26.0
|
||||||
|
transition.setFrame(view: self.maskGradientView, frame: CGRect(origin: CGPoint(x: 0.0, y: maskTopInset), size: CGSize(width: availableSize.width, height: max(0.0, availableSize.height - maskTopInset - maskBottomInset))))
|
||||||
|
|
||||||
|
transition.setFrame(view: self.listShadowView, frame: CGRect(origin: CGPoint(), size: availableSize))
|
||||||
|
|
||||||
|
self.listShadowView.backgroundColor = UIColor(white: 0.0, alpha: 0.3)
|
||||||
|
transition.setAlpha(view: self.listShadowView, alpha: self.isChatExpanded ? 1.0 : 0.0)
|
||||||
|
|
||||||
|
return availableSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeView() -> View {
|
||||||
|
return View(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -93,11 +93,13 @@ final class StoryItemContentComponent: Component {
|
|||||||
private let imageView: StoryItemImageView
|
private let imageView: StoryItemImageView
|
||||||
private let overlaysView: StoryItemOverlaysView
|
private let overlaysView: StoryItemOverlaysView
|
||||||
private var videoNode: UniversalVideoNode?
|
private var videoNode: UniversalVideoNode?
|
||||||
private var mediaStreamCall: PresentationGroupCallImpl?
|
private(set) var mediaStreamCall: PresentationGroupCallImpl?
|
||||||
private var mediaStream: ComponentView<Empty>?
|
private var mediaStream: ComponentView<Empty>?
|
||||||
private var loadingEffectView: StoryItemLoadingEffectView?
|
private var loadingEffectView: StoryItemLoadingEffectView?
|
||||||
private var loadingEffectAppearanceTimer: SwiftSignalKit.Timer?
|
private var loadingEffectAppearanceTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
|
private var liveChat: ComponentView<Empty>?
|
||||||
|
|
||||||
private var mediaAreasEffectView: StoryItemLoadingEffectView?
|
private var mediaAreasEffectView: StoryItemLoadingEffectView?
|
||||||
|
|
||||||
private var currentMessageMedia: EngineMedia?
|
private var currentMessageMedia: EngineMedia?
|
||||||
@ -544,6 +546,11 @@ final class StoryItemContentComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
if let liveChatView = self.liveChat?.view {
|
||||||
|
if let result = liveChatView.hitTest(self.convert(point, to: liveChatView), with: event) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
if let unsupportedButtonView = self.unsupportedButton?.view {
|
if let unsupportedButtonView = self.unsupportedButton?.view {
|
||||||
if let result = unsupportedButtonView.hitTest(self.convert(point, to: unsupportedButtonView), with: event) {
|
if let result = unsupportedButtonView.hitTest(self.convert(point, to: unsupportedButtonView), with: event) {
|
||||||
return result
|
return result
|
||||||
@ -777,6 +784,34 @@ final class StoryItemContentComponent: Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let liveChat: ComponentView<Empty>
|
||||||
|
if let current = self.liveChat {
|
||||||
|
liveChat = current
|
||||||
|
} else {
|
||||||
|
liveChat = ComponentView()
|
||||||
|
self.liveChat = liveChat
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = liveChat.update(
|
||||||
|
transition: mediaStreamTransition,
|
||||||
|
component: AnyComponent(StoryContentLiveChatComponent(
|
||||||
|
context: component.context,
|
||||||
|
strings: component.strings,
|
||||||
|
theme: environment.theme,
|
||||||
|
call: mediaStreamCall,
|
||||||
|
insets: environment.containerInsets
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: availableSize
|
||||||
|
)
|
||||||
|
let liveChatFrame = CGRect(origin: CGPoint(), size: availableSize)
|
||||||
|
if let liveChatView = liveChat.view {
|
||||||
|
if liveChatView.superview == nil {
|
||||||
|
self.insertSubview(liveChatView, aboveSubview: self.imageView)
|
||||||
|
}
|
||||||
|
mediaStreamTransition.setFrame(view: liveChatView, frame: liveChatFrame)
|
||||||
|
}
|
||||||
|
|
||||||
let _ = mediaStream.update(
|
let _ = mediaStream.update(
|
||||||
transition: mediaStreamTransition,
|
transition: mediaStreamTransition,
|
||||||
component: AnyComponent(MediaStreamVideoComponent(
|
component: AnyComponent(MediaStreamVideoComponent(
|
||||||
@ -833,6 +868,11 @@ final class StoryItemContentComponent: Component {
|
|||||||
mediaStream.view?.removeFromSuperview()
|
mediaStream.view?.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let liveChat = self.liveChat {
|
||||||
|
self.liveChat = nil
|
||||||
|
liveChat.view?.removeFromSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
if let messageMedia {
|
if let messageMedia {
|
||||||
var applyState = false
|
var applyState = false
|
||||||
self.imageView.didLoadContents = { [weak self] in
|
self.imageView.didLoadContents = { [weak self] in
|
||||||
|
|||||||
@ -278,6 +278,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
struct ItemLayout {
|
struct ItemLayout {
|
||||||
var containerSize: CGSize
|
var containerSize: CGSize
|
||||||
var contentFrame: CGRect
|
var contentFrame: CGRect
|
||||||
|
var contentInsets: UIEdgeInsets
|
||||||
var contentMinScale: CGFloat
|
var contentMinScale: CGFloat
|
||||||
var contentScaleFraction: CGFloat
|
var contentScaleFraction: CGFloat
|
||||||
var contentOverflowFraction: CGFloat
|
var contentOverflowFraction: CGFloat
|
||||||
@ -292,12 +293,14 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
init(
|
init(
|
||||||
containerSize: CGSize,
|
containerSize: CGSize,
|
||||||
contentFrame: CGRect,
|
contentFrame: CGRect,
|
||||||
|
contentInsets: UIEdgeInsets,
|
||||||
contentMinScale: CGFloat,
|
contentMinScale: CGFloat,
|
||||||
contentScaleFraction: CGFloat,
|
contentScaleFraction: CGFloat,
|
||||||
contentOverflowFraction: CGFloat
|
contentOverflowFraction: CGFloat
|
||||||
) {
|
) {
|
||||||
self.containerSize = containerSize
|
self.containerSize = containerSize
|
||||||
self.contentFrame = contentFrame
|
self.contentFrame = contentFrame
|
||||||
|
self.contentInsets = contentInsets
|
||||||
self.contentMinScale = contentMinScale
|
self.contentMinScale = contentMinScale
|
||||||
self.contentScaleFraction = contentScaleFraction
|
self.contentScaleFraction = contentScaleFraction
|
||||||
self.contentOverflowFraction = contentOverflowFraction
|
self.contentOverflowFraction = contentOverflowFraction
|
||||||
@ -1527,6 +1530,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
externalState: visibleItem.externalState,
|
externalState: visibleItem.externalState,
|
||||||
sharedState: component.storyItemSharedState,
|
sharedState: component.storyItemSharedState,
|
||||||
theme: component.theme,
|
theme: component.theme,
|
||||||
|
containerInsets: itemLayout.contentInsets,
|
||||||
presentationProgressUpdated: { [weak self, weak visibleItem] progress, isBuffering, canSwitch in
|
presentationProgressUpdated: { [weak self, weak visibleItem] progress, isBuffering, canSwitch in
|
||||||
guard let self, let component = self.component else {
|
guard let self, let component = self.component else {
|
||||||
return
|
return
|
||||||
@ -2575,8 +2579,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isFirstTime = self.component == nil
|
let isFirstTime = self.component == nil
|
||||||
|
|
||||||
let startTime1 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
if self.component == nil {
|
if self.component == nil {
|
||||||
self.sendMessageContext.setup(context: component.context, view: self, inputPanelExternalState: self.inputPanelExternalState, keyboardInputData: component.keyboardInputData)
|
self.sendMessageContext.setup(context: component.context, view: self, inputPanelExternalState: self.inputPanelExternalState, keyboardInputData: component.keyboardInputData)
|
||||||
@ -2704,6 +2706,11 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
self.component = component
|
self.component = component
|
||||||
self.state = state
|
self.state = state
|
||||||
|
|
||||||
|
var isLiveStream = false
|
||||||
|
if case .liveStream = component.slice.item.storyItem.media {
|
||||||
|
isLiveStream = true
|
||||||
|
}
|
||||||
|
|
||||||
var dismissPanOffset: CGFloat = 0.0
|
var dismissPanOffset: CGFloat = 0.0
|
||||||
var dismissPanScale: CGFloat = 1.0
|
var dismissPanScale: CGFloat = 1.0
|
||||||
var verticalPanFraction: CGFloat = 0.0
|
var verticalPanFraction: CGFloat = 0.0
|
||||||
@ -2719,8 +2726,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
component.externalState.dismissFraction = dismissFraction
|
component.externalState.dismissFraction = dismissFraction
|
||||||
|
|
||||||
let startTime2 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
transition.setPosition(view: self.componentContainerView, position: CGPoint(x: availableSize.width * 0.5, y: availableSize.height * 0.5 + dismissPanOffset))
|
transition.setPosition(view: self.componentContainerView, position: CGPoint(x: availableSize.width * 0.5, y: availableSize.height * 0.5 + dismissPanOffset))
|
||||||
transition.setBounds(view: self.componentContainerView, bounds: CGRect(origin: CGPoint(), size: availableSize))
|
transition.setBounds(view: self.componentContainerView, bounds: CGRect(origin: CGPoint(), size: availableSize))
|
||||||
transition.setScale(view: self.componentContainerView, scale: dismissPanScale)
|
transition.setScale(view: self.componentContainerView, scale: dismissPanScale)
|
||||||
@ -2732,8 +2737,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
transition.setBounds(view: self.overlayContainerView, bounds: CGRect(origin: CGPoint(), size: availableSize))
|
transition.setBounds(view: self.overlayContainerView, bounds: CGRect(origin: CGPoint(), size: availableSize))
|
||||||
transition.setScale(view: self.overlayContainerView, scale: dismissPanScale)
|
transition.setScale(view: self.overlayContainerView, scale: dismissPanScale)
|
||||||
|
|
||||||
let startTime21 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
var bottomContentInset: CGFloat
|
var bottomContentInset: CGFloat
|
||||||
if !component.safeInsets.bottom.isZero {
|
if !component.safeInsets.bottom.isZero {
|
||||||
bottomContentInset = component.safeInsets.bottom + 1.0
|
bottomContentInset = component.safeInsets.bottom + 1.0
|
||||||
@ -2860,8 +2863,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime22 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
var currentHasFirstResponder = false
|
var currentHasFirstResponder = false
|
||||||
if let reactionContextNode = self.reactionContextNode {
|
if let reactionContextNode = self.reactionContextNode {
|
||||||
if hasFirstResponder(reactionContextNode.view) {
|
if hasFirstResponder(reactionContextNode.view) {
|
||||||
@ -2881,8 +2882,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
var inputPanelSize: CGSize?
|
var inputPanelSize: CGSize?
|
||||||
|
|
||||||
let _ = inputNodeVisible
|
let _ = inputNodeVisible
|
||||||
|
|
||||||
let startTime23 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
if showMessageInputPanel {
|
if showMessageInputPanel {
|
||||||
var haveLikeOptions = false
|
var haveLikeOptions = false
|
||||||
@ -2902,6 +2901,11 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
displayAttachmentAction = false
|
displayAttachmentAction = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var maxInputLength = 4096
|
||||||
|
if isLiveStream {
|
||||||
|
maxInputLength = GroupCallMessagesContext.getStarAmountParamMapping(value: self.sendMessageContext.currentLiveStreamMessageStars?.value ?? 0).maxLength
|
||||||
|
}
|
||||||
|
|
||||||
inputPanelSize = self.inputPanel.update(
|
inputPanelSize = self.inputPanel.update(
|
||||||
transition: inputPanelTransition,
|
transition: inputPanelTransition,
|
||||||
component: AnyComponent(MessageInputPanelComponent(
|
component: AnyComponent(MessageInputPanelComponent(
|
||||||
@ -2911,8 +2915,8 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
strings: component.strings,
|
strings: component.strings,
|
||||||
style: .story,
|
style: .story,
|
||||||
placeholder: inputPlaceholder,
|
placeholder: inputPlaceholder,
|
||||||
sendPaidMessageStars: component.slice.additionalPeerData.sendPaidMessageStars,
|
sendPaidMessageStars: isLiveStream ? self.sendMessageContext.currentLiveStreamMessageStars : component.slice.additionalPeerData.sendPaidMessageStars,
|
||||||
maxLength: 4096,
|
maxLength: maxInputLength,
|
||||||
queryTypes: [.mention, .hashtag, .emoji],
|
queryTypes: [.mention, .hashtag, .emoji],
|
||||||
alwaysDarkWhenHasText: component.metrics.widthClass == .regular,
|
alwaysDarkWhenHasText: component.metrics.widthClass == .regular,
|
||||||
resetInputContents: resetInputContents,
|
resetInputContents: resetInputContents,
|
||||||
@ -3020,7 +3024,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
return MessageInputPanelComponent.MyReaction(reaction: value, file: centerAnimation, animationFileId: animationFileId)
|
return MessageInputPanelComponent.MyReaction(reaction: value, file: centerAnimation, animationFileId: animationFileId)
|
||||||
},
|
},
|
||||||
likeAction: component.slice.effectivePeer.isService ? nil : { [weak self] in
|
likeAction: (component.slice.effectivePeer.isService || isLiveStream) ? nil : { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -3045,12 +3049,18 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
timeoutAction: nil,
|
timeoutAction: nil,
|
||||||
forwardAction: component.slice.item.storyItem.isPublic && !component.slice.item.storyItem.isForwardingDisabled ? { [weak self] in
|
forwardAction: (!isLiveStream && component.slice.item.storyItem.isPublic && !component.slice.item.storyItem.isForwardingDisabled) ? { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.sendMessageContext.performShareAction(view: self)
|
self.sendMessageContext.performShareAction(view: self)
|
||||||
} : nil,
|
} : nil,
|
||||||
|
paidMessageAction: (isLiveStream && self.sendMessageContext.currentLiveStreamMessageStars == nil) ? { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.sendMessageContext.performPaidMessageAction(view: self)
|
||||||
|
} : nil,
|
||||||
moreAction: { [weak self] sourceView, gesture in
|
moreAction: { [weak self] sourceView, gesture in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -3129,8 +3139,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime3 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
var inputPanelInset: CGFloat = component.containerInsets.bottom
|
var inputPanelInset: CGFloat = component.containerInsets.bottom
|
||||||
var inputHeight = component.inputHeight
|
var inputHeight = component.inputHeight
|
||||||
|
|
||||||
@ -3211,14 +3219,18 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
inputPanelIsOverlay = true
|
inputPanelIsOverlay = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inputPanelFrameValue: CGRect?
|
||||||
|
if let inputPanelSize {
|
||||||
|
let inputPanelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - inputPanelSize.width) / 2.0), y: availableSize.height - inputPanelBottomInset - inputPanelSize.height), size: inputPanelSize)
|
||||||
|
inputPanelFrameValue = inputPanelFrame
|
||||||
|
}
|
||||||
|
|
||||||
var minimizedBottomContentHeight: CGFloat = 0.0
|
var minimizedBottomContentHeight: CGFloat = 0.0
|
||||||
var maximizedBottomContentHeight: CGFloat = 0.0
|
var maximizedBottomContentHeight: CGFloat = 0.0
|
||||||
|
|
||||||
let minimizedHeight = max(100.0, availableSize.height - (325.0 + 12.0))
|
let minimizedHeight = max(100.0, availableSize.height - (325.0 + 12.0))
|
||||||
let defaultHeight = 60.0 + component.safeInsets.bottom + 1.0
|
let defaultHeight = 60.0 + component.safeInsets.bottom + 1.0
|
||||||
|
|
||||||
let startTime4 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
var validViewListIds: [StoryId] = []
|
var validViewListIds: [StoryId] = []
|
||||||
|
|
||||||
var displayViewLists = false
|
var displayViewLists = false
|
||||||
@ -3717,8 +3729,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
self.viewLists.removeValue(forKey: id)
|
self.viewLists.removeValue(forKey: id)
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime5 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
let itemSize = CGSize(width: availableSize.width, height: ceil(availableSize.width * 1.77778))
|
let itemSize = CGSize(width: availableSize.width, height: ceil(availableSize.width * 1.77778))
|
||||||
let contentDefaultBottomInset: CGFloat = bottomContentInset
|
let contentDefaultBottomInset: CGFloat = bottomContentInset
|
||||||
|
|
||||||
@ -3751,6 +3761,10 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: component.containerInsets.top - (contentSize.height - contentVisualHeight) * 0.5 - contentBottomInsetOverflow), size: contentSize)
|
let contentFrame = CGRect(origin: CGPoint(x: 0.0, y: component.containerInsets.top - (contentSize.height - contentVisualHeight) * 0.5 - contentBottomInsetOverflow), size: contentSize)
|
||||||
|
var contentInsets = UIEdgeInsets(top: 54.0, left: 0.0, bottom: 0.0, right: 0.0)
|
||||||
|
if let inputPanelFrameValue {
|
||||||
|
contentInsets.bottom = max(0.0, contentFrame.maxY - (inputPanelFrameValue.minY + 8.0))
|
||||||
|
}
|
||||||
|
|
||||||
transition.setFrame(view: self.viewListsContainer, frame: CGRect(origin: CGPoint(x: contentFrame.minX, y: 0.0), size: CGSize(width: contentSize.width, height: availableSize.height)))
|
transition.setFrame(view: self.viewListsContainer, frame: CGRect(origin: CGPoint(x: contentFrame.minX, y: 0.0), size: CGSize(width: contentSize.width, height: availableSize.height)))
|
||||||
let viewListsRadius: CGFloat
|
let viewListsRadius: CGFloat
|
||||||
@ -3766,6 +3780,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
let itemLayout = ItemLayout(
|
let itemLayout = ItemLayout(
|
||||||
containerSize: availableSize,
|
containerSize: availableSize,
|
||||||
contentFrame: contentFrame,
|
contentFrame: contentFrame,
|
||||||
|
contentInsets: contentInsets,
|
||||||
contentMinScale: contentMinScale,
|
contentMinScale: contentMinScale,
|
||||||
contentScaleFraction: contentScaleFraction,
|
contentScaleFraction: contentScaleFraction,
|
||||||
contentOverflowFraction: contentOverflowFraction
|
contentOverflowFraction: contentOverflowFraction
|
||||||
@ -3882,8 +3897,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime6 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
let soundButtonState = isSilentVideo || component.isAudioMuted
|
let soundButtonState = isSilentVideo || component.isAudioMuted
|
||||||
let soundButtonSize = self.soundButton.update(
|
let soundButtonSize = self.soundButton.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
@ -4061,11 +4074,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
|
|
||||||
let focusedItem: StoryContentItem? = component.slice.item
|
let focusedItem: StoryContentItem? = component.slice.item
|
||||||
|
|
||||||
var isLiveStream = false
|
|
||||||
if case .liveStream = component.slice.item.storyItem.media {
|
|
||||||
isLiveStream = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentLeftInfoItem: InfoItem?
|
var currentLeftInfoItem: InfoItem?
|
||||||
if focusedItem != nil {
|
if focusedItem != nil {
|
||||||
let leftInfoComponent = AnyComponent(StoryAvatarInfoComponent(context: component.context, peer: component.slice.effectivePeer, isLiveStream: isLiveStream))
|
let leftInfoComponent = AnyComponent(StoryAvatarInfoComponent(context: component.context, peer: component.slice.effectivePeer, isLiveStream: isLiveStream))
|
||||||
@ -4204,18 +4212,12 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime7 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
let topGradientHeight: CGFloat = 90.0
|
let topGradientHeight: CGFloat = 90.0
|
||||||
let topContentGradientRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentFrame.width, height: topGradientHeight))
|
let topContentGradientRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentFrame.width, height: topGradientHeight))
|
||||||
transition.setPosition(view: self.topContentGradientView, position: topContentGradientRect.center)
|
transition.setPosition(view: self.topContentGradientView, position: topContentGradientRect.center)
|
||||||
transition.setBounds(view: self.topContentGradientView, bounds: CGRect(origin: CGPoint(), size: topContentGradientRect.size))
|
transition.setBounds(view: self.topContentGradientView, bounds: CGRect(origin: CGPoint(), size: topContentGradientRect.size))
|
||||||
|
|
||||||
var inputPanelFrameValue: CGRect?
|
if let inputPanelFrame = inputPanelFrameValue {
|
||||||
if let inputPanelSize {
|
|
||||||
let inputPanelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - inputPanelSize.width) / 2.0), y: availableSize.height - inputPanelBottomInset - inputPanelSize.height), size: inputPanelSize)
|
|
||||||
inputPanelFrameValue = inputPanelFrame
|
|
||||||
|
|
||||||
var inputPanelAlpha: CGFloat = (component.hideUI || self.isEditingStory || component.slice.item.storyItem.isPending) ? 0.0 : 1.0
|
var inputPanelAlpha: CGFloat = (component.hideUI || self.isEditingStory || component.slice.item.storyItem.isPending) ? 0.0 : 1.0
|
||||||
if case .liveStream = component.slice.item.storyItem.media {
|
if case .liveStream = component.slice.item.storyItem.media {
|
||||||
} else if component.slice.effectivePeer.id == component.context.account.peerId {
|
} else if component.slice.effectivePeer.id == component.context.account.peerId {
|
||||||
@ -4462,7 +4464,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
captionItemTransition.setAlpha(view: captionItemView, alpha: captionAlpha)
|
captionItemTransition.setAlpha(view: captionItemView, alpha: captionAlpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let reactionsAnchorRect: CGRect
|
let reactionsAnchorRect: CGRect
|
||||||
|
|
||||||
if self.inputPanelExternalState.isEditing, let inputPanelFrameValue {
|
if self.inputPanelExternalState.isEditing, let inputPanelFrameValue {
|
||||||
@ -4499,6 +4501,9 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
if self.sendMessageContext.currentInputMode != .text {
|
if self.sendMessageContext.currentInputMode != .text {
|
||||||
effectiveDisplayReactions = false
|
effectiveDisplayReactions = false
|
||||||
}
|
}
|
||||||
|
if case .liveStream = component.slice.item.storyItem.media {
|
||||||
|
effectiveDisplayReactions = false
|
||||||
|
}
|
||||||
|
|
||||||
if let reactionContextNode = self.reactionContextNode, self.willDismissReactionContextNode !== reactionContextNode, (reactionContextNode.isReactionSearchActive && !reactionContextNode.isAnimatingOutToReaction && !reactionContextNode.isAnimatingOut) {
|
if let reactionContextNode = self.reactionContextNode, self.willDismissReactionContextNode !== reactionContextNode, (reactionContextNode.isReactionSearchActive && !reactionContextNode.isAnimatingOutToReaction && !reactionContextNode.isAnimatingOut) {
|
||||||
effectiveDisplayReactions = true
|
effectiveDisplayReactions = true
|
||||||
@ -4925,6 +4930,9 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var dimAlpha: CGFloat = (inputPanelIsOverlay || self.inputPanelExternalState.isEditing) ? 1.0 : normalDimAlpha
|
var dimAlpha: CGFloat = (inputPanelIsOverlay || self.inputPanelExternalState.isEditing) ? 1.0 : normalDimAlpha
|
||||||
|
if case .liveStream = component.slice.item.storyItem.media {
|
||||||
|
dimAlpha = normalDimAlpha
|
||||||
|
}
|
||||||
if component.hideUI || self.viewListDisplayState != .hidden || self.isEditingStory {
|
if component.hideUI || self.viewListDisplayState != .hidden || self.isEditingStory {
|
||||||
dimAlpha = 0.0
|
dimAlpha = 0.0
|
||||||
}
|
}
|
||||||
@ -4964,14 +4972,10 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime8 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
self.ignoreScrolling = false
|
self.ignoreScrolling = false
|
||||||
|
|
||||||
self.updateScrolling(transition: itemsTransition)
|
self.updateScrolling(transition: itemsTransition)
|
||||||
|
|
||||||
let startTime9 = CFAbsoluteTimeGetCurrent()
|
|
||||||
|
|
||||||
let navigationStripSideInset: CGFloat = 8.0
|
let navigationStripSideInset: CGFloat = 8.0
|
||||||
let navigationStripTopInset: CGFloat = 8.0
|
let navigationStripTopInset: CGFloat = 8.0
|
||||||
if let focusedItem, let visibleItem = self.visibleItems[focusedItem.id], let index = focusedItem.position {
|
if let focusedItem, let visibleItem = self.visibleItems[focusedItem.id], let index = focusedItem.position {
|
||||||
@ -5051,23 +5055,6 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !"".isEmpty {
|
|
||||||
print("inner update time:\n" +
|
|
||||||
" 1: \((CFAbsoluteTimeGetCurrent() - startTime1) * 1000.0) ms\n" +
|
|
||||||
" 2: \((CFAbsoluteTimeGetCurrent() - startTime2) * 1000.0) ms\n" +
|
|
||||||
" 2.1: \((CFAbsoluteTimeGetCurrent() - startTime21) * 1000.0) ms\n" +
|
|
||||||
" 2.2: \((CFAbsoluteTimeGetCurrent() - startTime22) * 1000.0) ms\n" +
|
|
||||||
" 2.3: \((CFAbsoluteTimeGetCurrent() - startTime23) * 1000.0) ms\n" +
|
|
||||||
" 3: \((CFAbsoluteTimeGetCurrent() - startTime3) * 1000.0) ms\n" +
|
|
||||||
" 4: \((CFAbsoluteTimeGetCurrent() - startTime4) * 1000.0) ms\n" +
|
|
||||||
" 5: \((CFAbsoluteTimeGetCurrent() - startTime5) * 1000.0) ms\n" +
|
|
||||||
" 6: \((CFAbsoluteTimeGetCurrent() - startTime6) * 1000.0) ms\n" +
|
|
||||||
" 7: \((CFAbsoluteTimeGetCurrent() - startTime7) * 1000.0) ms\n" +
|
|
||||||
" 8: \((CFAbsoluteTimeGetCurrent() - startTime8) * 1000.0) ms\n" +
|
|
||||||
" 9: \((CFAbsoluteTimeGetCurrent() - startTime9) * 1000.0) ms\n"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let scheduledStoryUnpinnedUndoOverlay = self.scheduledStoryUnpinnedUndoOverlay {
|
if let scheduledStoryUnpinnedUndoOverlay = self.scheduledStoryUnpinnedUndoOverlay {
|
||||||
self.scheduledStoryUnpinnedUndoOverlay = nil
|
self.scheduledStoryUnpinnedUndoOverlay = nil
|
||||||
if !self.isAnimatingOut && !component.isDismissed {
|
if !self.isAnimatingOut && !component.isDismissed {
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import ReactionSelectionNode
|
|||||||
import StoryQualityUpgradeSheetScreen
|
import StoryQualityUpgradeSheetScreen
|
||||||
import AudioWaveform
|
import AudioWaveform
|
||||||
import ChatMessagePaymentAlertController
|
import ChatMessagePaymentAlertController
|
||||||
|
import ChatSendStarsScreen
|
||||||
|
|
||||||
private var ObjCKey_DeinitWatcher: Int?
|
private var ObjCKey_DeinitWatcher: Int?
|
||||||
|
|
||||||
@ -101,6 +102,8 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
|
|
||||||
var currentSpeechHolder: SpeechSynthesizerHolder?
|
var currentSpeechHolder: SpeechSynthesizerHolder?
|
||||||
|
|
||||||
|
var currentLiveStreamMessageStars: StarsAmount?
|
||||||
|
|
||||||
private(set) var isMediaRecordingLocked: Bool = false
|
private(set) var isMediaRecordingLocked: Bool = false
|
||||||
var wasRecordingDismissed: Bool = false
|
var wasRecordingDismissed: Bool = false
|
||||||
|
|
||||||
@ -581,6 +584,43 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
silentPosting: Bool = false,
|
silentPosting: Bool = false,
|
||||||
scheduleTime: Int32? = nil
|
scheduleTime: Int32? = nil
|
||||||
) {
|
) {
|
||||||
|
guard let component = view.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if case .liveStream = component.slice.item.storyItem.media {
|
||||||
|
if let visibleItem = view.visibleItems[component.slice.item.id], let itemView = visibleItem.view.view as? StoryItemContentComponent.View {
|
||||||
|
if let call = itemView.mediaStreamCall {
|
||||||
|
let focusedItem = component.slice.item
|
||||||
|
guard let peerId = focusedItem.peerId else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let inputPanelView = view.inputPanel.view as? MessageInputPanelComponent.View else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inputPanelView.getSendMessageInput() {
|
||||||
|
case let .text(text):
|
||||||
|
if !text.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||||
|
let entities = generateChatInputTextEntities(text)
|
||||||
|
|
||||||
|
call.sendMessage(text: text.string, entities: entities, paidStars: self.currentLiveStreamMessageStars?.value)
|
||||||
|
|
||||||
|
component.storyItemSharedState.replyDrafts.removeValue(forKey: StoryId(peerId: peerId, id: focusedItem.storyItem.id))
|
||||||
|
inputPanelView.clearSendMessageInput(updateState: true)
|
||||||
|
|
||||||
|
self.currentInputMode = .text
|
||||||
|
self.currentLiveStreamMessageStars = nil
|
||||||
|
view.state?.updated(transition: .spring(duration: 0.3))
|
||||||
|
|
||||||
|
let controller = component.controller() as? StoryContainerScreen
|
||||||
|
controller?.requestLayout(forceUpdate: true, transition: .animated(duration: 0.3, curve: .spring))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
self.performWithPossibleStealthModeConfirmation(view: view, action: { [weak self, weak view] in
|
self.performWithPossibleStealthModeConfirmation(view: view, action: { [weak self, weak view] in
|
||||||
guard let self, let view else {
|
guard let self, let view else {
|
||||||
return
|
return
|
||||||
@ -1201,6 +1241,40 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func performPaidMessageAction(view: StoryItemSetContainerComponent.View) {
|
||||||
|
Task { @MainActor [weak view] in
|
||||||
|
guard let view else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let component = view.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let controller = component.controller() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let focusedItem = component.slice.item
|
||||||
|
guard let peerId = focusedItem.peerId else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let initialData = await ChatSendStarsScreen.initialDataLiveStreamMessage(context: component.context, peerId: peerId, completion: { [weak self, weak view] amount, _ in
|
||||||
|
guard let self, let view else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.currentLiveStreamMessageStars = StarsAmount(value: amount, nanos: 0)
|
||||||
|
view.state?.updated(transition: .spring(duration: 0.4))
|
||||||
|
}).get()
|
||||||
|
if let initialData {
|
||||||
|
controller.push(ChatSendStarsScreen(
|
||||||
|
context: component.context,
|
||||||
|
initialData: initialData,
|
||||||
|
theme: component.theme
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func performShareTextAction(view: StoryItemSetContainerComponent.View, text: String) {
|
func performShareTextAction(view: StoryItemSetContainerComponent.View, text: String) {
|
||||||
guard let component = view.component else {
|
guard let component = view.component else {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -369,9 +369,11 @@ public final class TabBarComponent: Component {
|
|||||||
|
|
||||||
if let nativeTabBar = self.nativeTabBar {
|
if let nativeTabBar = self.nativeTabBar {
|
||||||
if previousComponent?.items.map(\.item.title) != component.items.map(\.item.title) {
|
if previousComponent?.items.map(\.item.title) != component.items.map(\.item.title) {
|
||||||
nativeTabBar.items = (0 ..< component.items.count).map { i in
|
let items: [UITabBarItem] = (0 ..< component.items.count).map { i in
|
||||||
return UITabBarItem(title: component.items[i].item.title, image: nil, tag: i)
|
return UITabBarItem(title: component.items[i].item.title, image: nil, tag: i)
|
||||||
}
|
}
|
||||||
|
//items.append(UITabBarItem(tabBarSystemItem: .search, tag: 100))
|
||||||
|
nativeTabBar.items = items
|
||||||
for (_, itemView) in self.itemViews {
|
for (_, itemView) in self.itemViews {
|
||||||
itemView.view?.removeFromSuperview()
|
itemView.view?.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user