Cherry-pick group call messages

This commit is contained in:
Isaac 2025-09-12 10:56:05 +02:00
parent 3e71e2428b
commit 3e6c432511
11 changed files with 558 additions and 131 deletions

2
MODULE.bazel.lock generated
View File

@ -159,7 +159,7 @@
"moduleExtensions": { "moduleExtensions": {
"@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": { "@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": {
"general": { "general": {
"bzlTransitiveDigest": "xcBTf2+GaloFpg7YEh/Bv+1yAczRkiCt3DGws4K7kSk=", "bzlTransitiveDigest": "RjubjYIojbv0PxTpnoknalV9QzT9asbV7elDuN7m2A4=",
"usagesDigest": "lfcV4HxPD+NLaRIT/v7BtSGFgE7c9xrWU7jDiwBAxzo=", "usagesDigest": "lfcV4HxPD+NLaRIT/v7BtSGFgE7c9xrWU7jDiwBAxzo=",
"recordedFileInputs": {}, "recordedFileInputs": {},
"recordedDirentsInputs": {}, "recordedDirentsInputs": {},

View File

@ -1069,8 +1069,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-761649164] = { return Api.Update.parse_updateChannelMessageForwards($0) } dict[-761649164] = { return Api.Update.parse_updateChannelMessageForwards($0) }
dict[-232346616] = { return Api.Update.parse_updateChannelMessageViews($0) } dict[-232346616] = { return Api.Update.parse_updateChannelMessageViews($0) }
dict[-1738720581] = { return Api.Update.parse_updateChannelParticipant($0) } dict[-1738720581] = { return Api.Update.parse_updateChannelParticipant($0) }
dict[422509539] = { return Api.Update.parse_updateChannelPinnedTopic($0) }
dict[-31881726] = { return Api.Update.parse_updateChannelPinnedTopics($0) }
dict[636691703] = { return Api.Update.parse_updateChannelReadMessagesContents($0) } dict[636691703] = { return Api.Update.parse_updateChannelReadMessagesContents($0) }
dict[277713951] = { return Api.Update.parse_updateChannelTooLong($0) } dict[277713951] = { return Api.Update.parse_updateChannelTooLong($0) }
dict[-1937192669] = { return Api.Update.parse_updateChannelUserTyping($0) } dict[-1937192669] = { return Api.Update.parse_updateChannelUserTyping($0) }
@ -1109,6 +1107,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1747565759] = { return Api.Update.parse_updateGroupCall($0) } dict[-1747565759] = { return Api.Update.parse_updateGroupCall($0) }
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[-1761933248] = { 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) }
@ -1141,6 +1141,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) } dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) }
dict[1538885128] = { return Api.Update.parse_updatePinnedChannelMessages($0) } dict[1538885128] = { return Api.Update.parse_updatePinnedChannelMessages($0) }
dict[-99664734] = { return Api.Update.parse_updatePinnedDialogs($0) } dict[-99664734] = { return Api.Update.parse_updatePinnedDialogs($0) }
dict[1748708434] = { return Api.Update.parse_updatePinnedForumTopic($0) }
dict[-554613808] = { return Api.Update.parse_updatePinnedForumTopics($0) }
dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) } dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) }
dict[1751942566] = { return Api.Update.parse_updatePinnedSavedDialogs($0) } dict[1751942566] = { return Api.Update.parse_updatePinnedSavedDialogs($0) }
dict[-298113238] = { return Api.Update.parse_updatePrivacy($0) } dict[-298113238] = { return Api.Update.parse_updatePrivacy($0) }

View File

@ -569,8 +569,6 @@ public extension Api {
case updateChannelMessageForwards(channelId: Int64, id: Int32, forwards: Int32) case updateChannelMessageForwards(channelId: Int64, id: Int32, forwards: Int32)
case updateChannelMessageViews(channelId: Int64, id: Int32, views: Int32) case updateChannelMessageViews(channelId: Int64, id: Int32, views: Int32)
case updateChannelParticipant(flags: Int32, channelId: Int64, date: Int32, actorId: Int64, userId: Int64, prevParticipant: Api.ChannelParticipant?, newParticipant: Api.ChannelParticipant?, invite: Api.ExportedChatInvite?, qts: Int32) case updateChannelParticipant(flags: Int32, channelId: Int64, date: Int32, actorId: Int64, userId: Int64, prevParticipant: Api.ChannelParticipant?, newParticipant: Api.ChannelParticipant?, invite: Api.ExportedChatInvite?, qts: Int32)
case updateChannelPinnedTopic(flags: Int32, channelId: Int64, topicId: Int32)
case updateChannelPinnedTopics(flags: Int32, channelId: Int64, order: [Int32]?)
case updateChannelReadMessagesContents(flags: Int32, channelId: Int64, topMsgId: Int32?, savedPeerId: Api.Peer?, messages: [Int32]) case updateChannelReadMessagesContents(flags: Int32, channelId: Int64, topMsgId: Int32?, savedPeerId: Api.Peer?, messages: [Int32])
case updateChannelTooLong(flags: Int32, channelId: Int64, pts: Int32?) case updateChannelTooLong(flags: Int32, channelId: Int64, pts: Int32?)
case updateChannelUserTyping(flags: Int32, channelId: Int64, topMsgId: Int32?, fromId: Api.Peer, action: Api.SendMessageAction) case updateChannelUserTyping(flags: Int32, channelId: Int64, topMsgId: Int32?, fromId: Api.Peer, action: Api.SendMessageAction)
@ -609,6 +607,8 @@ public extension Api {
case updateGroupCall(flags: Int32, chatId: Int64?, call: Api.GroupCall) case updateGroupCall(flags: Int32, chatId: Int64?, call: Api.GroupCall)
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 updateGroupCallMessage(call: Api.InputGroupCall, fromId: Api.Peer, message: Api.TextWithEntities)
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)
@ -641,6 +641,8 @@ public extension Api {
case updatePhoneCallSignalingData(phoneCallId: Int64, data: Buffer) case updatePhoneCallSignalingData(phoneCallId: Int64, data: Buffer)
case updatePinnedChannelMessages(flags: Int32, channelId: Int64, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedChannelMessages(flags: Int32, channelId: Int64, messages: [Int32], pts: Int32, ptsCount: Int32)
case updatePinnedDialogs(flags: Int32, folderId: Int32?, order: [Api.DialogPeer]?) case updatePinnedDialogs(flags: Int32, folderId: Int32?, order: [Api.DialogPeer]?)
case updatePinnedForumTopic(flags: Int32, peer: Api.Peer, topicId: Int32)
case updatePinnedForumTopics(flags: Int32, peer: Api.Peer, order: [Int32]?)
case updatePinnedMessages(flags: Int32, peer: Api.Peer, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedMessages(flags: Int32, peer: Api.Peer, messages: [Int32], pts: Int32, ptsCount: Int32)
case updatePinnedSavedDialogs(flags: Int32, order: [Api.DialogPeer]?) case updatePinnedSavedDialogs(flags: Int32, order: [Api.DialogPeer]?)
case updatePrivacy(key: Api.PrivacyKey, rules: [Api.PrivacyRule]) case updatePrivacy(key: Api.PrivacyKey, rules: [Api.PrivacyRule])
@ -959,26 +961,6 @@ public extension Api {
if Int(flags) & Int(1 << 2) != 0 {invite!.serialize(buffer, true)} if Int(flags) & Int(1 << 2) != 0 {invite!.serialize(buffer, true)}
serializeInt32(qts, buffer: buffer, boxed: false) serializeInt32(qts, buffer: buffer, boxed: false)
break break
case .updateChannelPinnedTopic(let flags, let channelId, let topicId):
if boxed {
buffer.appendInt32(422509539)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(channelId, buffer: buffer, boxed: false)
serializeInt32(topicId, buffer: buffer, boxed: false)
break
case .updateChannelPinnedTopics(let flags, let channelId, let order):
if boxed {
buffer.appendInt32(-31881726)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(channelId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order!.count))
for item in order! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
break
case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let savedPeerId, let messages): case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let savedPeerId, let messages):
if boxed { if boxed {
buffer.appendInt32(636691703) buffer.appendInt32(636691703)
@ -1317,6 +1299,22 @@ public extension Api {
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
params.serialize(buffer, true) params.serialize(buffer, true)
break break
case .updateGroupCallEncryptedMessage(let call, let fromId, let encryptedMessage):
if boxed {
buffer.appendInt32(-917002394)
}
call.serialize(buffer, true)
fromId.serialize(buffer, true)
serializeBytes(encryptedMessage, buffer: buffer, boxed: false)
break
case .updateGroupCallMessage(let call, let fromId, let message):
if boxed {
buffer.appendInt32(-1761933248)
}
call.serialize(buffer, true)
fromId.serialize(buffer, true)
message.serialize(buffer, true)
break
case .updateGroupCallParticipants(let call, let participants, let version): case .updateGroupCallParticipants(let call, let participants, let version):
if boxed { if boxed {
buffer.appendInt32(-219423922) buffer.appendInt32(-219423922)
@ -1589,6 +1587,26 @@ public extension Api {
item.serialize(buffer, true) item.serialize(buffer, true)
}} }}
break break
case .updatePinnedForumTopic(let flags, let peer, let topicId):
if boxed {
buffer.appendInt32(1748708434)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(topicId, buffer: buffer, boxed: false)
break
case .updatePinnedForumTopics(let flags, let peer, let order):
if boxed {
buffer.appendInt32(-554613808)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order!.count))
for item in order! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
break
case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount): case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount):
if boxed { if boxed {
buffer.appendInt32(-309990731) buffer.appendInt32(-309990731)
@ -2021,10 +2039,6 @@ public extension Api {
return ("updateChannelMessageViews", [("channelId", channelId as Any), ("id", id as Any), ("views", views as Any)]) return ("updateChannelMessageViews", [("channelId", channelId as Any), ("id", id as Any), ("views", views as Any)])
case .updateChannelParticipant(let flags, let channelId, let date, let actorId, let userId, let prevParticipant, let newParticipant, let invite, let qts): case .updateChannelParticipant(let flags, let channelId, let date, let actorId, let userId, let prevParticipant, let newParticipant, let invite, let qts):
return ("updateChannelParticipant", [("flags", flags as Any), ("channelId", channelId as Any), ("date", date as Any), ("actorId", actorId as Any), ("userId", userId as Any), ("prevParticipant", prevParticipant as Any), ("newParticipant", newParticipant as Any), ("invite", invite as Any), ("qts", qts as Any)]) return ("updateChannelParticipant", [("flags", flags as Any), ("channelId", channelId as Any), ("date", date as Any), ("actorId", actorId as Any), ("userId", userId as Any), ("prevParticipant", prevParticipant as Any), ("newParticipant", newParticipant as Any), ("invite", invite as Any), ("qts", qts as Any)])
case .updateChannelPinnedTopic(let flags, let channelId, let topicId):
return ("updateChannelPinnedTopic", [("flags", flags as Any), ("channelId", channelId as Any), ("topicId", topicId as Any)])
case .updateChannelPinnedTopics(let flags, let channelId, let order):
return ("updateChannelPinnedTopics", [("flags", flags as Any), ("channelId", channelId as Any), ("order", order as Any)])
case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let savedPeerId, let messages): case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let savedPeerId, let messages):
return ("updateChannelReadMessagesContents", [("flags", flags as Any), ("channelId", channelId as Any), ("topMsgId", topMsgId as Any), ("savedPeerId", savedPeerId as Any), ("messages", messages as Any)]) return ("updateChannelReadMessagesContents", [("flags", flags as Any), ("channelId", channelId as Any), ("topMsgId", topMsgId as Any), ("savedPeerId", savedPeerId as Any), ("messages", messages as Any)])
case .updateChannelTooLong(let flags, let channelId, let pts): case .updateChannelTooLong(let flags, let channelId, let pts):
@ -2101,6 +2115,10 @@ public extension Api {
return ("updateGroupCallChainBlocks", [("call", call as Any), ("subChainId", subChainId as Any), ("blocks", blocks as Any), ("nextOffset", nextOffset as Any)]) return ("updateGroupCallChainBlocks", [("call", call as Any), ("subChainId", subChainId as Any), ("blocks", blocks as Any), ("nextOffset", nextOffset as Any)])
case .updateGroupCallConnection(let flags, let params): case .updateGroupCallConnection(let flags, let params):
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):
return ("updateGroupCallEncryptedMessage", [("call", call as Any), ("fromId", fromId as Any), ("encryptedMessage", encryptedMessage as Any)])
case .updateGroupCallMessage(let call, let fromId, let message):
return ("updateGroupCallMessage", [("call", call as Any), ("fromId", fromId 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):
@ -2165,6 +2183,10 @@ public extension Api {
return ("updatePinnedChannelMessages", [("flags", flags as Any), ("channelId", channelId as Any), ("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)]) return ("updatePinnedChannelMessages", [("flags", flags as Any), ("channelId", channelId as Any), ("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)])
case .updatePinnedDialogs(let flags, let folderId, let order): case .updatePinnedDialogs(let flags, let folderId, let order):
return ("updatePinnedDialogs", [("flags", flags as Any), ("folderId", folderId as Any), ("order", order as Any)]) return ("updatePinnedDialogs", [("flags", flags as Any), ("folderId", folderId as Any), ("order", order as Any)])
case .updatePinnedForumTopic(let flags, let peer, let topicId):
return ("updatePinnedForumTopic", [("flags", flags as Any), ("peer", peer as Any), ("topicId", topicId as Any)])
case .updatePinnedForumTopics(let flags, let peer, let order):
return ("updatePinnedForumTopics", [("flags", flags as Any), ("peer", peer as Any), ("order", order as Any)])
case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount): case .updatePinnedMessages(let flags, let peer, let messages, let pts, let ptsCount):
return ("updatePinnedMessages", [("flags", flags as Any), ("peer", peer as Any), ("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)]) return ("updatePinnedMessages", [("flags", flags as Any), ("peer", peer as Any), ("messages", messages as Any), ("pts", pts as Any), ("ptsCount", ptsCount as Any)])
case .updatePinnedSavedDialogs(let flags, let order): case .updatePinnedSavedDialogs(let flags, let order):
@ -2872,42 +2894,6 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_updateChannelPinnedTopic(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
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.Update.updateChannelPinnedTopic(flags: _1!, channelId: _2!, topicId: _3!)
}
else {
return nil
}
}
public static func parse_updateChannelPinnedTopics(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: [Int32]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateChannelPinnedTopics(flags: _1!, channelId: _2!, order: _3)
}
else {
return nil
}
}
public static func parse_updateChannelReadMessagesContents(_ reader: BufferReader) -> Update? { public static func parse_updateChannelReadMessagesContents(_ reader: BufferReader) -> Update? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()
@ -3582,6 +3568,50 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_updateGroupCallEncryptedMessage(_ reader: BufferReader) -> Update? {
var _1: Api.InputGroupCall?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
}
var _2: Api.Peer?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _3: Buffer?
_3 = parseBytes(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateGroupCallEncryptedMessage(call: _1!, fromId: _2!, encryptedMessage: _3!)
}
else {
return nil
}
}
public static func parse_updateGroupCallMessage(_ reader: BufferReader) -> Update? {
var _1: Api.InputGroupCall?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
}
var _2: Api.Peer?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _3: Api.TextWithEntities?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateGroupCallMessage(call: _1!, fromId: _2!, message: _3!)
}
else {
return nil
}
}
public static func parse_updateGroupCallParticipants(_ reader: BufferReader) -> Update? { public static func parse_updateGroupCallParticipants(_ reader: BufferReader) -> Update? {
var _1: Api.InputGroupCall? var _1: Api.InputGroupCall?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -4156,6 +4186,46 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_updatePinnedForumTopic(_ reader: BufferReader) -> Update? {
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()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updatePinnedForumTopic(flags: _1!, peer: _2!, topicId: _3!)
}
else {
return nil
}
}
public static func parse_updatePinnedForumTopics(_ reader: BufferReader) -> Update? {
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]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updatePinnedForumTopics(flags: _1!, peer: _2!, order: _3)
}
else {
return nil
}
}
public static func parse_updatePinnedMessages(_ reader: BufferReader) -> Update? { public static func parse_updatePinnedMessages(_ reader: BufferReader) -> Update? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()

View File

@ -3414,27 +3414,6 @@ public extension Api.functions.channels {
}) })
} }
} }
public extension Api.functions.channels {
static func reorderPinnedForumTopics(flags: Int32, channel: Api.InputChannel, order: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(693150095)
serializeInt32(flags, buffer: buffer, boxed: false)
channel.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "channels.reorderPinnedForumTopics", parameters: [("flags", String(describing: flags)), ("channel", String(describing: channel)), ("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.channels { public extension Api.functions.channels {
static func reorderUsernames(channel: Api.InputChannel, order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func reorderUsernames(channel: Api.InputChannel, order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
@ -3839,23 +3818,6 @@ public extension Api.functions.channels {
}) })
} }
} }
public extension Api.functions.channels {
static func updatePinnedForumTopic(channel: Api.InputChannel, topicId: Int32, pinned: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(1814925350)
channel.serialize(buffer, true)
serializeInt32(topicId, buffer: buffer, boxed: false)
pinned.serialize(buffer, true)
return (FunctionDescription(name: "channels.updatePinnedForumTopic", parameters: [("channel", String(describing: channel)), ("topicId", String(describing: topicId)), ("pinned", String(describing: pinned))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.channels { public extension Api.functions.channels {
static func updateUsername(channel: Api.InputChannel, username: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func updateUsername(channel: Api.InputChannel, username: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
@ -7724,6 +7686,27 @@ public extension Api.functions.messages {
}) })
} }
} }
public extension Api.functions.messages {
static func reorderPinnedForumTopics(flags: Int32, peer: Api.InputPeer, order: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(242762224)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "messages.reorderPinnedForumTopics", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.messages { public extension Api.functions.messages {
static func reorderPinnedSavedDialogs(flags: Int32, order: [Api.InputDialogPeer]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func reorderPinnedSavedDialogs(flags: Int32, order: [Api.InputDialogPeer]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
@ -9183,6 +9166,23 @@ public extension Api.functions.messages {
}) })
} }
} }
public extension Api.functions.messages {
static func updatePinnedForumTopic(peer: Api.InputPeer, topicId: Int32, pinned: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(392032849)
peer.serialize(buffer, true)
serializeInt32(topicId, buffer: buffer, boxed: false)
pinned.serialize(buffer, true)
return (FunctionDescription(name: "messages.updatePinnedForumTopic", parameters: [("peer", String(describing: peer)), ("topicId", String(describing: topicId)), ("pinned", String(describing: pinned))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.messages { public extension Api.functions.messages {
static func updatePinnedMessage(flags: Int32, peer: Api.InputPeer, id: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { static func updatePinnedMessage(flags: Int32, peer: Api.InputPeer, id: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
@ -10796,6 +10796,38 @@ public extension Api.functions.phone {
}) })
} }
} }
public extension Api.functions.phone {
static func sendGroupCallEncryptedMessage(call: Api.InputGroupCall, encryptedMessage: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-441473683)
call.serialize(buffer, true)
serializeBytes(encryptedMessage, buffer: buffer, boxed: false)
return (FunctionDescription(name: "phone.sendGroupCallEncryptedMessage", parameters: [("call", String(describing: call)), ("encryptedMessage", String(describing: encryptedMessage))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.phone {
static func sendGroupCallMessage(call: Api.InputGroupCall, message: Api.TextWithEntities) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-614432696)
call.serialize(buffer, true)
message.serialize(buffer, true)
return (FunctionDescription(name: "phone.sendGroupCallMessage", parameters: [("call", String(describing: call)), ("message", String(describing: message))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.phone { public extension Api.functions.phone {
static func sendSignalingData(peer: Api.InputPhoneCall, data: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func sendSignalingData(peer: Api.InputPhoneCall, data: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()

View File

@ -822,6 +822,18 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private let e2eContext: ConferenceCallE2EContext? private let e2eContext: ConferenceCallE2EContext?
private var messagesContext: GroupCallMessagesContext? {
didSet {
if let messagesContext = self.messagesContext {
self.messagesStatePromise.set(messagesContext.state)
}
}
}
private let messagesStatePromise = Promise<GroupCallMessagesContext.State>(GroupCallMessagesContext.State(messages: []))
public var messagesState: Signal<GroupCallMessagesContext.State, NoError> {
return self.messagesStatePromise.get()
}
private var lastErrorAlertTimestamp: Double = 0.0 private var lastErrorAlertTimestamp: Double = 0.0
init( init(
@ -911,6 +923,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.e2eContext = nil self.e2eContext = nil
} }
if let initialCall {
self.messagesContext = accountContext.engine.messages.groupCallMessages(
callId: initialCall.description.id,
reference: .id(id: initialCall.description.id, accessHash: initialCall.description.accessHash),
e2eContext: self.e2eContext
)
}
var sharedAudioContext = sharedAudioContext var sharedAudioContext = sharedAudioContext
if sharedAudioContext == nil { if sharedAudioContext == nil {
var useSharedAudio = !isStream var useSharedAudio = !isStream
@ -2959,6 +2979,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
public func setIsMuted(action: PresentationGroupCallMuteAction) { public func setIsMuted(action: PresentationGroupCallMuteAction) {
if "".isEmpty {
self.messagesContext?.send(text: "test\(UInt32.random(in: 0 ... UInt32.max))", entities: [])
return
}
if self.isMutedValue == action { if self.isMutedValue == action {
return return
} }
@ -3959,6 +3984,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
}) })
} }
public func sendMessage(text: String, entities: [MessageTextEntity]) {
if let messagesContext = self.messagesContext {
messagesContext.send(text: text, entities: entities)
}
}
} }
public final class TelegramE2EEncryptionProviderImpl: TelegramE2EEncryptionProvider { public final class TelegramE2EEncryptionProviderImpl: TelegramE2EEncryptionProvider {

View File

@ -118,6 +118,8 @@ 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, text: Api.TextWithEntities)
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
case UpdateAudioTranscription(messageId: MessageId, id: Int64, isPending: Bool, text: String) case UpdateAudioTranscription(messageId: MessageId, id: Int64, isPending: Bool, text: String)
@ -409,6 +411,14 @@ 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, text: Api.TextWithEntities) {
self.addOperation(.UpdateGroupCallMessage(id: id, authorId: authorId, text: text))
}
mutating func updateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) {
self.addOperation(.UpdateGroupCallOpaqueMessage(id: id, authorId: authorId, data: data))
}
mutating func updateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?) { mutating func updateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?) {
self.addOperation(.UpdateAutoremoveTimeout(peer: peer, value: value)) self.addOperation(.UpdateAutoremoveTimeout(peer: peer, value: value))
} }
@ -719,7 +729,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .AddPeerLiveTypingDraftUpdate, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery, .UpdateMonoForumNoPaidException: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .AddPeerLiveTypingDraftUpdate, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateGroupCallMessage, .UpdateGroupCallOpaqueMessage, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery, .UpdateMonoForumNoPaidException:
break break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {
@ -855,6 +865,7 @@ struct AccountReplayedFinalState {
let updatedCalls: [Api.PhoneCall] let updatedCalls: [Api.PhoneCall]
let addedCallSignalingData: [(Int64, Data)] let addedCallSignalingData: [(Int64, Data)]
let updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] let updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)]
let groupCallMessageUpdates: [GroupCallMessageUpdate]
let storyUpdates: [InternalStoryUpdate] let storyUpdates: [InternalStoryUpdate]
let updatedPeersNearby: [PeerNearby]? let updatedPeersNearby: [PeerNearby]?
let isContactUpdates: [(PeerId, Bool)] let isContactUpdates: [(PeerId, Bool)]
@ -882,6 +893,7 @@ struct AccountFinalStateEvents {
let updatedCalls: [Api.PhoneCall] let updatedCalls: [Api.PhoneCall]
let addedCallSignalingData: [(Int64, Data)] let addedCallSignalingData: [(Int64, Data)]
let updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] let updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)]
let groupCallMessageUpdates: [GroupCallMessageUpdate]
let storyUpdates: [InternalStoryUpdate] let storyUpdates: [InternalStoryUpdate]
let updatedPeersNearby: [PeerNearby]? let updatedPeersNearby: [PeerNearby]?
let isContactUpdates: [(PeerId, Bool)] let isContactUpdates: [(PeerId, Bool)]
@ -903,10 +915,10 @@ struct AccountFinalStateEvents {
let addedConferenceInvitationMessagesIds: [MessageId] let addedConferenceInvitationMessagesIds: [MessageId]
var isEmpty: Bool { var isEmpty: Bool {
return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.sentScheduledMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedStarsBalance.isEmpty && self.updatedTonBalance.isEmpty && self.updatedStarsRevenueStatus.isEmpty && self.reportMessageDelivery.isEmpty && self.addedConferenceInvitationMessagesIds.isEmpty return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.sentScheduledMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.groupCallMessageUpdates.isEmpty && self.storyUpdates.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig && !self.isPremiumUpdated && self.updatedStarsBalance.isEmpty && self.updatedTonBalance.isEmpty && self.updatedStarsRevenueStatus.isEmpty && self.reportMessageDelivery.isEmpty && self.addedConferenceInvitationMessagesIds.isEmpty
} }
init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set<PeerId> = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedStarsBalance: [PeerId: StarsAmount] = [:], updatedTonBalance: [PeerId: StarsAmount] = [:], updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:], sentScheduledMessageIds: Set<MessageId> = Set(), reportMessageDelivery: Set<MessageId> = Set(), addedConferenceInvitationMessagesIds: [MessageId] = []) { init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: MessageReaction.Reaction, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], groupCallMessageUpdates: [GroupCallMessageUpdate] = [], storyUpdates: [InternalStoryUpdate] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set<PeerId> = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [PeerAndBoundThreadId: MessageId.Id] = [:], updateConfig: Bool = false, isPremiumUpdated: Bool = false, updatedStarsBalance: [PeerId: StarsAmount] = [:], updatedTonBalance: [PeerId: StarsAmount] = [:], updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:], sentScheduledMessageIds: Set<MessageId> = Set(), reportMessageDelivery: Set<MessageId> = Set(), addedConferenceInvitationMessagesIds: [MessageId] = []) {
self.addedIncomingMessageIds = addedIncomingMessageIds self.addedIncomingMessageIds = addedIncomingMessageIds
self.addedReactionEvents = addedReactionEvents self.addedReactionEvents = addedReactionEvents
self.wasScheduledMessageIds = wasScheduledMessageIds self.wasScheduledMessageIds = wasScheduledMessageIds
@ -916,6 +928,7 @@ struct AccountFinalStateEvents {
self.updatedCalls = updatedCalls self.updatedCalls = updatedCalls
self.addedCallSignalingData = addedCallSignalingData self.addedCallSignalingData = addedCallSignalingData
self.updatedGroupCallParticipants = updatedGroupCallParticipants self.updatedGroupCallParticipants = updatedGroupCallParticipants
self.groupCallMessageUpdates = groupCallMessageUpdates
self.storyUpdates = storyUpdates self.storyUpdates = storyUpdates
self.updatedPeersNearby = updatedPeersNearby self.updatedPeersNearby = updatedPeersNearby
self.isContactUpdates = isContactUpdates self.isContactUpdates = isContactUpdates
@ -948,6 +961,7 @@ struct AccountFinalStateEvents {
self.updatedCalls = state.updatedCalls self.updatedCalls = state.updatedCalls
self.addedCallSignalingData = state.addedCallSignalingData self.addedCallSignalingData = state.addedCallSignalingData
self.updatedGroupCallParticipants = state.updatedGroupCallParticipants self.updatedGroupCallParticipants = state.updatedGroupCallParticipants
self.groupCallMessageUpdates = state.groupCallMessageUpdates
self.storyUpdates = state.storyUpdates self.storyUpdates = state.storyUpdates
self.updatedPeersNearby = state.updatedPeersNearby self.updatedPeersNearby = state.updatedPeersNearby
self.isContactUpdates = state.isContactUpdates self.isContactUpdates = state.isContactUpdates
@ -1016,6 +1030,7 @@ struct AccountFinalStateEvents {
updatedCalls: self.updatedCalls + other.updatedCalls, updatedCalls: self.updatedCalls + other.updatedCalls,
addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData, addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData,
updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants, updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants,
groupCallMessageUpdates: self.groupCallMessageUpdates + other.groupCallMessageUpdates,
storyUpdates: self.storyUpdates + other.storyUpdates, storyUpdates: self.storyUpdates + other.storyUpdates,
isContactUpdates: self.isContactUpdates + other.isContactUpdates, isContactUpdates: self.isContactUpdates + other.isContactUpdates,
displayAlerts: self.displayAlerts + other.displayAlerts, displayAlerts: self.displayAlerts + other.displayAlerts,

View File

@ -499,8 +499,8 @@ func _internal_setForumChannelPinnedTopics(account: Account, id: EnginePeer.Id,
} }
} }
} else { } else {
return account.postbox.transaction { transaction -> Api.InputChannel? in return account.postbox.transaction { transaction -> Api.InputPeer? in
guard let inputChannel = transaction.getPeer(id).flatMap(apiInputChannel) else { guard let inputChannel = transaction.getPeer(id).flatMap(apiInputPeer) else {
return nil return nil
} }
@ -509,14 +509,14 @@ func _internal_setForumChannelPinnedTopics(account: Account, id: EnginePeer.Id,
return inputChannel return inputChannel
} }
|> castError(SetForumChannelTopicPinnedError.self) |> castError(SetForumChannelTopicPinnedError.self)
|> mapToSignal { inputChannel -> Signal<Never, SetForumChannelTopicPinnedError> in |> mapToSignal { inputPeer -> Signal<Never, SetForumChannelTopicPinnedError> in
guard let inputChannel = inputChannel else { guard let inputPeer else {
return .fail(.generic) return .fail(.generic)
} }
return account.network.request(Api.functions.channels.reorderPinnedForumTopics( return account.network.request(Api.functions.messages.reorderPinnedForumTopics(
flags: 1 << 0, flags: 1 << 0,
channel: inputChannel, peer: inputPeer,
order: threadIds.map(Int32.init(clamping:)) order: threadIds.map(Int32.init(clamping:))
)) ))
|> mapError { _ -> SetForumChannelTopicPinnedError in |> mapError { _ -> SetForumChannelTopicPinnedError in

View File

@ -115,10 +115,9 @@ private func peerIdsRequiringLocalChatStateFromUpdates(_ updates: [Api.Update])
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order): case let .updatePinnedForumTopics(_, peerId, order):
if order == nil { if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) peerIds.insert(peerId.peerId)
peerIds.insert(peerId)
} }
case let .updateFolderPeers(folderPeers, _, _): case let .updateFolderPeers(folderPeers, _, _):
for peer in folderPeers { for peer in folderPeers {
@ -357,10 +356,9 @@ private func peerIdsRequiringLocalChatStateFromDifference(_ difference: Api.upda
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order): case let .updatePinnedForumTopics(_, peerId, order):
if order == nil { if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) peerIds.insert(peerId.peerId)
peerIds.insert(peerId)
} }
default: default:
break break
@ -384,10 +382,9 @@ private func peerIdsRequiringLocalChatStateFromDifference(_ difference: Api.upda
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order): case let .updatePinnedForumTopics(_, peerId, order):
if order == nil { if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) peerIds.insert(peerId.peerId)
peerIds.insert(peerId)
} }
default: default:
break break
@ -767,15 +764,15 @@ private func sortedUpdates(_ updates: [Api.Update]) -> [Api.Update] {
} else { } else {
updatesByChannel[peerId]!.append(update) updatesByChannel[peerId]!.append(update)
} }
case let .updateChannelPinnedTopic(_, channelId, _): case let .updatePinnedForumTopic(_, peerId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = peerId.peerId
if updatesByChannel[peerId] == nil { if updatesByChannel[peerId] == nil {
updatesByChannel[peerId] = [update] updatesByChannel[peerId] = [update]
} else { } else {
updatesByChannel[peerId]!.append(update) updatesByChannel[peerId]!.append(update)
} }
case let .updateChannelPinnedTopics(_, channelId, _): case let .updatePinnedForumTopics(_, peerId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = peerId.peerId
if updatesByChannel[peerId] == nil { if updatesByChannel[peerId] == nil {
updatesByChannel[peerId] = [update] updatesByChannel[peerId] = [update]
} else { } else {
@ -922,11 +919,11 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
channelsToPoll[peerId] = channelPts channelsToPoll[peerId] = channelPts
} }
} }
case let .updateChannelPinnedTopics(_, channelId, order): case let .updatePinnedForumTopics(_, peerId, order):
if let order = order { if let order = order {
updatedState.addUpdatePinnedTopicOrder(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadIds: order.map(Int64.init)) updatedState.addUpdatePinnedTopicOrder(peerId: peerId.peerId, threadIds: order.map(Int64.init))
} else { } else {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = peerId.peerId
if case .none = channelsToPoll[peerId] { if case .none = channelsToPoll[peerId] {
channelsToPoll[peerId] = nil channelsToPoll[peerId] = nil
} }
@ -1555,9 +1552,9 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
} else { } else {
updatedState.addUpdatePinnedSavedItemIds(operation: .sync) updatedState.addUpdatePinnedSavedItemIds(operation: .sync)
} }
case let .updateChannelPinnedTopic(flags, channelId, topicId): case let .updatePinnedForumTopic(flags, peerId, topicId):
let isPinned = (flags & (1 << 0)) != 0 let isPinned = (flags & (1 << 0)) != 0
updatedState.addUpdatePinnedTopic(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadId: Int64(topicId), isPinned: isPinned) updatedState.addUpdatePinnedTopic(peerId: peerId.peerId, threadId: Int64(topicId), isPinned: isPinned)
case let .updateReadMessagesContents(_, messages, _, _, date): case let .updateReadMessagesContents(_, messages, _, _, date):
updatedState.addReadMessagesContents((nil, nil, messages), date: date) updatedState.addReadMessagesContents((nil, nil, messages), date: date)
case let .updateChannelReadMessagesContents(_, channelId, topMsgId, savedPeerId, messages): case let .updateChannelReadMessagesContents(_, channelId, topMsgId, savedPeerId, messages):
@ -1687,6 +1684,14 @@ 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, message):
if case let .inputGroupCall(id, _) = call {
updatedState.updateGroupCallMessage(id: id, authorId: fromId.peerId, text: message)
}
case let .updateGroupCallEncryptedMessage(call, fromId, encryptedMessage):
if case let .inputGroupCall(id, _) = call {
updatedState.updateGroupCallOpaqueMessage(id: id, authorId: fromId.peerId, data: encryptedMessage.makeData())
}
case let .updatePeerHistoryTTL(_, peer, ttl): case let .updatePeerHistoryTTL(_, peer, ttl):
updatedState.updateAutoremoveTimeout(peer: peer, value: CachedPeerAutoremoveTimeout.Value(ttl)) updatedState.updateAutoremoveTimeout(peer: peer, value: CachedPeerAutoremoveTimeout.Value(ttl))
case let .updateLangPackTooLong(langCode): case let .updateLangPackTooLong(langCode):
@ -3613,7 +3618,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddQuickReplyMessages: OptimizeAddMessagesState? var currentAddQuickReplyMessages: OptimizeAddMessagesState?
for operation in operations { for operation in operations {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .AddPeerLiveTypingDraftUpdate, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery, .UpdateMonoForumNoPaidException: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .AddPeerLiveTypingDraftUpdate, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateGroupCallChainBlocks, .UpdateGroupCallMessage, .UpdateGroupCallOpaqueMessage, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery, .UpdateMonoForumNoPaidException:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
} }
@ -3730,6 +3735,7 @@ func replayFinalState(
var updatedCalls: [Api.PhoneCall] = [] var updatedCalls: [Api.PhoneCall] = []
var addedCallSignalingData: [(Int64, Data)] = [] var addedCallSignalingData: [(Int64, Data)] = []
var updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [] var updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = []
var groupCallMessageUpdates: [GroupCallMessageUpdate] = []
var storyUpdates: [InternalStoryUpdate] = [] var storyUpdates: [InternalStoryUpdate] = []
var updatedPeersNearby: [PeerNearby]? var updatedPeersNearby: [PeerNearby]?
var isContactUpdates: [(PeerId, Bool)] = [] var isContactUpdates: [(PeerId, Bool)] = []
@ -4871,6 +4877,13 @@ 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, text):
switch text {
case let .textWithEntities(text, entities):
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newPlaintextMessage(authorId: authorId, text: text, entities: messageTextEntitiesFromApiEntities(entities))))
}
case let .UpdateGroupCallOpaqueMessage(callId, authorId, data):
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newOpaqueMessage(authorId: authorId, data: data)))
case let .UpdateGroupCall(peerId, call): case let .UpdateGroupCall(peerId, call):
switch call { switch call {
case .groupCall: case .groupCall:
@ -5834,6 +5847,7 @@ func replayFinalState(
updatedCalls: updatedCalls, updatedCalls: updatedCalls,
addedCallSignalingData: addedCallSignalingData, addedCallSignalingData: addedCallSignalingData,
updatedGroupCallParticipants: updatedGroupCallParticipants, updatedGroupCallParticipants: updatedGroupCallParticipants,
groupCallMessageUpdates: groupCallMessageUpdates,
storyUpdates: storyUpdates, storyUpdates: storyUpdates,
updatedPeersNearby: updatedPeersNearby, updatedPeersNearby: updatedPeersNearby,
isContactUpdates: isContactUpdates, isContactUpdates: isContactUpdates,

View File

@ -305,6 +305,11 @@ public final class AccountStateManager {
return self.groupCallParticipantUpdatesPipe.signal() return self.groupCallParticipantUpdatesPipe.signal()
} }
private let groupCallMessageUpdatesPipe = ValuePipe<[GroupCallMessageUpdate]>()
public var groupCallMessageUpdates: Signal<[GroupCallMessageUpdate], NoError> {
return self.groupCallMessageUpdatesPipe.signal()
}
private let deletedMessagesPipe = ValuePipe<[DeletedMessageId]>() private let deletedMessagesPipe = ValuePipe<[DeletedMessageId]>()
public var deletedMessages: Signal<[DeletedMessageId], NoError> { public var deletedMessages: Signal<[DeletedMessageId], NoError> {
return self.deletedMessagesPipe.signal() return self.deletedMessagesPipe.signal()
@ -1129,6 +1134,9 @@ public final class AccountStateManager {
if !events.updatedGroupCallParticipants.isEmpty { if !events.updatedGroupCallParticipants.isEmpty {
strongSelf.groupCallParticipantUpdatesPipe.putNext(events.updatedGroupCallParticipants) strongSelf.groupCallParticipantUpdatesPipe.putNext(events.updatedGroupCallParticipants)
} }
if !events.groupCallMessageUpdates.isEmpty {
strongSelf.groupCallMessageUpdatesPipe.putNext(events.groupCallMessageUpdates)
}
if !events.storyUpdates.isEmpty { if !events.storyUpdates.isEmpty {
strongSelf.storyUpdatesPipe.putNext(events.storyUpdates) strongSelf.storyUpdatesPipe.putNext(events.storyUpdates)
} }
@ -1924,6 +1932,12 @@ public final class AccountStateManager {
} }
} }
var groupCallMessageUpdates: Signal<[GroupCallMessageUpdate], NoError> {
return self.impl.signalWith { impl, subscriber in
return impl.groupCallMessageUpdates.start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
}
}
public var deletedMessages: Signal<[DeletedMessageId], NoError> { public var deletedMessages: Signal<[DeletedMessageId], NoError> {
return self.impl.signalWith { impl, subscriber in return self.impl.signalWith { impl, subscriber in
return impl.deletedMessages.start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion) return impl.deletedMessages.start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)

View File

@ -3373,3 +3373,248 @@ func _internal_refreshInlineGroupCall(account: Account, messageId: MessageId) ->
|> ignoreValues |> ignoreValues
} }
} }
struct GroupCallMessageUpdate {
enum Update {
case newPlaintextMessage(authorId: PeerId, text: String, entities: [MessageTextEntity])
case newOpaqueMessage(authorId: PeerId, data: Data)
}
var callId: Int64
var update: Update
init(callId: Int64, update: Update) {
self.callId = callId
self.update = update
}
}
public final class GroupCallMessagesContext {
public final class Message: Equatable {
public let id: Int64
public let author: EnginePeer?
public let text: String
public let entities: [MessageTextEntity]
public init(id: Int64, author: EnginePeer?, text: String, entities: [MessageTextEntity]) {
self.id = id
self.author = author
self.text = text
self.entities = entities
}
public static func ==(lhs: Message, rhs: Message) -> Bool {
if lhs.id != rhs.id {
return false
}
if lhs === rhs {
return true
}
if lhs.author != rhs.author {
return false
}
if lhs.text != rhs.text {
return false
}
if lhs.entities != rhs.entities {
return false
}
return true
}
}
public struct State: Equatable {
public var messages: [Message]
public init(messages: [Message]) {
self.messages = messages
}
}
private final class Impl {
let queue: Queue
let account: Account
let callId: Int64
let reference: InternalGroupCallReference
let e2eContext: ConferenceCallE2EContext?
var nextId: Int64 = 1
var state: State {
didSet {
self.stateValue.set(self.state)
}
}
let stateValue = ValuePromise<State>()
var updatesDisposable: Disposable?
let sendMessageDisposables = DisposableSet()
init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?) {
self.queue = queue
self.account = account
self.callId = callId
self.reference = reference
self.e2eContext = e2eContext
self.state = State(messages: [])
self.stateValue.set(self.state)
self.updatesDisposable = (account.stateManager.groupCallMessageUpdates
|> deliverOn(self.queue)).startStrict(next: { [weak self] updates in
guard let self else {
return
}
var addedMessages: [(authorId: PeerId, text: String, entities: [MessageTextEntity])] = []
var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = []
for update in updates {
if update.callId != self.callId {
continue
}
switch update.update {
case let .newPlaintextMessage(authorId, text, entities):
addedMessages.append((authorId, text, entities))
case let .newOpaqueMessage(authorId, data):
addedOpaqueMessages.append((authorId, data))
}
}
if !addedMessages.isEmpty || !addedOpaqueMessages.isEmpty {
let _ = (self.account.postbox.transaction { transaction -> [Message] in
var messages: [Message] = []
if let e2eContext = self.e2eContext {
let decryptedMessages = e2eContext.state.with({ state -> [Data?] in
guard let state = state.state else {
return []
}
var result: [Data?] = []
for addedOpaqueMessage in addedOpaqueMessages {
result.append(state.decrypt(message: addedOpaqueMessage.data, userId: addedOpaqueMessage.authorId.id._internalGetInt64Value()))
}
return result
})
for i in 0 ..< addedOpaqueMessages.count {
let addedOpaqueMessage = addedOpaqueMessages[i]
var decryptedMessage: Data?
if i < decryptedMessages.count {
decryptedMessage = decryptedMessages[i]
}
guard let decryptedMessage else {
continue
}
guard let text = String(data: decryptedMessage, encoding: .utf8) else {
continue
}
let messageId = self.nextId
self.nextId += 1
messages.append(Message(
id: messageId,
author: transaction.getPeer(addedOpaqueMessage.authorId).flatMap(EnginePeer.init),
text: text,
entities: []
))
}
} else {
for addedMessage in addedMessages {
let messageId = self.nextId
self.nextId += 1
messages.append(Message(
id: messageId,
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
text: addedMessage.text,
entities: addedMessage.entities
))
}
}
return messages
}
|> deliverOn(self.queue)).startStandalone(next: { [weak self] messages in
guard let self else {
return
}
var state = self.state
state.messages.append(contentsOf: messages)
self.state = state
})
}
})
}
deinit {
self.updatesDisposable?.dispose()
self.sendMessageDisposables.dispose()
}
func send(text: String, entities: [MessageTextEntity]) {
let accountPeerId = self.account.peerId
let _ = (self.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(accountPeerId)
}
|> deliverOn(self.queue)).startStandalone(next: { [weak self] accountPeer in
guard let self else {
return
}
let messageId = self.nextId
self.nextId += 1
var state = self.state
state.messages.append(Message(
id: messageId,
author: accountPeer.flatMap(EnginePeer.init),
text: text,
entities: entities
))
self.state = state
if let e2eContext = self.e2eContext {
let messageData = text.data(using: .utf8)!
let encryptedMessage = e2eContext.state.with({ state -> Data? in
guard let state = state.state else {
return nil
}
return state.encrypt(message: messageData, channelId: 2, plaintextPrefixLength: 0)
})
if let encryptedMessage {
self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallEncryptedMessage(
call: self.reference.apiInputGroupCall,
encryptedMessage: Buffer(data: encryptedMessage)
)).startStrict())
}
} else {
self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallMessage(
call: self.reference.apiInputGroupCall,
message: .textWithEntities(
text: text,
entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())
)
)).startStrict())
}
})
}
}
private let queue: Queue
private let impl: QueueLocalObject<Impl>
public var state: Signal<State, NoError> {
return self.impl.signalWith { impl, subscriber in
return impl.stateValue.get().startStandalone(next: subscriber.putNext)
}
}
init(account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?) {
let queue = Queue(name: "GroupCallMessagesContext")
self.queue = queue
self.impl = QueueLocalObject(queue: queue, generate: {
return Impl(queue: queue, account: account, callId: callId, reference: reference, e2eContext: e2eContext)
})
}
public func send(text: String, entities: [MessageTextEntity]) {
self.impl.with { impl in
impl.send(text: text, entities: entities)
}
}
}

View File

@ -1631,6 +1631,10 @@ public extension TelegramEngine {
public func refreshGlobalPostSearchState() -> Signal<Never, NoError> { public func refreshGlobalPostSearchState() -> Signal<Never, NoError> {
return _internal_refreshGlobalPostSearchState(account: self.account) return _internal_refreshGlobalPostSearchState(account: self.account)
} }
public func groupCallMessages(callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?) -> GroupCallMessagesContext {
return GroupCallMessagesContext(account: self.account, callId: callId, reference: reference, e2eContext: e2eContext)
}
} }
} }