Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2020-11-20 12:30:23 +04:00
commit e87908a532
17 changed files with 560 additions and 849 deletions

View File

@ -155,6 +155,29 @@ public final class CachedChannelData: CachedPeerData {
case known(PeerId?) case known(PeerId?)
} }
public struct ActiveCall: Equatable, PostboxCoding {
public var id: Int64
public var accessHash: Int64
public init(
id: Int64,
accessHash: Int64
) {
self.id = id
self.accessHash = accessHash
}
public init(decoder: PostboxDecoder) {
self.id = decoder.decodeInt64ForKey("id", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0)
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.id, forKey: "id")
encoder.encodeInt64(self.accessHash, forKey: "accessHash")
}
}
public let isNotAccessible: Bool public let isNotAccessible: Bool
public let flags: CachedChannelFlags public let flags: CachedChannelFlags
public let about: String? public let about: String?
@ -174,7 +197,7 @@ public final class CachedChannelData: CachedPeerData {
public let statsDatacenterId: Int32 public let statsDatacenterId: Int32
public let invitedBy: PeerId? public let invitedBy: PeerId?
public let photo: TelegramMediaImage? public let photo: TelegramMediaImage?
public let activeCallMessageId: MessageId? public let activeCall: ActiveCall?
public let peerIds: Set<PeerId> public let peerIds: Set<PeerId>
public let messageIds: Set<MessageId> public let messageIds: Set<MessageId>
@ -204,10 +227,10 @@ public final class CachedChannelData: CachedPeerData {
self.statsDatacenterId = 0 self.statsDatacenterId = 0
self.invitedBy = nil self.invitedBy = nil
self.photo = nil self.photo = nil
self.activeCallMessageId = nil self.activeCall = nil
} }
public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: LinkedDiscussionPeerId, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?, photo: TelegramMediaImage?, activeCallMessageId: MessageId?) { public init(isNotAccessible: Bool, flags: CachedChannelFlags, about: String?, participantsSummary: CachedChannelParticipantsSummary, exportedInvitation: ExportedInvitation?, botInfos: [CachedPeerBotInfo], peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, stickerPack: StickerPackCollectionInfo?, minAvailableMessageId: MessageId?, migrationReference: ChannelMigrationReference?, linkedDiscussionPeerId: LinkedDiscussionPeerId, peerGeoLocation: PeerGeoLocation?, slowModeTimeout: Int32?, slowModeValidUntilTimestamp: Int32?, hasScheduledMessages: Bool, statsDatacenterId: Int32, invitedBy: PeerId?, photo: TelegramMediaImage?, activeCall: ActiveCall?) {
self.isNotAccessible = isNotAccessible self.isNotAccessible = isNotAccessible
self.flags = flags self.flags = flags
self.about = about self.about = about
@ -227,7 +250,7 @@ public final class CachedChannelData: CachedPeerData {
self.statsDatacenterId = statsDatacenterId self.statsDatacenterId = statsDatacenterId
self.invitedBy = invitedBy self.invitedBy = invitedBy
self.photo = photo self.photo = photo
self.activeCallMessageId = activeCallMessageId self.activeCall = activeCall
var peerIds = Set<PeerId>() var peerIds = Set<PeerId>()
for botInfo in botInfos { for botInfo in botInfos {
@ -255,83 +278,83 @@ public final class CachedChannelData: CachedPeerData {
} }
public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData { public func withUpdatedIsNotAccessible(_ isNotAccessible: Bool) -> CachedChannelData {
return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData { public func withUpdatedFlags(_ flags: CachedChannelFlags) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedAbout(_ about: String?) -> CachedChannelData { public func withUpdatedAbout(_ about: String?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData { public func withUpdatedParticipantsSummary(_ participantsSummary: CachedChannelParticipantsSummary) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData { public func withUpdatedExportedInvitation(_ exportedInvitation: ExportedInvitation?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData { public func withUpdatedBotInfos(_ botInfos: [CachedPeerBotInfo]) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData { public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData { public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData { public func withUpdatedStickerPack(_ stickerPack: StickerPackCollectionInfo?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData { public func withUpdatedMinAvailableMessageId(_ minAvailableMessageId: MessageId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData { public func withUpdatedMigrationReference(_ migrationReference: ChannelMigrationReference?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData { public func withUpdatedLinkedDiscussionPeerId(_ linkedDiscussionPeerId: LinkedDiscussionPeerId) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData { public func withUpdatedPeerGeoLocation(_ peerGeoLocation: PeerGeoLocation?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData { public func withUpdatedSlowModeTimeout(_ slowModeTimeout: Int32?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData { public func withUpdatedSlowModeValidUntilTimestamp(_ slowModeValidUntilTimestamp: Int32?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData { public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData { public func withUpdatedStatsDatacenterId(_ statsDatacenterId: Int32) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData { public func withUpdatedInvitedBy(_ invitedBy: PeerId?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, photo: self.photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: invitedBy, photo: self.photo, activeCall: self.activeCall)
} }
public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData { public func withUpdatedPhoto(_ photo: TelegramMediaImage?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: photo, activeCallMessageId: self.activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: photo, activeCall: self.activeCall)
} }
public func withUpdatedActiveCallMessageId(_ activeCallMessageId: MessageId?) -> CachedChannelData { public func withUpdatedActiveCall(_ activeCall: ActiveCall?) -> CachedChannelData {
return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCallMessageId: activeCallMessageId) return CachedChannelData(isNotAccessible: self.isNotAccessible, flags: self.flags, about: self.about, participantsSummary: self.participantsSummary, exportedInvitation: self.exportedInvitation, botInfos: self.botInfos, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, stickerPack: self.stickerPack, minAvailableMessageId: self.minAvailableMessageId, migrationReference: self.migrationReference, linkedDiscussionPeerId: self.linkedDiscussionPeerId, peerGeoLocation: self.peerGeoLocation, slowModeTimeout: self.slowModeTimeout, slowModeValidUntilTimestamp: self.slowModeValidUntilTimestamp, hasScheduledMessages: self.hasScheduledMessages, statsDatacenterId: self.statsDatacenterId, invitedBy: self.invitedBy, photo: self.photo, activeCall: activeCall)
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
@ -356,10 +379,10 @@ public final class CachedChannelData: CachedPeerData {
self.pinnedMessageId = nil self.pinnedMessageId = nil
} }
if let activeCallMessagePeerId = decoder.decodeOptionalInt64ForKey("activeCallMessageId.p"), let activeCallMessageNamespace = decoder.decodeOptionalInt32ForKey("activeCallMessageId.n"), let activeCallMessageId = decoder.decodeOptionalInt32ForKey("activeCallMessageId.i") { if let activeCall = decoder.decodeObjectForKey("activeCall", decoder: { ActiveCall(decoder: $0) }) as? ActiveCall {
self.activeCallMessageId = MessageId(peerId: PeerId(activeCallMessagePeerId), namespace: activeCallMessageNamespace, id: activeCallMessageId) self.activeCall = activeCall
} else { } else {
self.activeCallMessageId = nil self.activeCall = nil
} }
if let stickerPack = decoder.decodeObjectForKey("sp", decoder: { StickerPackCollectionInfo(decoder: $0) }) as? StickerPackCollectionInfo { if let stickerPack = decoder.decodeObjectForKey("sp", decoder: { StickerPackCollectionInfo(decoder: $0) }) as? StickerPackCollectionInfo {
@ -454,14 +477,10 @@ public final class CachedChannelData: CachedPeerData {
encoder.encodeNil(forKey: "pm.i") encoder.encodeNil(forKey: "pm.i")
} }
if let activeCallMessageId = self.activeCallMessageId { if let activeCall = self.activeCall {
encoder.encodeInt64(activeCallMessageId.peerId.toInt64(), forKey: "activeCallMessageId.p") encoder.encodeObject(activeCall, forKey: "activeCall")
encoder.encodeInt32(activeCallMessageId.namespace, forKey: "activeCallMessageId.n")
encoder.encodeInt32(activeCallMessageId.id, forKey: "activeCallMessageId.i")
} else { } else {
encoder.encodeNil(forKey: "activeCallMessageId.p") encoder.encodeNil(forKey: "activeCall")
encoder.encodeNil(forKey: "activeCallMessageId.n")
encoder.encodeNil(forKey: "activeCallMessageId.i")
} }
if let stickerPack = self.stickerPack { if let stickerPack = self.stickerPack {
@ -606,7 +625,7 @@ public final class CachedChannelData: CachedPeerData {
return false return false
} }
if other.activeCallMessageId != self.activeCallMessageId { if other.activeCall != self.activeCall {
return false return false
} }

View File

@ -7,13 +7,13 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1255641564] = { return parseString($0) } dict[-1255641564] = { return parseString($0) }
dict[-1240849242] = { return Api.messages.StickerSet.parse_stickerSet($0) } dict[-1240849242] = { return Api.messages.StickerSet.parse_stickerSet($0) }
dict[1829443076] = { return Api.GroupCall.parse_groupCallPrivate($0) } dict[1829443076] = { return Api.GroupCall.parse_groupCallPrivate($0) }
dict[-857633264] = { return Api.GroupCall.parse_groupCall($0) } dict[1441699306] = { return Api.GroupCall.parse_groupCall($0) }
dict[2004925620] = { return Api.GroupCall.parse_groupCallDiscarded($0) } dict[2004925620] = { return Api.GroupCall.parse_groupCallDiscarded($0) }
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) } dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) } dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) } dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[461151667] = { return Api.ChatFull.parse_chatFull($0) } dict[461151667] = { return Api.ChatFull.parse_chatFull($0) }
dict[-428758403] = { return Api.ChatFull.parse_channelFull($0) } dict[-281384243] = { return Api.ChatFull.parse_channelFull($0) }
dict[-1159937629] = { return Api.PollResults.parse_pollResults($0) } dict[-1159937629] = { return Api.PollResults.parse_pollResults($0) }
dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) } dict[-925415106] = { return Api.ChatParticipant.parse_chatParticipant($0) }
dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) } dict[-636267638] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
@ -135,11 +135,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1511503333] = { return Api.InputEncryptedFile.parse_inputEncryptedFile($0) } dict[1511503333] = { return Api.InputEncryptedFile.parse_inputEncryptedFile($0) }
dict[767652808] = { return Api.InputEncryptedFile.parse_inputEncryptedFileBigUploaded($0) } dict[767652808] = { return Api.InputEncryptedFile.parse_inputEncryptedFileBigUploaded($0) }
dict[-1456996667] = { return Api.messages.InactiveChats.parse_inactiveChats($0) } dict[-1456996667] = { return Api.messages.InactiveChats.parse_inactiveChats($0) }
dict[-1513019911] = { return Api.GroupCallParticipant.parse_groupCallParticipantAdmin($0) }
dict[-1985949076] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) } dict[-1985949076] = { return Api.GroupCallParticipant.parse_groupCallParticipant($0) }
dict[1100680690] = { return Api.GroupCallParticipant.parse_groupCallParticipantLeft($0) }
dict[-1648085351] = { return Api.GroupCallParticipant.parse_groupCallParticipantKicked($0) }
dict[-874654354] = { return Api.GroupCallParticipant.parse_groupCallParticipantInvited($0) }
dict[1443858741] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedMessage($0) } dict[1443858741] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedMessage($0) }
dict[-1802240206] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedFile($0) } dict[-1802240206] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedFile($0) }
dict[1571494644] = { return Api.ExportedMessageLink.parse_exportedMessageLink($0) } dict[1571494644] = { return Api.ExportedMessageLink.parse_exportedMessageLink($0) }
@ -266,7 +262,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-13975905] = { return Api.Update.parse_updateChannelUserTyping($0) } dict[-13975905] = { return Api.Update.parse_updateChannelUserTyping($0) }
dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) } dict[-309990731] = { return Api.Update.parse_updatePinnedMessages($0) }
dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($0) } dict[-2054649973] = { return Api.Update.parse_updatePinnedChannelMessages($0) }
dict[92188360] = { return Api.Update.parse_updateGroupCallParticipant($0) } dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
dict[-2046916883] = { return Api.Update.parse_updateGroupCall($0) } dict[-2046916883] = { return Api.Update.parse_updateGroupCall($0) }
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) } dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) } dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
@ -507,7 +503,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1495959709] = { return Api.MessageReplyHeader.parse_messageReplyHeader($0) } dict[-1495959709] = { return Api.MessageReplyHeader.parse_messageReplyHeader($0) }
dict[411017418] = { return Api.SecureValue.parse_secureValue($0) } dict[411017418] = { return Api.SecureValue.parse_secureValue($0) }
dict[-316748368] = { return Api.SecureValueHash.parse_secureValueHash($0) } dict[-316748368] = { return Api.SecureValueHash.parse_secureValueHash($0) }
dict[1731723191] = { return Api.phone.GroupCall.parse_groupCall($0) } dict[1118525718] = { return Api.phone.GroupCall.parse_groupCall($0) }
dict[-398136321] = { return Api.messages.SearchCounter.parse_searchCounter($0) } dict[-398136321] = { return Api.messages.SearchCounter.parse_searchCounter($0) }
dict[-2128698738] = { return Api.auth.CheckedPhone.parse_checkedPhone($0) } dict[-2128698738] = { return Api.auth.CheckedPhone.parse_checkedPhone($0) }
dict[-1188055347] = { return Api.PageListItem.parse_pageListItemText($0) } dict[-1188055347] = { return Api.PageListItem.parse_pageListItemText($0) }
@ -535,6 +531,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-2042159726] = { return Api.SecurePasswordKdfAlgo.parse_securePasswordKdfAlgoSHA512($0) } dict[-2042159726] = { return Api.SecurePasswordKdfAlgo.parse_securePasswordKdfAlgoSHA512($0) }
dict[-1032140601] = { return Api.BotCommand.parse_botCommand($0) } dict[-1032140601] = { return Api.BotCommand.parse_botCommand($0) }
dict[1474462241] = { return Api.account.ContentSettings.parse_contentSettings($0) } dict[1474462241] = { return Api.account.ContentSettings.parse_contentSettings($0) }
dict[1325740111] = { return Api.phone.GroupParticipants.parse_groupParticipants($0) }
dict[-2066640507] = { return Api.messages.AffectedMessages.parse_affectedMessages($0) } dict[-2066640507] = { return Api.messages.AffectedMessages.parse_affectedMessages($0) }
dict[-402498398] = { return Api.messages.SavedGifs.parse_savedGifsNotModified($0) } dict[-402498398] = { return Api.messages.SavedGifs.parse_savedGifsNotModified($0) }
dict[772213157] = { return Api.messages.SavedGifs.parse_savedGifs($0) } dict[772213157] = { return Api.messages.SavedGifs.parse_savedGifs($0) }
@ -1265,6 +1262,8 @@ public struct Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.account.ContentSettings: case let _1 as Api.account.ContentSettings:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.phone.GroupParticipants:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.AffectedMessages: case let _1 as Api.messages.AffectedMessages:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.messages.SavedGifs: case let _1 as Api.messages.SavedGifs:

View File

@ -1911,7 +1911,7 @@ public struct messages {
public extension Api { public extension Api {
public enum GroupCall: TypeConstructorDescription { public enum GroupCall: TypeConstructorDescription {
case groupCallPrivate(flags: Int32, id: Int64, accessHash: Int64, channelId: Int32?, participantsCount: Int32, adminId: Int32) case groupCallPrivate(flags: Int32, id: Int64, accessHash: Int64, channelId: Int32?, participantsCount: Int32, adminId: Int32)
case groupCall(flags: Int32, id: Int64, accessHash: Int64, channelId: Int32?, adminId: Int32, reflectorId: Int64, params: Api.DataJSON?) case groupCall(flags: Int32, id: Int64, accessHash: Int64, channelId: Int32?, adminId: Int32, reflectorId: Int64, params: Api.DataJSON?, version: Int32)
case groupCallDiscarded(id: Int64, accessHash: Int64, duration: Int32) case groupCallDiscarded(id: Int64, accessHash: Int64, duration: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@ -1927,9 +1927,9 @@ public extension Api {
serializeInt32(participantsCount, buffer: buffer, boxed: false) serializeInt32(participantsCount, buffer: buffer, boxed: false)
serializeInt32(adminId, buffer: buffer, boxed: false) serializeInt32(adminId, buffer: buffer, boxed: false)
break break
case .groupCall(let flags, let id, let accessHash, let channelId, let adminId, let reflectorId, let params): case .groupCall(let flags, let id, let accessHash, let channelId, let adminId, let reflectorId, let params, let version):
if boxed { if boxed {
buffer.appendInt32(-857633264) buffer.appendInt32(1441699306)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false) serializeInt64(id, buffer: buffer, boxed: false)
@ -1938,6 +1938,7 @@ public extension Api {
serializeInt32(adminId, buffer: buffer, boxed: false) serializeInt32(adminId, buffer: buffer, boxed: false)
serializeInt64(reflectorId, buffer: buffer, boxed: false) serializeInt64(reflectorId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {params!.serialize(buffer, true)} if Int(flags) & Int(1 << 1) != 0 {params!.serialize(buffer, true)}
serializeInt32(version, buffer: buffer, boxed: false)
break break
case .groupCallDiscarded(let id, let accessHash, let duration): case .groupCallDiscarded(let id, let accessHash, let duration):
if boxed { if boxed {
@ -1954,8 +1955,8 @@ public extension Api {
switch self { switch self {
case .groupCallPrivate(let flags, let id, let accessHash, let channelId, let participantsCount, let adminId): case .groupCallPrivate(let flags, let id, let accessHash, let channelId, let participantsCount, let adminId):
return ("groupCallPrivate", [("flags", flags), ("id", id), ("accessHash", accessHash), ("channelId", channelId), ("participantsCount", participantsCount), ("adminId", adminId)]) return ("groupCallPrivate", [("flags", flags), ("id", id), ("accessHash", accessHash), ("channelId", channelId), ("participantsCount", participantsCount), ("adminId", adminId)])
case .groupCall(let flags, let id, let accessHash, let channelId, let adminId, let reflectorId, let params): case .groupCall(let flags, let id, let accessHash, let channelId, let adminId, let reflectorId, let params, let version):
return ("groupCall", [("flags", flags), ("id", id), ("accessHash", accessHash), ("channelId", channelId), ("adminId", adminId), ("reflectorId", reflectorId), ("params", params)]) return ("groupCall", [("flags", flags), ("id", id), ("accessHash", accessHash), ("channelId", channelId), ("adminId", adminId), ("reflectorId", reflectorId), ("params", params), ("version", version)])
case .groupCallDiscarded(let id, let accessHash, let duration): case .groupCallDiscarded(let id, let accessHash, let duration):
return ("groupCallDiscarded", [("id", id), ("accessHash", accessHash), ("duration", duration)]) return ("groupCallDiscarded", [("id", id), ("accessHash", accessHash), ("duration", duration)])
} }
@ -2004,6 +2005,8 @@ public extension Api {
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() { if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.DataJSON _7 = Api.parse(reader, signature: signature) as? Api.DataJSON
} } } }
var _8: Int32?
_8 = reader.readInt32()
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
@ -2011,8 +2014,9 @@ public extension Api {
let _c5 = _5 != nil let _c5 = _5 != nil
let _c6 = _6 != nil let _c6 = _6 != nil
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 { let _c8 = _8 != nil
return Api.GroupCall.groupCall(flags: _1!, id: _2!, accessHash: _3!, channelId: _4, adminId: _5!, reflectorId: _6!, params: _7) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.GroupCall.groupCall(flags: _1!, id: _2!, accessHash: _3!, channelId: _4, adminId: _5!, reflectorId: _6!, params: _7, version: _8!)
} }
else { else {
return nil return nil
@ -2097,7 +2101,7 @@ public extension Api {
} }
public enum ChatFull: TypeConstructorDescription { public enum ChatFull: TypeConstructorDescription {
case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?) case chatFull(flags: Int32, id: Int32, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?)
case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, callMsgId: Int32?) case channelFull(flags: Int32, id: Int32, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite, botInfo: [Api.BotInfo], migratedFromChatId: Int32?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int32?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -2120,9 +2124,9 @@ public extension Api {
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
break break
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let callMsgId): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call):
if boxed { if boxed {
buffer.appendInt32(-428758403) buffer.appendInt32(-281384243)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
@ -2155,7 +2159,7 @@ public extension Api {
if Int(flags) & Int(1 << 18) != 0 {serializeInt32(slowmodeNextSendDate!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 18) != 0 {serializeInt32(slowmodeNextSendDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 12) != 0 {serializeInt32(statsDc!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 12) != 0 {serializeInt32(statsDc!, buffer: buffer, boxed: false)}
serializeInt32(pts, buffer: buffer, boxed: false) serializeInt32(pts, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 21) != 0 {serializeInt32(callMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 21) != 0 {call!.serialize(buffer, true)}
break break
} }
} }
@ -2164,8 +2168,8 @@ public extension Api {
switch self { switch self {
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId):
return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId)]) return ("chatFull", [("flags", flags), ("id", id), ("about", about), ("participants", participants), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("folderId", folderId)])
case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let callMsgId): case .channelFull(let flags, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call):
return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("location", location), ("slowmodeSeconds", slowmodeSeconds), ("slowmodeNextSendDate", slowmodeNextSendDate), ("statsDc", statsDc), ("pts", pts), ("callMsgId", callMsgId)]) return ("channelFull", [("flags", flags), ("id", id), ("about", about), ("participantsCount", participantsCount), ("adminsCount", adminsCount), ("kickedCount", kickedCount), ("bannedCount", bannedCount), ("onlineCount", onlineCount), ("readInboxMaxId", readInboxMaxId), ("readOutboxMaxId", readOutboxMaxId), ("unreadCount", unreadCount), ("chatPhoto", chatPhoto), ("notifySettings", notifySettings), ("exportedInvite", exportedInvite), ("botInfo", botInfo), ("migratedFromChatId", migratedFromChatId), ("migratedFromMaxId", migratedFromMaxId), ("pinnedMsgId", pinnedMsgId), ("stickerset", stickerset), ("availableMinId", availableMinId), ("folderId", folderId), ("linkedChatId", linkedChatId), ("location", location), ("slowmodeSeconds", slowmodeSeconds), ("slowmodeNextSendDate", slowmodeNextSendDate), ("statsDc", statsDc), ("pts", pts), ("call", call)])
} }
} }
@ -2284,8 +2288,10 @@ public extension Api {
if Int(_1!) & Int(1 << 12) != 0 {_26 = reader.readInt32() } if Int(_1!) & Int(1 << 12) != 0 {_26 = reader.readInt32() }
var _27: Int32? var _27: Int32?
_27 = reader.readInt32() _27 = reader.readInt32()
var _28: Int32? var _28: Api.InputGroupCall?
if Int(_1!) & Int(1 << 21) != 0 {_28 = reader.readInt32() } if Int(_1!) & Int(1 << 21) != 0 {if let signature = reader.readInt32() {
_28 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
} }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
@ -2315,7 +2321,7 @@ public extension Api {
let _c27 = _27 != nil let _c27 = _27 != nil
let _c28 = (Int(_1!) & Int(1 << 21) == 0) || _28 != nil let _c28 = (Int(_1!) & Int(1 << 21) == 0) || _28 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 { if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 {
return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, location: _23, slowmodeSeconds: _24, slowmodeNextSendDate: _25, statsDc: _26, pts: _27!, callMsgId: _28) return Api.ChatFull.channelFull(flags: _1!, id: _2!, about: _3!, participantsCount: _4, adminsCount: _5, kickedCount: _6, bannedCount: _7, onlineCount: _8, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, chatPhoto: _12!, notifySettings: _13!, exportedInvite: _14!, botInfo: _15!, migratedFromChatId: _16, migratedFromMaxId: _17, pinnedMsgId: _18, stickerset: _19, availableMinId: _20, folderId: _21, linkedChatId: _22, location: _23, slowmodeSeconds: _24, slowmodeNextSendDate: _25, statsDc: _26, pts: _27!, call: _28)
} }
else { else {
return nil return nil
@ -5400,21 +5406,10 @@ public extension Api {
} }
public enum GroupCallParticipant: TypeConstructorDescription { public enum GroupCallParticipant: TypeConstructorDescription {
case groupCallParticipantAdmin(userId: Int32, source: Int32)
case groupCallParticipant(flags: Int32, userId: Int32, date: Int32, source: Int32) case groupCallParticipant(flags: Int32, userId: Int32, date: Int32, source: Int32)
case groupCallParticipantLeft(userId: Int32)
case groupCallParticipantKicked(userId: Int32)
case groupCallParticipantInvited(flags: Int32, userId: Int32, inviterId: Int32, date: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .groupCallParticipantAdmin(let userId, let source):
if boxed {
buffer.appendInt32(-1513019911)
}
serializeInt32(userId, buffer: buffer, boxed: false)
serializeInt32(source, buffer: buffer, boxed: false)
break
case .groupCallParticipant(let flags, let userId, let date, let source): case .groupCallParticipant(let flags, let userId, let date, let source):
if boxed { if boxed {
buffer.appendInt32(-1985949076) buffer.appendInt32(-1985949076)
@ -5424,59 +5419,16 @@ public extension Api {
serializeInt32(date, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false)
serializeInt32(source, buffer: buffer, boxed: false) serializeInt32(source, buffer: buffer, boxed: false)
break break
case .groupCallParticipantLeft(let userId):
if boxed {
buffer.appendInt32(1100680690)
}
serializeInt32(userId, buffer: buffer, boxed: false)
break
case .groupCallParticipantKicked(let userId):
if boxed {
buffer.appendInt32(-1648085351)
}
serializeInt32(userId, buffer: buffer, boxed: false)
break
case .groupCallParticipantInvited(let flags, let userId, let inviterId, let date):
if boxed {
buffer.appendInt32(-874654354)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(userId, buffer: buffer, boxed: false)
serializeInt32(inviterId, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
break
} }
} }
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .groupCallParticipantAdmin(let userId, let source):
return ("groupCallParticipantAdmin", [("userId", userId), ("source", source)])
case .groupCallParticipant(let flags, let userId, let date, let source): case .groupCallParticipant(let flags, let userId, let date, let source):
return ("groupCallParticipant", [("flags", flags), ("userId", userId), ("date", date), ("source", source)]) return ("groupCallParticipant", [("flags", flags), ("userId", userId), ("date", date), ("source", source)])
case .groupCallParticipantLeft(let userId):
return ("groupCallParticipantLeft", [("userId", userId)])
case .groupCallParticipantKicked(let userId):
return ("groupCallParticipantKicked", [("userId", userId)])
case .groupCallParticipantInvited(let flags, let userId, let inviterId, let date):
return ("groupCallParticipantInvited", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("date", date)])
} }
} }
public static func parse_groupCallParticipantAdmin(_ reader: BufferReader) -> GroupCallParticipant? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.GroupCallParticipant.groupCallParticipantAdmin(userId: _1!, source: _2!)
}
else {
return nil
}
}
public static func parse_groupCallParticipant(_ reader: BufferReader) -> GroupCallParticipant? { public static func parse_groupCallParticipant(_ reader: BufferReader) -> GroupCallParticipant? {
var _1: Int32? var _1: Int32?
_1 = reader.readInt32() _1 = reader.readInt32()
@ -5497,48 +5449,6 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_groupCallParticipantLeft(_ reader: BufferReader) -> GroupCallParticipant? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.GroupCallParticipant.groupCallParticipantLeft(userId: _1!)
}
else {
return nil
}
}
public static func parse_groupCallParticipantKicked(_ reader: BufferReader) -> GroupCallParticipant? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.GroupCallParticipant.groupCallParticipantKicked(userId: _1!)
}
else {
return nil
}
}
public static func parse_groupCallParticipantInvited(_ reader: BufferReader) -> GroupCallParticipant? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.GroupCallParticipant.groupCallParticipantInvited(flags: _1!, userId: _2!, inviterId: _3!, date: _4!)
}
else {
return nil
}
}
} }
public enum ExportedMessageLink: TypeConstructorDescription { public enum ExportedMessageLink: TypeConstructorDescription {
@ -6467,7 +6377,7 @@ public extension Api {
case updateChannelUserTyping(flags: Int32, channelId: Int32, topMsgId: Int32?, userId: Int32, action: Api.SendMessageAction) case updateChannelUserTyping(flags: Int32, channelId: Int32, topMsgId: Int32?, userId: Int32, action: Api.SendMessageAction)
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 updatePinnedChannelMessages(flags: Int32, channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32) case updatePinnedChannelMessages(flags: Int32, channelId: Int32, messages: [Int32], pts: Int32, ptsCount: Int32)
case updateGroupCallParticipant(call: Api.InputGroupCall, participant: Api.GroupCallParticipant) case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
case updateGroupCall(call: Api.GroupCall) case updateGroupCall(call: Api.GroupCall)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@ -7204,12 +7114,17 @@ public extension Api {
serializeInt32(pts, buffer: buffer, boxed: false) serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false) serializeInt32(ptsCount, buffer: buffer, boxed: false)
break break
case .updateGroupCallParticipant(let call, let participant): case .updateGroupCallParticipants(let call, let participants, let version):
if boxed { if boxed {
buffer.appendInt32(92188360) buffer.appendInt32(-219423922)
} }
call.serialize(buffer, true) call.serialize(buffer, true)
participant.serialize(buffer, true) buffer.appendInt32(481674261)
buffer.appendInt32(Int32(participants.count))
for item in participants {
item.serialize(buffer, true)
}
serializeInt32(version, buffer: buffer, boxed: false)
break break
case .updateGroupCall(let call): case .updateGroupCall(let call):
if boxed { if boxed {
@ -7392,8 +7307,8 @@ public extension Api {
return ("updatePinnedMessages", [("flags", flags), ("peer", peer), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) return ("updatePinnedMessages", [("flags", flags), ("peer", peer), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)])
case .updatePinnedChannelMessages(let flags, let channelId, let messages, let pts, let ptsCount): case .updatePinnedChannelMessages(let flags, let channelId, let messages, let pts, let ptsCount):
return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)]) return ("updatePinnedChannelMessages", [("flags", flags), ("channelId", channelId), ("messages", messages), ("pts", pts), ("ptsCount", ptsCount)])
case .updateGroupCallParticipant(let call, let participant): case .updateGroupCallParticipants(let call, let participants, let version):
return ("updateGroupCallParticipant", [("call", call), ("participant", participant)]) return ("updateGroupCallParticipants", [("call", call), ("participants", participants), ("version", version)])
case .updateGroupCall(let call): case .updateGroupCall(let call):
return ("updateGroupCall", [("call", call)]) return ("updateGroupCall", [("call", call)])
} }
@ -8868,19 +8783,22 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_updateGroupCallParticipant(_ 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() {
_1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall _1 = Api.parse(reader, signature: signature) as? Api.InputGroupCall
} }
var _2: Api.GroupCallParticipant? var _2: [Api.GroupCallParticipant]?
if let signature = reader.readInt32() { if let _ = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.GroupCallParticipant _2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
} }
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
if _c1 && _c2 { let _c3 = _3 != nil
return Api.Update.updateGroupCallParticipant(call: _1!, participant: _2!) if _c1 && _c2 && _c3 {
return Api.Update.updateGroupCallParticipants(call: _1!, participants: _2!, version: _3!)
} }
else { else {
return nil return nil

View File

@ -1649,16 +1649,21 @@ public struct photos {
public extension Api { public extension Api {
public struct phone { public struct phone {
public enum GroupCall: TypeConstructorDescription { public enum GroupCall: TypeConstructorDescription {
case groupCall(call: Api.GroupCall, participants: [Api.GroupCallParticipant], chats: [Api.Chat], users: [Api.User]) case groupCall(call: Api.GroupCall, sources: [Int32], participants: [Api.GroupCallParticipant], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .groupCall(let call, let participants, let chats, let users): case .groupCall(let call, let sources, let participants, let chats, let users):
if boxed { if boxed {
buffer.appendInt32(1731723191) buffer.appendInt32(1118525718)
} }
call.serialize(buffer, true) call.serialize(buffer, true)
buffer.appendInt32(481674261) buffer.appendInt32(481674261)
buffer.appendInt32(Int32(sources.count))
for item in sources {
serializeInt32(item, buffer: buffer, boxed: false)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(participants.count)) buffer.appendInt32(Int32(participants.count))
for item in participants { for item in participants {
item.serialize(buffer, true) item.serialize(buffer, true)
@ -1679,8 +1684,8 @@ public struct phone {
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .groupCall(let call, let participants, let chats, let users): case .groupCall(let call, let sources, let participants, let chats, let users):
return ("groupCall", [("call", call), ("participants", participants), ("chats", chats), ("users", users)]) return ("groupCall", [("call", call), ("sources", sources), ("participants", participants), ("chats", chats), ("users", users)])
} }
} }
@ -1689,24 +1694,83 @@ public struct phone {
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.GroupCall _1 = Api.parse(reader, signature: signature) as? Api.GroupCall
} }
var _2: [Api.GroupCallParticipant]? var _2: [Int32]?
if let _ = reader.readInt32() { if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self) _2 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
} }
var _3: [Api.Chat]? var _3: [Api.GroupCallParticipant]?
if let _ = reader.readInt32() { if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
} }
var _4: [Api.User]? var _4: [Api.Chat]?
if let _ = reader.readInt32() { if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) _4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _5: [Api.User]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
} }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
let _c4 = _4 != nil let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 { let _c5 = _5 != nil
return Api.phone.GroupCall.groupCall(call: _1!, participants: _2!, chats: _3!, users: _4!) if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.phone.GroupCall.groupCall(call: _1!, sources: _2!, participants: _3!, chats: _4!, users: _5!)
}
else {
return nil
}
}
}
public enum GroupParticipants: TypeConstructorDescription {
case groupParticipants(count: Int32, participants: [Api.GroupCallParticipant], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .groupParticipants(let count, let participants, let users):
if boxed {
buffer.appendInt32(1325740111)
}
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(participants.count))
for item in participants {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .groupParticipants(let count, let participants, let users):
return ("groupParticipants", [("count", count), ("participants", participants), ("users", users)])
}
}
public static func parse_groupParticipants(_ reader: BufferReader) -> GroupParticipants? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.GroupCallParticipant]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.GroupCallParticipant.self)
}
var _3: [Api.User]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.phone.GroupParticipants.groupParticipants(count: _1!, participants: _2!, users: _3!)
} }
else { else {
return nil return nil
@ -7246,22 +7310,6 @@ public extension Api {
}) })
} }
public static func kickGroupCallMember(flags: Int32, call: Api.InputGroupCall, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-1731080446)
serializeInt32(flags, buffer: buffer, boxed: false)
call.serialize(buffer, true)
userId.serialize(buffer, true)
return (FunctionDescription(name: "phone.kickGroupCallMember", parameters: [("flags", flags), ("call", call), ("userId", userId)]), 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 static func discardGroupCall(call: Api.InputGroupCall) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { public static func discardGroupCall(call: Api.InputGroupCall) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(2054648117) buffer.appendInt32(2054648117)
@ -7289,6 +7337,37 @@ public extension Api {
return result return result
}) })
} }
public static func getGroupParticipants(call: Api.InputGroupCall, maxDate: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.phone.GroupParticipants>) {
let buffer = Buffer()
buffer.appendInt32(-566111310)
call.serialize(buffer, true)
serializeInt32(maxDate, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "phone.getGroupParticipants", parameters: [("call", call), ("maxDate", maxDate), ("limit", limit)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.phone.GroupParticipants? in
let reader = BufferReader(buffer)
var result: Api.phone.GroupParticipants?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.phone.GroupParticipants
}
return result
})
}
public static func checkGroupCall(call: Api.InputGroupCall, source: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1219855382)
call.serialize(buffer, true)
serializeInt32(source, buffer: buffer, boxed: false)
return (FunctionDescription(name: "phone.checkGroupCall", parameters: [("call", call), ("source", source)]), 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
})
}
} }
} }
} }

View File

@ -27,7 +27,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private enum InternalState { private enum InternalState {
case requesting case requesting
case active(GroupCallInfo) case active(GroupCallInfo)
case estabilished(GroupCallInfo, String, [UInt32: PeerId]) case estabilished(GroupCallInfo, String, [UInt32], [UInt32: PeerId])
var callInfo: GroupCallInfo? { var callInfo: GroupCallInfo? {
switch self { switch self {
@ -35,7 +35,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
return nil return nil
case let .active(info): case let .active(info):
return info return info
case let .estabilished(info, _, _): case let .estabilished(info, _, _, _):
return info return info
} }
} }
@ -224,18 +224,26 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
if case let .estabilished(callInfo, _, _) = strongSelf.internalState { if case let .estabilished(callInfo, _, _, _) = strongSelf.internalState {
var addedSsrc: [UInt32] = [] var addedSsrc: [UInt32] = []
for (callId, peerId, ssrc, _) in updates { var removedSsrc: [UInt32] = []
for (callId, peerId, ssrc, isAdded) in updates {
if callId == callInfo.id { if callId == callInfo.id {
let mappedSsrc = UInt32(bitPattern: ssrc) let mappedSsrc = UInt32(bitPattern: ssrc)
addedSsrc.append(mappedSsrc) if isAdded {
strongSelf.ssrcMapping[mappedSsrc] = peerId addedSsrc.append(mappedSsrc)
strongSelf.ssrcMapping[mappedSsrc] = peerId
} else {
removedSsrc.append(mappedSsrc)
}
} }
} }
if !addedSsrc.isEmpty { if !addedSsrc.isEmpty {
strongSelf.callContext?.addSsrcs(ssrcs: addedSsrc) strongSelf.callContext?.addSsrcs(ssrcs: addedSsrc)
} }
if !removedSsrc.isEmpty {
strongSelf.callContext?.removeSsrcs(ssrcs: removedSsrc)
}
} }
}) })
} }
@ -291,7 +299,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
return return
} }
if let clientParams = joinCallResult.callInfo.clientParams { if let clientParams = joinCallResult.callInfo.clientParams {
strongSelf.updateSessionState(internalState: .estabilished(joinCallResult.callInfo, clientParams, joinCallResult.ssrcMapping), audioSessionControl: strongSelf.audioSessionControl) strongSelf.updateSessionState(internalState: .estabilished(joinCallResult.callInfo, clientParams, joinCallResult.ssrcs, joinCallResult.ssrcMapping), audioSessionControl: strongSelf.audioSessionControl)
} }
})) }))
})) }))
@ -342,9 +350,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
case .estabilished: case .estabilished:
break break
default: default:
if case let .estabilished(_, clientParams, ssrcMapping) = internalState { if case let .estabilished(_, clientParams, ssrcs, ssrcMapping) = internalState {
self.ssrcMapping = ssrcMapping self.ssrcMapping = ssrcMapping
self.callContext?.setJoinResponse(payload: clientParams, ssrcs: Array(ssrcMapping.keys)) self.callContext?.setJoinResponse(payload: clientParams, ssrcs: ssrcs)
} }
} }
} }
@ -356,7 +364,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
public func leave() -> Signal<Bool, NoError> { public func leave() -> Signal<Bool, NoError> {
if case let .estabilished(callInfo, _, _) = self.internalState { if case let .estabilished(callInfo, _, _, _) = self.internalState {
self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash) self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash)
|> deliverOnMainQueue).start(completed: { [weak self] in |> deliverOnMainQueue).start(completed: { [weak self] in
self?._canBeRemoved.set(.single(true)) self?._canBeRemoved.set(.single(true))

View File

@ -110,7 +110,7 @@ enum AccountStateMutationOperation {
case UpdateChatListFilterOrder(order: [Int32]) case UpdateChatListFilterOrder(order: [Int32])
case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?) case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?)
case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?) case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?)
case UpdateGroupCallParticipant(id: Int64, accessHash: Int64, participant: Api.GroupCallParticipant) case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
} }
struct HoleFromPreviousState { struct HoleFromPreviousState {
@ -277,8 +277,8 @@ struct AccountMutableState {
self.addOperation(.UpdateReadThread(threadMessageId: threadMessageId, readMaxId: readMaxId, isIncoming: isIncoming, mainChannelMessage: mainChannelMessage)) self.addOperation(.UpdateReadThread(threadMessageId: threadMessageId, readMaxId: readMaxId, isIncoming: isIncoming, mainChannelMessage: mainChannelMessage))
} }
mutating func updateGroupCallParticipant(id: Int64, accessHash: Int64, participant: Api.GroupCallParticipant) { mutating func updateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32) {
self.addOperation(.UpdateGroupCallParticipant(id: id, accessHash: accessHash, participant: participant)) self.addOperation(.UpdateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version))
} }
mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) { mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) {
@ -489,7 +489,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, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipant, .UpdateMessagesPinned: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateMessagesPinned:
break break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {

View File

@ -1306,10 +1306,10 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.addUpdateCall(phoneCall) updatedState.addUpdateCall(phoneCall)
case let .updatePhoneCallSignalingData(phoneCallId, data): case let .updatePhoneCallSignalingData(phoneCallId, data):
updatedState.addCallSignalingData(callId: phoneCallId, data: data.makeData()) updatedState.addCallSignalingData(callId: phoneCallId, data: data.makeData())
case let .updateGroupCallParticipant(call, participant): case let .updateGroupCallParticipants(call, participants, version):
switch call { switch call {
case let .inputGroupCall(id, accessHash): case let .inputGroupCall(id, accessHash):
updatedState.updateGroupCallParticipant(id: id, accessHash: accessHash, participant: participant) updatedState.updateGroupCallParticipants(id: id, accessHash: accessHash, participants: participants, version: version)
} }
case let .updateLangPackTooLong(langCode): case let .updateLangPackTooLong(langCode):
updatedState.updateLangPack(langCode: langCode, difference: nil) updatedState.updateLangPack(langCode: langCode, difference: nil)
@ -2114,7 +2114,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState? var currentAddScheduledMessages: 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, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipant: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll/*, .UpdateMessageReactions*/, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants:
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))
} }
@ -2931,25 +2931,22 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
updatedCalls.append(call) updatedCalls.append(call)
case let .AddCallSignalingData(callId, data): case let .AddCallSignalingData(callId, data):
addedCallSignalingData.append((callId, data)) addedCallSignalingData.append((callId, data))
case let .UpdateGroupCallParticipant(callId, _, participant): case let .UpdateGroupCallParticipants(callId, _, participants, version):
var peerId: PeerId? for participant in participants {
var ssrc: Int32? var peerId: PeerId?
switch participant { var ssrc: Int32?
case let .groupCallParticipantAdmin(userId, source): var isAdded = true
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) switch participant {
ssrc = source case let .groupCallParticipant(flags, userId, date, source):
case let .groupCallParticipant(_, userId, _, source): peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) ssrc = source
ssrc = source if flags & (1 << 1) != 0 {
case .groupCallParticipantLeft: isAdded = false
break }
case .groupCallParticipantKicked: }
break if let peerId = peerId, let ssrc = ssrc {
case .groupCallParticipantInvited: updatedGroupCallParticipants.append((callId, peerId, ssrc, isAdded))
break }
}
if let peerId = peerId, let ssrc = ssrc {
updatedGroupCallParticipants.append((callId, peerId, ssrc, true))
} }
case let .UpdateLangPack(langCode, difference): case let .UpdateLangPack(langCode, difference):
if let difference = difference { if let difference = difference {

View File

@ -9,6 +9,7 @@ public struct GroupCallInfo: Equatable {
public var accessHash: Int64 public var accessHash: Int64
public var peerId: PeerId? public var peerId: PeerId?
public var clientParams: String? public var clientParams: String?
public var version: Int32?
} }
private extension GroupCallInfo { private extension GroupCallInfo {
@ -19,9 +20,10 @@ private extension GroupCallInfo {
id: id, id: id,
accessHash: accessHash, accessHash: accessHash,
peerId: channelId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: $0) }, peerId: channelId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: $0) },
clientParams: nil clientParams: nil,
version: nil
) )
case let .groupCall(_, id, accessHash, channelId, _, _, params): case let .groupCall(_, id, accessHash, channelId, _, _, params, version):
var clientParams: String? var clientParams: String?
if let params = params { if let params = params {
switch params { switch params {
@ -33,7 +35,8 @@ private extension GroupCallInfo {
id: id, id: id,
accessHash: accessHash, accessHash: accessHash,
peerId: channelId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: $0) }, peerId: channelId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: $0) },
clientParams: clientParams clientParams: clientParams,
version: version
) )
case .groupCallDiscarded: case .groupCallDiscarded:
return nil return nil
@ -50,7 +53,7 @@ public func getCurrentGroupCall(account: Account, peerId: PeerId) -> Signal<Grou
transaction.getPeer(peerId).flatMap(apiInputChannel) transaction.getPeer(peerId).flatMap(apiInputChannel)
} }
|> castError(GetCurrentGroupCallError.self) |> castError(GetCurrentGroupCallError.self)
|> mapToSignal { inputPeer -> Signal<MessageId?, GetCurrentGroupCallError> in |> mapToSignal { inputPeer -> Signal<Api.InputGroupCall?, GetCurrentGroupCallError> in
guard let inputPeer = inputPeer else { guard let inputPeer = inputPeer else {
return .fail(.generic) return .fail(.generic)
} }
@ -58,99 +61,36 @@ public func getCurrentGroupCall(account: Account, peerId: PeerId) -> Signal<Grou
|> mapError { _ -> GetCurrentGroupCallError in |> mapError { _ -> GetCurrentGroupCallError in
return .generic return .generic
} }
|> mapToSignal { result -> Signal<MessageId?, GetCurrentGroupCallError> in |> mapToSignal { result -> Signal<Api.InputGroupCall?, GetCurrentGroupCallError> in
switch result { switch result {
case let .chatFull(fullChat, _, _): case let .chatFull(fullChat, _, _):
switch fullChat { switch fullChat {
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, callMsgId): case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, inputCall):
return .single(callMsgId.flatMap { callMsgId in return .single(inputCall)
MessageId(peerId: peerId, namespace: Namespaces.Peer.CloudChannel, id: callMsgId)
})
default: default:
return .single(nil) return .single(nil)
} }
default:
return .single(nil)
} }
} }
} }
|> mapToSignal { messageId -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in |> mapToSignal { inputCall -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in
guard let messageId = messageId else { guard let inputCall = inputCall else {
return .single(nil) return .single(nil)
} }
return account.postbox.transaction { transaction -> Api.InputChannel? in
return transaction.getPeer(peerId).flatMap(apiInputChannel) return account.network.request(Api.functions.phone.getGroupCall(call: inputCall))
|> mapError { _ -> GetCurrentGroupCallError in
return .generic
} }
|> castError(GetCurrentGroupCallError.self) |> mapToSignal { result -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in
|> mapToSignal { inputPeer -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in switch result {
guard let inputPeer = inputPeer else { case let .groupCall(call, sources, participants, chats, users):
return .fail(.generic) return account.postbox.transaction { transaction -> GroupCallInfo? in
} return GroupCallInfo(call)
return account.network.request(Api.functions.channels.getMessages(channel: inputPeer, id: [.inputMessageID(id: messageId.id)]))
|> mapError { _ -> GetCurrentGroupCallError in
return .generic
}
|> mapToSignal { result -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in
let messages: [Api.Message]
let chats: [Api.Chat]
let users: [Api.User]
switch result {
case let .messages(apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
case .messagesNotModified:
return .fail(.generic)
} }
guard let apiMessage = messages.first else {
return .single(nil)
}
guard let message = StoreMessage(apiMessage: apiMessage) else {
return .fail(.generic)
}
var maybeInputCall: Api.InputGroupCall?
loop: for media in message.media {
if let action = media as? TelegramMediaAction {
switch action.action {
case let .groupPhoneCall(callId, accessHash, _):
maybeInputCall = .inputGroupCall(id: callId, accessHash: accessHash)
break loop
default:
break
}
}
}
guard let inputCall = maybeInputCall else {
return .fail(.generic)
}
return account.network.request(Api.functions.phone.getGroupCall(call: inputCall))
|> mapError { _ -> GetCurrentGroupCallError in |> mapError { _ -> GetCurrentGroupCallError in
return .generic return .generic
} }
|> mapToSignal { result -> Signal<GroupCallInfo?, GetCurrentGroupCallError> in
switch result {
case let .groupCall(call, participants, chats, users):
return account.postbox.transaction { transaction -> GroupCallInfo? in
return GroupCallInfo(call)
}
|> mapError { _ -> GetCurrentGroupCallError in
return .generic
}
}
}
} }
} }
} }
@ -203,6 +143,7 @@ public enum JoinGroupCallError {
public struct JoinGroupCallResult { public struct JoinGroupCallResult {
public var callInfo: GroupCallInfo public var callInfo: GroupCallInfo
public var ssrcs: [UInt32]
public var ssrcMapping: [UInt32: PeerId] public var ssrcMapping: [UInt32: PeerId]
} }
@ -235,7 +176,7 @@ public func joinGroupCall(account: Account, callId: Int64, accessHash: Int64, jo
} }
switch result { switch result {
case let .groupCall(call, participants, chats, users): case let .groupCall(call, sources, participants, chats, users):
guard let _ = GroupCallInfo(call) else { guard let _ = GroupCallInfo(call) else {
return .fail(.generic) return .fail(.generic)
} }
@ -244,18 +185,9 @@ public func joinGroupCall(account: Account, callId: Int64, accessHash: Int64, jo
var peerId: PeerId? var peerId: PeerId?
var ssrc: UInt32? var ssrc: UInt32?
switch participant { switch participant {
case let .groupCallParticipantAdmin(userId, source): case let .groupCallParticipant(flags, userId, date, source):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
ssrc = UInt32(bitPattern: source) ssrc = UInt32(bitPattern: source)
case let .groupCallParticipant(_, userId, _, source):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
ssrc = UInt32(bitPattern: source)
case .groupCallParticipantLeft:
break
case .groupCallParticipantKicked:
break
case .groupCallParticipantInvited:
break
} }
if let peerId = peerId, let ssrc = ssrc { if let peerId = peerId, let ssrc = ssrc {
ssrcMapping[ssrc] = peerId ssrcMapping[ssrc] = peerId
@ -264,6 +196,7 @@ public func joinGroupCall(account: Account, callId: Int64, accessHash: Int64, jo
return account.postbox.transaction { transaction -> JoinGroupCallResult in return account.postbox.transaction { transaction -> JoinGroupCallResult in
return JoinGroupCallResult( return JoinGroupCallResult(
callInfo: parsedCall, callInfo: parsedCall,
ssrcs: sources.map(UInt32.init(bitPattern:)),
ssrcMapping: ssrcMapping ssrcMapping: ssrcMapping
) )
} }

View File

@ -346,7 +346,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
} }
switch fullChat { switch fullChat {
case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts, callMsgId): case let .channelFull(flags, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, folderId, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, pts, inputCall):
var channelFlags = CachedChannelFlags() var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants) channelFlags.insert(.canDisplayParticipants)
@ -396,9 +396,12 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
pinnedMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: pinnedMsgId) pinnedMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: pinnedMsgId)
} }
var updatedActiveCallMessageId: MessageId? var updatedActiveCall: CachedChannelData.ActiveCall?
if let callMsgId = callMsgId { if let inputCall = inputCall {
updatedActiveCallMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: callMsgId) switch inputCall {
case let .inputGroupCall(id, accessHash):
updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash)
}
} }
var minAvailableMessageId: MessageId? var minAvailableMessageId: MessageId?
@ -515,7 +518,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
.withUpdatedStatsDatacenterId(statsDc ?? 0) .withUpdatedStatsDatacenterId(statsDc ?? 0)
.withUpdatedInvitedBy(invitedBy) .withUpdatedInvitedBy(invitedBy)
.withUpdatedPhoto(photo) .withUpdatedPhoto(photo)
.withUpdatedActiveCallMessageId(updatedActiveCallMessageId) .withUpdatedActiveCall(updatedActiveCall)
}) })
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated { if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {

View File

@ -147,7 +147,7 @@ final class ChatCallTitlePanelNode: ChatTitleAccessoryPanelNode {
guard let activeGroupCallInfo = self.activeGroupCallInfo else { guard let activeGroupCallInfo = self.activeGroupCallInfo else {
return return
} }
interfaceInteraction.joinGroupCall(activeGroupCallInfo.messageId) interfaceInteraction.joinGroupCall(activeGroupCallInfo.activeCall)
} }
} }

View File

@ -3750,8 +3750,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp)) slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp))
} }
} }
if let messageId = cachedData.activeCallMessageId { if let activeCall = cachedData.activeCall {
activeGroupCallInfo = ChatActiveGroupCallInfo(messageId: messageId) activeGroupCallInfo = ChatActiveGroupCallInfo(activeCall: activeCall)
} }
} else if let cachedData = combinedInitialData.cachedData as? CachedUserData { } else if let cachedData = combinedInitialData.cachedData as? CachedUserData {
peerIsBlocked = cachedData.isBlocked peerIsBlocked = cachedData.isBlocked
@ -3905,8 +3905,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp)) slowmodeState = ChatSlowmodeState(timeout: timeout, variant: .timestamp(slowmodeUntilTimestamp))
} }
} }
if let messageId = cachedData.activeCallMessageId { if let activeCall = cachedData.activeCall {
activeGroupCallInfo = ChatActiveGroupCallInfo(messageId: messageId) activeGroupCallInfo = ChatActiveGroupCallInfo(activeCall: activeCall)
} }
} else if let cachedData = cachedData as? CachedUserData { } else if let cachedData = cachedData as? CachedUserData {
peerIsBlocked = cachedData.isBlocked peerIsBlocked = cachedData.isBlocked
@ -5978,6 +5978,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
chatController.canReadHistory.set(false) chatController.canReadHistory.set(false)
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, passthroughTouches: true)), items: .single(items), reactionItems: [], gesture: gesture) let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, passthroughTouches: true)), items: .single(items), reactionItems: [], gesture: gesture)
strongSelf.presentInGlobalOverlay(contextController) strongSelf.presentInGlobalOverlay(contextController)
}, joinGroupCall: { [weak self] activeCall in
}, editMessageMedia: { [weak self] messageId, draw in }, editMessageMedia: { [weak self] messageId, draw in
if let strongSelf = self { if let strongSelf = self {
strongSelf.controllerInteraction?.editMessageMedia(messageId, draw) strongSelf.controllerInteraction?.editMessageMedia(messageId, draw)

View File

@ -127,8 +127,8 @@ final class ChatPanelInterfaceInteraction {
let viewReplies: (MessageId?, ChatReplyThreadMessage) -> Void let viewReplies: (MessageId?, ChatReplyThreadMessage) -> Void
let activatePinnedListPreview: (ASDisplayNode, ContextGesture) -> Void let activatePinnedListPreview: (ASDisplayNode, ContextGesture) -> Void
let editMessageMedia: (MessageId, Bool) -> Void let editMessageMedia: (MessageId, Bool) -> Void
let joinGroupCall: (CachedChannelData.ActiveCall) -> Void
let statuses: ChatPanelInterfaceInteractionStatuses? let statuses: ChatPanelInterfaceInteractionStatuses?
let joinGroupCall: (MessageId) -> Void
init( init(
setupReplyMessage: @escaping (MessageId, @escaping (ContainedViewLayoutTransition) -> Void) -> Void, setupReplyMessage: @escaping (MessageId, @escaping (ContainedViewLayoutTransition) -> Void) -> Void,
@ -207,8 +207,8 @@ final class ChatPanelInterfaceInteraction {
scrollToTop: @escaping () -> Void, scrollToTop: @escaping () -> Void,
viewReplies: @escaping (MessageId?, ChatReplyThreadMessage) -> Void, viewReplies: @escaping (MessageId?, ChatReplyThreadMessage) -> Void,
activatePinnedListPreview: @escaping (ASDisplayNode, ContextGesture) -> Void, activatePinnedListPreview: @escaping (ASDisplayNode, ContextGesture) -> Void,
editMessageMedia: @escaping (MessageId, Bool) -> Void,
joinGroupCall: @escaping (MessageId) -> Void, joinGroupCall: @escaping (MessageId) -> Void,
editMessageMedia: @escaping (MessageId, Bool) -> Void,
statuses: ChatPanelInterfaceInteractionStatuses? statuses: ChatPanelInterfaceInteractionStatuses?
) { ) {
self.setupReplyMessage = setupReplyMessage self.setupReplyMessage = setupReplyMessage

View File

@ -294,7 +294,7 @@ final class ChatPinnedMessage: Equatable {
} }
struct ChatActiveGroupCallInfo: Equatable { struct ChatActiveGroupCallInfo: Equatable {
var messageId: MessageId var activeCall: CachedChannelData.ActiveCall
} }
final class ChatPresentationInterfaceState: Equatable { final class ChatPresentationInterfaceState: Equatable {

View File

@ -26,411 +26,6 @@ private final class ContextQueueImpl: NSObject, OngoingCallThreadLocalContextQue
} }
} }
private struct ParsedJoinPayload {
var payload: String
var audioSsrc: UInt32
}
private func parseSdpIntoJoinPayload(sdp: String) -> ParsedJoinPayload? {
let lines = sdp.components(separatedBy: "\n")
var videoLines: [String] = []
var audioLines: [String] = []
var isAudioLine = false
var isVideoLine = false
for line in lines {
if line.hasPrefix("m=audio") {
isAudioLine = true
isVideoLine = false
} else if line.hasPrefix("m=video") {
isVideoLine = true
isAudioLine = false
}
if isAudioLine {
audioLines.append(line)
} else if isVideoLine {
videoLines.append(line)
}
}
func getLines(prefix: String) -> [String] {
var result: [String] = []
for line in lines {
if line.hasPrefix(prefix) {
var cleanLine = String(line[line.index(line.startIndex, offsetBy: prefix.count)...])
if cleanLine.hasSuffix("\r") {
cleanLine.removeLast()
}
result.append(cleanLine)
}
}
return result
}
func getLines(prefix: String, isAudio: Bool) -> [String] {
var result: [String] = []
for line in (isAudio ? audioLines : videoLines) {
if line.hasPrefix(prefix) {
var cleanLine = String(line[line.index(line.startIndex, offsetBy: prefix.count)...])
if cleanLine.hasSuffix("\r") {
cleanLine.removeLast()
}
result.append(cleanLine)
}
}
return result
}
var audioSources: [Int] = []
for line in getLines(prefix: "a=ssrc:", isAudio: true) {
let scanner = Scanner(string: line)
if #available(iOS 13.0, *) {
if let ssrc = scanner.scanInt() {
if !audioSources.contains(ssrc) {
audioSources.append(ssrc)
}
}
}
}
guard let ssrc = audioSources.first else {
return nil
}
guard let ufrag = getLines(prefix: "a=ice-ufrag:").first else {
return nil
}
guard let pwd = getLines(prefix: "a=ice-pwd:").first else {
return nil
}
var resultPayload: [String: Any] = [:]
var fingerprints: [[String: Any]] = []
for line in getLines(prefix: "a=fingerprint:") {
let components = line.components(separatedBy: " ")
if components.count != 2 {
continue
}
fingerprints.append([
"hash": components[0],
"fingerprint": components[1],
"setup": "active"
])
}
resultPayload["fingerprints"] = fingerprints
resultPayload["ufrag"] = ufrag
resultPayload["pwd"] = pwd
resultPayload["ssrc"] = ssrc
guard let payloadData = try? JSONSerialization.data(withJSONObject: resultPayload, options: []) else {
return nil
}
guard let payloadString = String(data: payloadData, encoding: .utf8) else {
return nil
}
return ParsedJoinPayload(
payload: payloadString,
audioSsrc: UInt32(ssrc)
)
}
private func parseJoinResponseIntoSdp(sessionId: UInt32, mainStreamAudioSsrc: UInt32, payload: String, isAnswer: Bool, otherSsrcs: [UInt32]) -> String? {
guard let payloadData = payload.data(using: .utf8) else {
return nil
}
guard let jsonPayload = try? JSONSerialization.jsonObject(with: payloadData, options: []) as? [String: Any] else {
return nil
}
guard let transport = jsonPayload["transport"] as? [String: Any] else {
return nil
}
guard let pwd = transport["pwd"] as? String else {
return nil
}
guard let ufrag = transport["ufrag"] as? String else {
return nil
}
struct ParsedFingerprint {
var hashValue: String
var fingerprint: String
var setup: String
}
var fingerprints: [ParsedFingerprint] = []
guard let fingerprintsValue = transport["fingerprints"] as? [[String: Any]] else {
return nil
}
for fingerprintValue in fingerprintsValue {
guard let hashValue = fingerprintValue["hash"] as? String else {
continue
}
guard let fingerprint = fingerprintValue["fingerprint"] as? String else {
continue
}
guard let setup = fingerprintValue["setup"] as? String else {
continue
}
fingerprints.append(ParsedFingerprint(
hashValue: hashValue,
fingerprint: fingerprint,
setup: setup
))
}
struct ParsedCandidate {
var port: String
var `protocol`: String
var network: String
var generation: String
var id: String
var component: String
var foundation: String
var priority: String
var ip: String
var type: String
var tcpType: String?
var relAddr: String?
var relPort: String?
}
var candidates: [ParsedCandidate] = []
guard let candidatesValue = transport["candidates"] as? [[String: Any]] else {
return nil
}
for candidateValue in candidatesValue {
guard let port = candidateValue["port"] as? String else {
continue
}
guard let `protocol` = candidateValue["protocol"] as? String else {
continue
}
guard let network = candidateValue["network"] as? String else {
continue
}
guard let generation = candidateValue["generation"] as? String else {
continue
}
guard let id = candidateValue["id"] as? String else {
continue
}
guard let component = candidateValue["component"] as? String else {
continue
}
guard let foundation = candidateValue["foundation"] as? String else {
continue
}
guard let priority = candidateValue["priority"] as? String else {
continue
}
guard let ip = candidateValue["ip"] as? String else {
continue
}
guard let type = candidateValue["type"] as? String else {
continue
}
let tcpType = candidateValue["tcptype"] as? String
let relAddr = candidateValue["rel-addr"] as? String
let relPort = candidateValue["rel-port"] as? String
candidates.append(ParsedCandidate(
port: port,
protocol: `protocol`,
network: network,
generation: generation,
id: id,
component: component,
foundation: foundation,
priority: priority,
ip: ip,
type: type,
tcpType: tcpType,
relAddr: relAddr,
relPort: relPort
))
}
struct StreamSpec {
var isMain: Bool
var audioSsrc: Int
var isRemoved: Bool
}
func createSdp(sessionId: UInt32, bundleStreams: [StreamSpec]) -> String {
var sdp = ""
func appendSdp(_ string: String) {
if !sdp.isEmpty {
sdp.append("\n")
}
sdp.append(string)
}
appendSdp("v=0")
appendSdp("o=- \(sessionId) 2 IN IP4 0.0.0.0")
appendSdp("s=-")
appendSdp("t=0 0")
var bundleString = "a=group:BUNDLE"
for stream in bundleStreams {
bundleString.append(" ")
let audioMid: String
if stream.isMain {
audioMid = "0"
} else {
audioMid = "audio\(stream.audioSsrc)"
}
bundleString.append("\(audioMid)")
}
appendSdp(bundleString)
appendSdp("a=ice-lite")
for stream in bundleStreams {
let audioMid: String
if stream.isMain {
audioMid = "0"
} else {
audioMid = "audio\(stream.audioSsrc)"
}
appendSdp("m=audio \(stream.isMain ? "1" : "0") RTP/SAVPF 111 126")
if stream.isMain {
appendSdp("c=IN IP4 0.0.0.0")
}
appendSdp("a=mid:\(audioMid)")
if stream.isRemoved {
appendSdp("a=inactive")
} else {
if stream.isMain {
appendSdp("a=ice-ufrag:\(ufrag)")
appendSdp("a=ice-pwd:\(pwd)")
for fingerprint in fingerprints {
appendSdp("a=fingerprint:\(fingerprint.hashValue) \(fingerprint.fingerprint)")
appendSdp("a=setup:passive")
}
for candidate in candidates {
var candidateString = "a=candidate:"
candidateString.append("\(candidate.foundation) ")
candidateString.append("\(candidate.component) ")
var protocolValue = candidate.protocol
if protocolValue == "ssltcp" {
protocolValue = "tcp"
}
candidateString.append("\(protocolValue) ")
candidateString.append("\(candidate.priority) ")
let ip = candidate.ip
candidateString.append("\(ip) ")
candidateString.append("\(candidate.port) ")
candidateString.append("typ \(candidate.type) ")
switch candidate.type {
case "srflx", "prflx", "relay":
if let relAddr = candidate.relAddr, let relPort = candidate.relPort {
candidateString.append("raddr \(relAddr) rport \(relPort) ")
}
break
default:
break
}
if protocolValue == "tcp" {
guard let tcpType = candidate.tcpType else {
continue
}
candidateString.append("tcptype \(tcpType) ")
}
candidateString.append("generation \(candidate.generation)")
appendSdp(candidateString)
}
}
appendSdp("a=rtpmap:111 opus/48000/2")
appendSdp("a=rtpmap:126 telephone-event/8000")
appendSdp("a=fmtp:111 minptime=10; useinbandfec=1; usedtx=1")
appendSdp("a=rtcp:1 IN IP4 0.0.0.0")
appendSdp("a=rtcp-mux")
appendSdp("a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level")
appendSdp("a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time")
appendSdp("a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01")
appendSdp("a=rtcp-fb:111 transport-cc")
if isAnswer {
appendSdp("a=recvonly")
} else {
if stream.isMain {
appendSdp("a=sendrecv")
} else {
appendSdp("a=sendonly")
appendSdp("a=bundle-only")
}
appendSdp("a=ssrc-group:FID \(stream.audioSsrc)")
appendSdp("a=ssrc:\(stream.audioSsrc) cname:stream\(stream.audioSsrc)")
appendSdp("a=ssrc:\(stream.audioSsrc) msid:stream\(stream.audioSsrc) audio\(stream.audioSsrc)")
appendSdp("a=ssrc:\(stream.audioSsrc) mslabel:audio\(stream.audioSsrc)")
appendSdp("a=ssrc:\(stream.audioSsrc) label:audio\(stream.audioSsrc)")
}
}
}
appendSdp("")
return sdp
}
var bundleStreams: [StreamSpec] = []
bundleStreams.append(StreamSpec(
isMain: true,
audioSsrc: Int(mainStreamAudioSsrc),
isRemoved: false
))
for ssrc in otherSsrcs {
bundleStreams.append(StreamSpec(
isMain: false,
audioSsrc: Int(ssrc),
isRemoved: false
))
}
/*var bundleStreams: [StreamSpec] = []
if let currentState = currentState {
for item in currentState.items {
let isRemoved = !streams.contains(where: { $0.audioSsrc == item.audioSsrc })
bundleStreams.append(StreamSpec(
isMain: item.audioSsrc == mainStreamAudioSsrc,
audioSsrc: item.audioSsrc,
videoSsrc: item.videoSsrc,
isRemoved: isRemoved
))
}
}
for stream in streams {
if bundleStreams.contains(where: { $0.audioSsrc == stream.audioSsrc }) {
continue
}
bundleStreams.append(stream)
}*/
return createSdp(sessionId: sessionId, bundleStreams: bundleStreams)
}
public final class OngoingGroupCallContext { public final class OngoingGroupCallContext {
public enum NetworkState { public enum NetworkState {
case connecting case connecting
@ -447,25 +42,29 @@ public final class OngoingGroupCallContext {
let sessionId = UInt32.random(in: 0 ..< UInt32(Int32.max)) let sessionId = UInt32.random(in: 0 ..< UInt32(Int32.max))
var mainStreamAudioSsrc: UInt32? var mainStreamAudioSsrc: UInt32?
var initialAnswerPayload: String?
var otherSsrcs: [UInt32] = [] var otherSsrcs: [UInt32] = []
let joinPayload = Promise<String>() let joinPayload = Promise<String>()
let networkState = ValuePromise<NetworkState>(.connecting, ignoreRepeated: true) let networkState = ValuePromise<NetworkState>(.connecting, ignoreRepeated: true)
let isMuted = ValuePromise<Bool>(true, ignoreRepeated: true) let isMuted = ValuePromise<Bool>(true, ignoreRepeated: true)
let memberStates = ValuePromise<[UInt32: MemberState]>([:], ignoreRepeated: true) let memberStates = ValuePromise<[UInt32: MemberState]>([:], ignoreRepeated: true)
let audioLevels = ValuePipe<[(UInt32, Float)]>()
init(queue: Queue) { init(queue: Queue) {
self.queue = queue self.queue = queue
var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)? var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)?
var audioLevelsUpdatedImpl: (([NSNumber]) -> Void)?
self.context = GroupCallThreadLocalContext(queue: ContextQueueImpl(queue: queue), relaySdpAnswer: { _ in self.context = GroupCallThreadLocalContext(
}, incomingVideoStreamListUpdated: { _ in queue: ContextQueueImpl(queue: queue),
}, videoCapturer: nil, networkStateUpdated: { state in
networkStateUpdated: { state in networkStateUpdatedImpl?(state)
networkStateUpdatedImpl?(state) },
}) audioLevelsUpdated: { levels in
audioLevelsUpdatedImpl?(levels)
}
)
let queue = self.queue let queue = self.queue
@ -487,30 +86,33 @@ public final class OngoingGroupCallContext {
} }
} }
self.context.emitOffer(adjustSdp: { sdp in let audioLevels = self.audioLevels
return sdp audioLevelsUpdatedImpl = { levels in
}, completion: { [weak self] offerSdp in var mappedLevels: [(UInt32, Float)] = []
var i = 0
while i < levels.count {
mappedLevels.append((levels[i].uint32Value, levels[i + 1].floatValue))
i += 2
}
queue.async {
audioLevels.putNext(mappedLevels)
}
}
self.context.emitJoinPayload({ [weak self] payload, ssrc in
queue.async { queue.async {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
if let payload = parseSdpIntoJoinPayload(sdp: offerSdp) { strongSelf.mainStreamAudioSsrc = ssrc
strongSelf.mainStreamAudioSsrc = payload.audioSsrc strongSelf.joinPayload.set(.single(payload))
strongSelf.joinPayload.set(.single(payload.payload))
}
} }
}) })
} }
func setJoinResponse(payload: String, ssrcs: [UInt32]) { func setJoinResponse(payload: String, ssrcs: [UInt32]) {
guard let mainStreamAudioSsrc = self.mainStreamAudioSsrc else { self.context.setJoinResponsePayload(payload)
return self.addSsrcs(ssrcs: ssrcs)
}
if let sdp = parseJoinResponseIntoSdp(sessionId: self.sessionId, mainStreamAudioSsrc: mainStreamAudioSsrc, payload: payload, isAnswer: true, otherSsrcs: []) {
self.initialAnswerPayload = payload
self.context.setOfferSdp(sdp, isPartial: true)
self.addSsrcs(ssrcs: ssrcs)
}
} }
func addSsrcs(ssrcs: [UInt32]) { func addSsrcs(ssrcs: [UInt32]) {
@ -520,9 +122,6 @@ public final class OngoingGroupCallContext {
guard let mainStreamAudioSsrc = self.mainStreamAudioSsrc else { guard let mainStreamAudioSsrc = self.mainStreamAudioSsrc else {
return return
} }
guard let initialAnswerPayload = self.initialAnswerPayload else {
return
}
let mappedSsrcs = ssrcs let mappedSsrcs = ssrcs
var otherSsrcs = self.otherSsrcs var otherSsrcs = self.otherSsrcs
for ssrc in mappedSsrcs { for ssrc in mappedSsrcs {
@ -541,9 +140,33 @@ public final class OngoingGroupCallContext {
} }
self.memberStates.set(memberStatesValue) self.memberStates.set(memberStatesValue)
if let sdp = parseJoinResponseIntoSdp(sessionId: self.sessionId, mainStreamAudioSsrc: mainStreamAudioSsrc, payload: initialAnswerPayload, isAnswer: false, otherSsrcs: self.otherSsrcs) { self.context.setSsrcs(self.otherSsrcs.map { ssrc in
self.context.setOfferSdp(sdp, isPartial: false) return ssrc as NSNumber
})
}
}
func removeSsrcs(ssrcs: [UInt32]) {
if ssrcs.isEmpty {
return
}
guard let mainStreamAudioSsrc = self.mainStreamAudioSsrc else {
return
}
var otherSsrcs = self.otherSsrcs.filter { ssrc in
return !ssrcs.contains(ssrc)
}
if self.otherSsrcs != otherSsrcs {
self.otherSsrcs = otherSsrcs
var memberStatesValue: [UInt32: MemberState] = [:]
for ssrc in otherSsrcs {
memberStatesValue[ssrc] = MemberState(isSpeaking: false)
} }
self.memberStates.set(memberStatesValue)
self.context.setSsrcs(self.otherSsrcs.map { ssrc in
return ssrc as NSNumber
})
} }
} }
@ -592,6 +215,18 @@ public final class OngoingGroupCallContext {
} }
} }
public var audioLevels: Signal<[(UInt32, Float)], NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
self.impl.with { impl in
disposable.set(impl.audioLevels.signal().start(next: { value in
subscriber.putNext(value)
}))
}
return disposable
}
}
public var isMuted: Signal<Bool, NoError> { public var isMuted: Signal<Bool, NoError> {
return Signal { subscriber in return Signal { subscriber in
let disposable = MetaDisposable() let disposable = MetaDisposable()
@ -628,4 +263,10 @@ public final class OngoingGroupCallContext {
impl.addSsrcs(ssrcs: ssrcs) impl.addSsrcs(ssrcs: ssrcs)
} }
} }
public func removeSsrcs(ssrcs: [UInt32]) {
self.impl.with { impl in
impl.removeSsrcs(ssrcs: ssrcs)
}
}
} }

View File

@ -158,12 +158,12 @@ typedef NS_ENUM(int32_t, GroupCallNetworkState) {
@interface GroupCallThreadLocalContext : NSObject @interface GroupCallThreadLocalContext : NSObject
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue relaySdpAnswer:(void (^ _Nonnull)(NSString * _Nonnull))relaySdpAnswer incomingVideoStreamListUpdated:(void (^ _Nonnull)(NSArray<NSString *> * _Nonnull))incomingVideoStreamListUpdated videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated; - (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated;
- (void)emitOfferWithAdjustSdp:(NSString * _Nonnull (^ _Nonnull)(NSString * _Nonnull))adjustSdp completion:(void (^ _Nonnull)(NSString * _Nonnull))completion; - (void)emitJoinPayload:(void (^ _Nonnull)(NSString * _Nonnull, uint32_t))completion;
- (void)setOfferSdp:(NSString * _Nonnull)offerSdp isPartial:(bool)isPartial; - (void)setJoinResponsePayload:(NSString * _Nonnull)payload;
- (void)setSsrcs:(NSArray<NSNumber *> * _Nonnull)ssrcs;
- (void)setIsMuted:(bool)isMuted; - (void)setIsMuted:(bool)isMuted;
- (void)makeIncomingVideoViewWithStreamId:(NSString * _Nonnull)streamId completion:(void (^_Nonnull)(UIView<OngoingCallThreadLocalContextWebrtcVideoView> * _Nullable))completion;
@end @end

View File

@ -808,40 +808,15 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
@implementation GroupCallThreadLocalContext @implementation GroupCallThreadLocalContext
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue relaySdpAnswer:(void (^ _Nonnull)(NSString * _Nonnull))relaySdpAnswer incomingVideoStreamListUpdated:(void (^ _Nonnull)(NSArray<NSString *> * _Nonnull))incomingVideoStreamListUpdated videoCapturer:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated { - (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueueWebrtc> _Nonnull)queue networkStateUpdated:(void (^ _Nonnull)(GroupCallNetworkState))networkStateUpdated audioLevelsUpdated:(void (^ _Nonnull)(NSArray<NSNumber *> * _Nonnull))audioLevelsUpdated {
self = [super init]; self = [super init];
if (self != nil) { if (self != nil) {
_queue = queue; _queue = queue;
_videoCapturer = videoCapturer;
_networkStateUpdated = [networkStateUpdated copy]; _networkStateUpdated = [networkStateUpdated copy];
__weak GroupCallThreadLocalContext *weakSelf = self; __weak GroupCallThreadLocalContext *weakSelf = self;
_instance.reset(new tgcalls::GroupInstanceImpl((tgcalls::GroupInstanceDescriptor){ _instance.reset(new tgcalls::GroupInstanceImpl((tgcalls::GroupInstanceDescriptor){
.sdpAnswerEmitted = [weakSelf, queue, relaySdpAnswer](std::string const &sdpAnswer) {
NSString *string = [NSString stringWithUTF8String:sdpAnswer.c_str()];
[queue dispatch:^{
__strong GroupCallThreadLocalContext *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
relaySdpAnswer(string);
}];
},
.incomingVideoStreamListUpdated = [weakSelf, queue, incomingVideoStreamListUpdated](std::vector<std::string> const &incomingVideoStreamList) {
NSMutableArray<NSString *> *mappedList = [[NSMutableArray alloc] init];
for (auto &it : incomingVideoStreamList) {
[mappedList addObject:[NSString stringWithUTF8String:it.c_str()]];
}
[queue dispatch:^{
__strong GroupCallThreadLocalContext *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
incomingVideoStreamListUpdated(mappedList);
}];
},
.videoCapture = [_videoCapturer getInterface],
.networkStateUpdated = [weakSelf, queue, networkStateUpdated](bool isConnected) { .networkStateUpdated = [weakSelf, queue, networkStateUpdated](bool isConnected) {
[queue dispatch:^{ [queue dispatch:^{
__strong GroupCallThreadLocalContext *strongSelf = weakSelf; __strong GroupCallThreadLocalContext *strongSelf = weakSelf;
@ -850,28 +825,204 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
} }
networkStateUpdated(isConnected ? GroupCallNetworkStateConnected : GroupCallNetworkStateConnecting); networkStateUpdated(isConnected ? GroupCallNetworkStateConnected : GroupCallNetworkStateConnecting);
}]; }];
},
.audioLevelsUpdated = [weakSelf, queue, audioLevelsUpdated](std::vector<std::pair<uint32_t, float>> const &levels) {
NSMutableArray *result = [[NSMutableArray alloc] init];
for (auto &it : levels) {
[result addObject:@(it.first)];
[result addObject:@(it.second)];
}
} }
})); }));
} }
return self; return self;
} }
- (void)emitOfferWithAdjustSdp:(NSString * _Nonnull (^ _Nonnull)(NSString * _Nonnull))adjustSdp completion:(void (^ _Nonnull)(NSString * _Nonnull))completion { - (void)emitJoinPayload:(void (^ _Nonnull)(NSString * _Nonnull, uint32_t))completion {
if (_instance) { if (_instance) {
_instance->emitOffer([adjustSdp](std::string const &sdp) { _instance->emitJoinPayload([completion](tgcalls::GroupJoinPayload payload) {
NSString *string = [NSString stringWithUTF8String:sdp.c_str()]; NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSString *result = adjustSdp(string);
return result.UTF8String; int32_t signedSsrc = *(int32_t *)&payload.ssrc;
}, [completion](std::string const &sdp) {
NSString *string = [NSString stringWithUTF8String:sdp.c_str()]; dict[@"ssrc"] = @(signedSsrc);
completion(string); dict[@"ufrag"] = [NSString stringWithUTF8String:payload.ufrag.c_str()];
dict[@"pwd"] = [NSString stringWithUTF8String:payload.pwd.c_str()];
NSMutableArray *fingerprints = [[NSMutableArray alloc] init];
for (auto &fingerprint : payload.fingerprints) {
[fingerprints addObject:@{
@"hash": [NSString stringWithUTF8String:fingerprint.hash.c_str()],
@"fingerprint": [NSString stringWithUTF8String:fingerprint.fingerprint.c_str()],
@"setup": [NSString stringWithUTF8String:fingerprint.setup.c_str()]
}];
}
dict[@"fingerprints"] = fingerprints;
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
completion(string, payload.ssrc);
}); });
} }
} }
- (void)setOfferSdp:(NSString * _Nonnull)offerSdp isPartial:(bool)isPartial { - (void)setJoinResponsePayload:(NSString * _Nonnull)payload {
tgcalls::GroupJoinResponsePayload result;
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
if (payloadData == nil) {
return;
}
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:payloadData options:0 error:nil];
if (![dict isKindOfClass:[NSDictionary class]]) {
return;
}
NSDictionary *transport = dict[@"transport"];
if (![transport isKindOfClass:[NSDictionary class]]) {
return;
}
NSString *pwd = transport[@"pwd"];
if (![pwd isKindOfClass:[NSString class]]) {
return;
}
NSString *ufrag = transport[@"ufrag"];
if (![ufrag isKindOfClass:[NSString class]]) {
return;
}
result.pwd = [pwd UTF8String];
result.ufrag = [ufrag UTF8String];
NSArray *fingerprintsValue = transport[@"fingerprints"];
if (![fingerprintsValue isKindOfClass:[NSArray class]]) {
return;
}
for (NSDictionary *fingerprintValue in fingerprintsValue) {
if (![fingerprintValue isKindOfClass:[NSDictionary class]]) {
continue;
}
NSString *hashValue = fingerprintValue[@"hash"];
if (![hashValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *fingerprint = fingerprintValue[@"fingerprint"];
if (![fingerprint isKindOfClass:[NSString class]]) {
continue;
}
NSString *setup = fingerprintValue[@"setup"];
if (![setup isKindOfClass:[NSString class]]) {
continue;
}
tgcalls::GroupJoinPayloadFingerprint parsed;
parsed.fingerprint = [fingerprint UTF8String];
parsed.setup = [setup UTF8String];
parsed.hash = [hashValue UTF8String];
result.fingerprints.push_back(parsed);
}
NSArray *candidatesValue = transport[@"candidates"];
if (![candidatesValue isKindOfClass:[NSArray class]]) {
return;
}
for (NSDictionary *candidateValue in candidatesValue) {
if (![candidateValue isKindOfClass:[NSDictionary class]]) {
continue;
}
NSString *portValue = candidateValue[@"port"];
if (![portValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *protocolValue = candidateValue[@"protocol"];
if (![protocolValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *networkValue = candidateValue[@"network"];
if (![networkValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *generationValue = candidateValue[@"generation"];
if (![generationValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *idValue = candidateValue[@"id"];
if (![idValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *componentValue = candidateValue[@"component"];
if (![componentValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *foundationValue = candidateValue[@"foundation"];
if (![foundationValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *priorityValue = candidateValue[@"priority"];
if (![priorityValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *ipValue = candidateValue[@"ip"];
if (![ipValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *typeValue = candidateValue[@"type"];
if (![typeValue isKindOfClass:[NSString class]]) {
continue;
}
NSString *tcpTypeValue = candidateValue[@"tcptype"];
if (![tcpTypeValue isKindOfClass:[NSString class]]) {
tcpTypeValue = @"";
}
NSString *relAddrValue = candidateValue[@"rel-addr"];
if (![relAddrValue isKindOfClass:[NSString class]]) {
relAddrValue = @"";
}
NSString *relPortValue = candidateValue[@"rel-port"];
if (![relPortValue isKindOfClass:[NSString class]]) {
relPortValue = @"";
}
tgcalls::GroupJoinResponseCandidate candidate;
candidate.port = [portValue UTF8String];
candidate.protocol = [protocolValue UTF8String];
candidate.network = [networkValue UTF8String];
candidate.generation = [generationValue UTF8String];
candidate.id = [idValue UTF8String];
candidate.component = [componentValue UTF8String];
candidate.foundation = [foundationValue UTF8String];
candidate.priority = [priorityValue UTF8String];
candidate.ip = [ipValue UTF8String];
candidate.type = [typeValue UTF8String];
candidate.tcpType = [tcpTypeValue UTF8String];
candidate.relAddr = [relAddrValue UTF8String];
candidate.relPort = [relPortValue UTF8String];
result.candidates.push_back(candidate);
}
if (_instance) { if (_instance) {
_instance->setOfferSdp([offerSdp UTF8String], isPartial); _instance->setJoinResponsePayload(result);
}
}
- (void)setSsrcs:(NSArray<NSNumber *> * _Nonnull)ssrcs {
if (_instance) {
std::vector<uint32_t> values;
for (NSNumber *ssrc in ssrcs) {
values.push_back([ssrc unsignedIntValue]);
}
_instance->setSsrcs(values);
} }
} }
@ -881,43 +1032,5 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
} }
} }
- (void)makeIncomingVideoViewWithStreamId:(NSString * _Nonnull)streamId completion:(void (^_Nonnull)(UIView<OngoingCallThreadLocalContextWebrtcVideoView> * _Nullable))completion {
if (_instance) {
__weak GroupCallThreadLocalContext *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if ([VideoMetalView isSupported]) {
VideoMetalView *remoteRenderer = [[VideoMetalView alloc] initWithFrame:CGRectZero];
#if TARGET_OS_IPHONE
remoteRenderer.videoContentMode = UIViewContentModeScaleToFill;
#else
remoteRenderer.videoContentMode = UIViewContentModeScaleAspect;
#endif
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink = [remoteRenderer getSink];
__strong GroupCallThreadLocalContext *strongSelf = weakSelf;
if (strongSelf) {
//[remoteRenderer setOrientation:strongSelf->_remoteVideoOrientation];
//strongSelf->_currentRemoteVideoRenderer = remoteRenderer;
strongSelf->_instance->setIncomingVideoOutput([streamId UTF8String], sink);
}
completion(remoteRenderer);
} else {
GLVideoView *remoteRenderer = [[GLVideoView alloc] initWithFrame:CGRectZero];
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink = [remoteRenderer getSink];
__strong GroupCallThreadLocalContext *strongSelf = weakSelf;
if (strongSelf) {
//[remoteRenderer setOrientation:strongSelf->_remoteVideoOrientation];
//strongSelf->_currentRemoteVideoRenderer = remoteRenderer;
strongSelf->_instance->setIncomingVideoOutput([streamId UTF8String], sink);
}
completion(remoteRenderer);
}
});
}
}
@end @end

@ -1 +1 @@
Subproject commit 9da28c047317708366da3af6c657cf514ef53593 Subproject commit f679bba27327cfe0327a89816d4ba56355b9c9c7