Voice chat and admin updates

This commit is contained in:
Ali 2021-03-18 23:39:46 +04:00
parent 8f96c71ca1
commit a274bf350d
28 changed files with 3685 additions and 3531 deletions

View File

@ -3,7 +3,7 @@
@implementation Serialization
- (NSUInteger)currentLayer {
return 125;
return 126;
}
- (id _Nullable)parseMessage:(NSData * _Nullable)data {

View File

@ -6297,3 +6297,5 @@ Sorry for the inconvenience.";
"VoiceChat.ForwardTooltip.Chat" = "Invite link forwarded to **%@**";
"VoiceChat.ForwardTooltip.TwoChats" = "Invite link forwarded to **%@** and **%@**";
"VoiceChat.ForwardTooltip.ManyChats" = "Invite link forwarded to **%@** and %@ others";
"GroupRemoved.ViewChannelInfo" = "View Channel";

View File

@ -1023,6 +1023,8 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
} else {
updateFlags = []
}
} else {
updateFlags = adminInfo?.rights.rights
}
}
currentRank = rank

View File

@ -389,8 +389,16 @@ private func channelAdminsControllerEntries(presentationData: PresentationData,
if id == accountPeerId {
canEdit = false
} else if let adminInfo = adminInfo {
if peer.flags.contains(.isCreator) || adminInfo.promotedBy == accountPeerId {
if peer.flags.contains(.isCreator) {
canEdit = true
canOpen = true
} else if adminInfo.promotedBy == accountPeerId {
canEdit = true
if let adminRights = peer.adminRights {
if adminRights.rights.isEmpty {
canOpen = false
}
}
} else {
canEdit = false
}

View File

@ -274,7 +274,8 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
let updateState: ((ChannelBlacklistControllerState) -> ChannelBlacklistControllerState) -> Void = { f in
statePromise.set(stateValue.modify { f($0) })
}
var getNavigationControllerImpl: (() -> NavigationController?)?
var presentControllerImpl: ((ViewController, Any?) -> Void)?
var pushControllerImpl: ((ViewController) -> Void)?
var dismissInputImpl: (() -> Void)?
@ -364,9 +365,19 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
if !participant.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder).isEmpty {
items.append(ActionSheetTextItem(title: participant.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)))
}
items.append(ActionSheetButtonItem(title: presentationData.strings.GroupRemoved_ViewUserInfo, action: { [weak actionSheet] in
let viewInfoTitle: String
if participant.peer is TelegramChannel {
viewInfoTitle = presentationData.strings.GroupRemoved_ViewChannelInfo
} else {
viewInfoTitle = presentationData.strings.GroupRemoved_ViewUserInfo
}
items.append(ActionSheetButtonItem(title: viewInfoTitle, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let infoController = context.sharedContext.makePeerInfoController(context: context, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false) {
if participant.peer is TelegramChannel {
if let navigationController = getNavigationControllerImpl?() {
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(participant.peer.id)))
}
} else if let infoController = context.sharedContext.makePeerInfoController(context: context, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false) {
pushControllerImpl?(infoController)
}
}))
@ -520,6 +531,9 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId)
(controller.navigationController as? NavigationController)?.pushViewController(c)
}
}
getNavigationControllerImpl = { [weak controller] in
return controller?.navigationController as? NavigationController
}
dismissInputImpl = { [weak controller] in
controller?.view.endEditing(true)
}

View File

@ -88,7 +88,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-347535331] = { return Api.RecentMeUrl.parse_recentMeUrlChatInvite($0) }
dict[-1140172836] = { return Api.RecentMeUrl.parse_recentMeUrlStickerSet($0) }
dict[-797791052] = { return Api.RestrictionReason.parse_restrictionReason($0) }
dict[-177282392] = { return Api.channels.ChannelParticipants.parse_channelParticipants($0) }
dict[-1699676497] = { return Api.channels.ChannelParticipants.parse_channelParticipants($0) }
dict[-266911767] = { return Api.channels.ChannelParticipants.parse_channelParticipantsNotModified($0) }
dict[-599948721] = { return Api.RichText.parse_textEmpty($0) }
dict[1950782688] = { return Api.RichText.parse_textPlain($0) }
@ -122,7 +122,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[84438264] = { return Api.WallPaperSettings.parse_wallPaperSettings($0) }
dict[-1519029347] = { return Api.EmojiURL.parse_emojiURL($0) }
dict[1611985938] = { return Api.StatsGroupTopAdmin.parse_statsGroupTopAdmin($0) }
dict[-791039645] = { return Api.channels.ChannelParticipant.parse_channelParticipant($0) }
dict[-541588713] = { return Api.channels.ChannelParticipant.parse_channelParticipant($0) }
dict[-1736378792] = { return Api.InputCheckPasswordSRP.parse_inputCheckPasswordEmpty($0) }
dict[-763367294] = { return Api.InputCheckPasswordSRP.parse_inputCheckPasswordSRP($0) }
dict[-1432995067] = { return Api.storage.FileType.parse_fileUnknown($0) }
@ -287,7 +287,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1557620115] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
dict[1149094475] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
dict[-859915345] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
dict[470789295] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
dict[1352785878] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
dict[-1010402965] = { return Api.ChannelParticipant.parse_channelParticipantLeft($0) }
dict[-1567730343] = { return Api.MessageUserVote.parse_messageUserVote($0) }
dict[909603888] = { return Api.MessageUserVote.parse_messageUserVoteInputOption($0) }
@ -471,6 +471,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1036572727] = { return Api.account.PasswordInputSettings.parse_passwordInputSettings($0) }
dict[878078826] = { return Api.PageTableCell.parse_pageTableCell($0) }
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
dict[423690591] = { return Api.ChatBannedRights.parse_chatBannedRightsChannel($0) }
dict[1968737087] = { return Api.InputClientProxy.parse_inputClientProxy($0) }
dict[649453030] = { return Api.messages.MessageEditData.parse_messageEditData($0) }
dict[-886477832] = { return Api.LabeledPrice.parse_labeledPrice($0) }

View File

@ -7362,7 +7362,7 @@ public extension Api {
case channelParticipantSelf(userId: Int32, inviterId: Int32, date: Int32)
case channelParticipantCreator(flags: Int32, userId: Int32, adminRights: Api.ChatAdminRights, rank: String?)
case channelParticipantAdmin(flags: Int32, userId: Int32, inviterId: Int32?, promotedBy: Int32, date: Int32, adminRights: Api.ChatAdminRights, rank: String?)
case channelParticipantBanned(flags: Int32, userId: Int32, kickedBy: Int32, date: Int32, bannedRights: Api.ChatBannedRights)
case channelParticipantBanned(flags: Int32, peer: Api.Peer, kickedBy: Int32, date: Int32, bannedRights: Api.ChatBannedRights)
case channelParticipantLeft(userId: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@ -7403,12 +7403,12 @@ public extension Api {
adminRights.serialize(buffer, true)
if Int(flags) & Int(1 << 2) != 0 {serializeString(rank!, buffer: buffer, boxed: false)}
break
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
case .channelParticipantBanned(let flags, let peer, let kickedBy, let date, let bannedRights):
if boxed {
buffer.appendInt32(470789295)
buffer.appendInt32(1352785878)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(userId, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(kickedBy, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
bannedRights.serialize(buffer, true)
@ -7432,8 +7432,8 @@ public extension Api {
return ("channelParticipantCreator", [("flags", flags), ("userId", userId), ("adminRights", adminRights), ("rank", rank)])
case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank):
return ("channelParticipantAdmin", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("promotedBy", promotedBy), ("date", date), ("adminRights", adminRights), ("rank", rank)])
case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights):
return ("channelParticipantBanned", [("flags", flags), ("userId", userId), ("kickedBy", kickedBy), ("date", date), ("bannedRights", bannedRights)])
case .channelParticipantBanned(let flags, let peer, let kickedBy, let date, let bannedRights):
return ("channelParticipantBanned", [("flags", flags), ("peer", peer), ("kickedBy", kickedBy), ("date", date), ("bannedRights", bannedRights)])
case .channelParticipantLeft(let userId):
return ("channelParticipantLeft", [("userId", userId)])
}
@ -7526,8 +7526,10 @@ public extension Api {
public static func parse_channelParticipantBanned(_ reader: BufferReader) -> ChannelParticipant? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _2: Api.Peer?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
@ -7542,7 +7544,7 @@ public extension Api {
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.ChannelParticipant.channelParticipantBanned(flags: _1!, userId: _2!, kickedBy: _3!, date: _4!, bannedRights: _5!)
return Api.ChannelParticipant.channelParticipantBanned(flags: _1!, peer: _2!, kickedBy: _3!, date: _4!, bannedRights: _5!)
}
else {
return nil
@ -12067,6 +12069,7 @@ public extension Api {
}
public enum ChatBannedRights: TypeConstructorDescription {
case chatBannedRights(flags: Int32, untilDate: Int32)
case chatBannedRightsChannel(flags: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -12077,6 +12080,12 @@ public extension Api {
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(untilDate, buffer: buffer, boxed: false)
break
case .chatBannedRightsChannel(let flags):
if boxed {
buffer.appendInt32(423690591)
}
serializeInt32(flags, buffer: buffer, boxed: false)
break
}
}
@ -12084,6 +12093,8 @@ public extension Api {
switch self {
case .chatBannedRights(let flags, let untilDate):
return ("chatBannedRights", [("flags", flags), ("untilDate", untilDate)])
case .chatBannedRightsChannel(let flags):
return ("chatBannedRightsChannel", [("flags", flags)])
}
}
@ -12101,6 +12112,17 @@ public extension Api {
return nil
}
}
public static func parse_chatBannedRightsChannel(_ reader: BufferReader) -> ChatBannedRights? {
var _1: Int32?
_1 = reader.readInt32()
let _c1 = _1 != nil
if _c1 {
return Api.ChatBannedRights.chatBannedRightsChannel(flags: _1!)
}
else {
return nil
}
}
}
public enum InputClientProxy: TypeConstructorDescription {

View File

@ -1,14 +1,14 @@
public extension Api {
public struct channels {
public enum ChannelParticipants: TypeConstructorDescription {
case channelParticipants(count: Int32, participants: [Api.ChannelParticipant], users: [Api.User])
case channelParticipants(count: Int32, participants: [Api.ChannelParticipant], chats: [Api.Chat], users: [Api.User])
case channelParticipantsNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .channelParticipants(let count, let participants, let users):
case .channelParticipants(let count, let participants, let chats, let users):
if boxed {
buffer.appendInt32(-177282392)
buffer.appendInt32(-1699676497)
}
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
@ -17,6 +17,11 @@ public struct channels {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
@ -33,8 +38,8 @@ public struct channels {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .channelParticipants(let count, let participants, let users):
return ("channelParticipants", [("count", count), ("participants", participants), ("users", users)])
case .channelParticipants(let count, let participants, let chats, let users):
return ("channelParticipants", [("count", count), ("participants", participants), ("chats", chats), ("users", users)])
case .channelParticipantsNotModified:
return ("channelParticipantsNotModified", [])
}
@ -47,15 +52,20 @@ public struct channels {
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ChannelParticipant.self)
}
var _3: [Api.User]?
var _3: [Api.Chat]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _4: [Api.User]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.channels.ChannelParticipants.channelParticipants(count: _1!, participants: _2!, users: _3!)
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.channels.ChannelParticipants.channelParticipants(count: _1!, participants: _2!, chats: _3!, users: _4!)
}
else {
return nil
@ -67,16 +77,21 @@ public struct channels {
}
public enum ChannelParticipant: TypeConstructorDescription {
case channelParticipant(participant: Api.ChannelParticipant, users: [Api.User])
case channelParticipant(participant: Api.ChannelParticipant, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .channelParticipant(let participant, let users):
case .channelParticipant(let participant, let chats, let users):
if boxed {
buffer.appendInt32(-791039645)
buffer.appendInt32(-541588713)
}
participant.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
for item in chats {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
@ -87,8 +102,8 @@ public struct channels {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .channelParticipant(let participant, let users):
return ("channelParticipant", [("participant", participant), ("users", users)])
case .channelParticipant(let participant, let chats, let users):
return ("channelParticipant", [("participant", participant), ("chats", chats), ("users", users)])
}
}
@ -97,14 +112,19 @@ public struct channels {
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.ChannelParticipant
}
var _2: [Api.User]?
var _2: [Api.Chat]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _3: [Api.User]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.channels.ChannelParticipant.channelParticipant(participant: _1!, users: _2!)
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.channels.ChannelParticipant.channelParticipant(participant: _1!, chats: _2!, users: _3!)
}
else {
return nil

View File

@ -4376,12 +4376,12 @@ public extension Api {
})
}
public static func getParticipant(channel: Api.InputChannel, userId: Api.InputUser) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.channels.ChannelParticipant>) {
public static func getParticipant(channel: Api.InputChannel, participant: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.channels.ChannelParticipant>) {
let buffer = Buffer()
buffer.appendInt32(1416484774)
buffer.appendInt32(-1599378234)
channel.serialize(buffer, true)
userId.serialize(buffer, true)
return (FunctionDescription(name: "channels.getParticipant", parameters: [("channel", channel), ("userId", userId)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.channels.ChannelParticipant? in
participant.serialize(buffer, true)
return (FunctionDescription(name: "channels.getParticipant", parameters: [("channel", channel), ("participant", participant)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.channels.ChannelParticipant? in
let reader = BufferReader(buffer)
var result: Api.channels.ChannelParticipant?
if let signature = reader.readInt32() {
@ -4624,13 +4624,13 @@ public extension Api {
})
}
public static func editBanned(channel: Api.InputChannel, userId: Api.InputUser, bannedRights: Api.ChatBannedRights) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
public static func editBanned(channel: Api.InputChannel, participant: Api.InputPeer, bannedRights: Api.ChatBannedRights) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(1920559378)
buffer.appendInt32(-1763259007)
channel.serialize(buffer, true)
userId.serialize(buffer, true)
participant.serialize(buffer, true)
bannedRights.serialize(buffer, true)
return (FunctionDescription(name: "channels.editBanned", parameters: [("channel", channel), ("userId", userId), ("bannedRights", bannedRights)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
return (FunctionDescription(name: "channels.editBanned", parameters: [("channel", channel), ("participant", participant), ("bannedRights", bannedRights)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {

View File

@ -3,6 +3,17 @@ import SwiftSignalKit
import AVFoundation
import UIKit
private var managedAudioSessionLogger: (String) -> Void = { _ in }
public func setManagedAudioSessionLogger(_ f: @escaping (String) -> Void) {
managedAudioSessionLogger = f
}
func managedAudioSessionLog(_ what: @autoclosure () -> String) {
managedAudioSessionLogger(what())
}
public enum ManagedAudioSessionType: Equatable {
case ambient
case play
@ -524,7 +535,7 @@ public final class ManagedAudioSession {
private func updateHolders(interruption: Bool = false) {
assert(self.queue.isCurrent())
print("holder count \(self.holders.count)")
managedAudioSessionLog("holder count \(self.holders.count)")
if !self.holders.isEmpty {
var activeIndex: Int?
@ -625,7 +636,7 @@ public final class ManagedAudioSession {
assert(self.queue.isCurrent())
let route = AVAudioSession.sharedInstance().currentRoute
//print("\(route)")
//managedAudioSessionLog("\(route)")
for desc in route.outputs {
if desc.portType == .headphones || desc.portType == .bluetoothA2DP || desc.portType == .bluetoothHFP {
return true
@ -643,13 +654,13 @@ public final class ManagedAudioSession {
let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false
self.currentTypeAndOutputMode = nil
print("ManagedAudioSession setting active false")
managedAudioSessionLog("ManagedAudioSession setting active false")
do {
try AVAudioSession.sharedInstance().setActive(false, options: [.notifyOthersOnDeactivation])
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
try AVAudioSession.sharedInstance().setPreferredInput(nil)
} catch let error {
print("ManagedAudioSession applyNone error \(error), waiting")
managedAudioSessionLog("ManagedAudioSession applyNone error \(error), waiting")
Thread.sleep(forTimeInterval: 2.0)
@ -658,7 +669,7 @@ public final class ManagedAudioSession {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
try AVAudioSession.sharedInstance().setPreferredInput(nil)
} catch let error {
print("ManagedAudioSession applyNone repeated error \(error), giving up")
managedAudioSessionLog("ManagedAudioSession applyNone repeated error \(error), giving up")
}
}
@ -687,7 +698,7 @@ public final class ManagedAudioSession {
do {
let nativeCategory = nativeCategoryForType(type, headphones: self.isHeadsetPluggedInValue, outputMode: outputMode)
print("ManagedAudioSession setting category for \(type) (native: \(nativeCategory)) activateNow: \(activateNow)")
managedAudioSessionLog("ManagedAudioSession setting category for \(type) (native: \(nativeCategory)) activateNow: \(activateNow)")
var options: AVAudioSession.CategoryOptions = []
switch type {
case .play, .ambient:
@ -703,7 +714,7 @@ public final class ManagedAudioSession {
case .record, .voiceCall, .videoCall:
options.insert(.allowBluetooth)
}
print("ManagedAudioSession setting active true")
managedAudioSessionLog("ManagedAudioSession setting active true")
let mode: AVAudioSession.Mode
switch type {
case .voiceCall:
@ -720,7 +731,7 @@ public final class ManagedAudioSession {
try AVAudioSession.sharedInstance().setMode(mode)
}
} catch let error {
print("ManagedAudioSession setup error \(error)")
managedAudioSessionLog("ManagedAudioSession setup error \(error)")
}
}
@ -741,7 +752,7 @@ public final class ManagedAudioSession {
}
private func setupOutputMode(_ outputMode: AudioSessionOutputMode, type: ManagedAudioSessionType) throws {
print("ManagedAudioSession setup \(outputMode) for \(type)")
managedAudioSessionLog("ManagedAudioSession setup \(outputMode) for \(type)")
var resetToBuiltin = false
switch outputMode {
case .system:
@ -831,21 +842,21 @@ public final class ManagedAudioSession {
try AVAudioSession.sharedInstance().setActive(true, options: [.notifyOthersOnDeactivation])
print("\(CFAbsoluteTimeGetCurrent()) AudioSession activate: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
managedAudioSessionLog("\(CFAbsoluteTimeGetCurrent()) AudioSession activate: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
try self.setupOutputMode(outputMode, type: type)
print("\(CFAbsoluteTimeGetCurrent()) AudioSession setupOutputMode: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
managedAudioSessionLog("\(CFAbsoluteTimeGetCurrent()) AudioSession setupOutputMode: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
self.updateCurrentAudioRouteInfo()
print("\(CFAbsoluteTimeGetCurrent()) AudioSession updateCurrentAudioRouteInfo: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
managedAudioSessionLog("\(CFAbsoluteTimeGetCurrent()) AudioSession updateCurrentAudioRouteInfo: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
if case .voiceCall = type {
try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(0.005)
}
} catch let error {
print("ManagedAudioSession activate error \(error)")
managedAudioSessionLog("ManagedAudioSession activate error \(error)")
}
}
}
@ -858,7 +869,7 @@ public final class ManagedAudioSession {
public func callKitActivatedAudioSession() {
/*self.queue.async {
print("ManagedAudioSession callKitDeactivatedAudioSession")
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
self.callKitAudioSessionIsActive = true
self.updateHolders()
}*/
@ -866,7 +877,7 @@ public final class ManagedAudioSession {
public func callKitDeactivatedAudioSession() {
/*self.queue.async {
print("ManagedAudioSession callKitDeactivatedAudioSession")
managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession")
self.callKitAudioSessionIsActive = false
self.updateHolders()
}*/

View File

@ -1174,6 +1174,19 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.VoiceChat_ChatFullAlertText, actions: [
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})
]), on: .root, blockInteraction: false, completion: {})
} else if case .invalidJoinAsPeer = error {
let peerId = strongSelf.peerId
let _ = (strongSelf.accountContext.account.postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedChannelData {
return current.withUpdatedCallJoinPeerId(nil)
} else if let current = current as? CachedGroupData {
return current.withUpdatedCallJoinPeerId(nil)
} else {
return current
}
})
}).start()
}
strongSelf.markAsCanBeRemoved()
}))
@ -1678,16 +1691,23 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.isRequestingMissingSsrcs = false
strongSelf.missingSsrcs.subtract(requestedSsrcs)
var addedParticipants: [(UInt32, String?)] = []
var addedParticipants: [(UInt32, Int32?, String?)] = []
for participant in state.participants {
if let ssrc = participant.ssrc {
addedParticipants.append((ssrc, participant.jsonParams))
addedParticipants.append((ssrc, participant.volume, participant.jsonParams))
}
}
if !addedParticipants.isEmpty {
strongSelf.callContext?.addParticipants(participants: addedParticipants)
for (ssrc, volume, _) in addedParticipants {
if let volume = volume {
strongSelf.callContext?.setVolume(ssrc: ssrc, volume: Double(volume) / 10000.0)
}
}
strongSelf.callContext?.addParticipants(participants: addedParticipants.map { ssrc, _, params in
return (ssrc, params)
})
}
strongSelf.maybeRequestMissingSsrcs()

View File

@ -1285,7 +1285,7 @@ public final class VoiceChatController: ViewController {
f(.default)
})))
if let callState = strongSelf.callState, (callState.canManageCall && !callState.adminIds.contains(peer.id) && peer.id.namespace != Namespaces.Peer.CloudChannel) {
if let callState = strongSelf.callState, (callState.canManageCall && !callState.adminIds.contains(peer.id)) {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_RemovePeer, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { [weak self] c, _ in

View File

@ -205,7 +205,7 @@ extension ChannelParticipant {
case let .channelParticipantBanned(flags, userId, restrictedBy, date, bannedRights):
let hasLeft = (flags & (1 << 0)) != 0
let banInfo = ChannelParticipantBannedInfo(rights: TelegramChatBannedRights(apiBannedRights: bannedRights), restrictedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: restrictedBy), timestamp: date, isMember: !hasLeft)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil)
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil)
case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights, rank: rank):
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: promotedBy), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank)
case let .channelParticipantSelf(userId, _, date):

View File

@ -13,7 +13,7 @@ public func channelAdmins(account: Account, peerId: PeerId) -> Signal<[RenderedC
|> retryRequest
|> mapToSignal { result -> Signal<[RenderedChannelParticipant], NoError> in
switch result {
case let .channelParticipants(count, participants, users):
case let .channelParticipants(count, participants, chats, users):
var items: [RenderedChannelParticipant] = []
var peers: [PeerId: Peer] = [:]
@ -58,7 +58,7 @@ public func channelAdminIds(postbox: Postbox, network: Network, peerId: PeerId,
let api = Api.functions.channels.getParticipants(channel: apiChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: hash)
return network.request(api) |> retryRequest |> mapToSignal { result in
switch result {
case let .channelParticipants(_, participants, users):
case let .channelParticipants(_, participants, _, users):
let users = users.filter({ user in
return participants.contains(where: { participant in
switch participant {

View File

@ -26,9 +26,9 @@ private func fetchChannelBlacklist(account: Account, peerId: PeerId, filter: Cha
|> map { result -> [RenderedChannelParticipant] in
var items: [RenderedChannelParticipant] = []
switch result {
case let .channelParticipants(_, participants, users):
case let .channelParticipants(_, participants, chats, users):
var peers: [PeerId: Peer] = [:]
var presences:[PeerId: PeerPresence] = [:]
var presences: [PeerId: PeerPresence] = [:]
for user in users {
let peer = TelegramUser(user: user)
peers[peer.id] = peer
@ -36,6 +36,11 @@ private func fetchChannelBlacklist(account: Account, peerId: PeerId, filter: Cha
presences[peer.id] = presence
}
}
for chat in chats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers[groupOrChannel.id] = groupOrChannel
}
}
for participant in CachedChannelParticipants(apiParticipants: participants).participants {
if let peer = peers[participant.peerId] {
@ -133,7 +138,7 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
return fetchChannelParticipant(account: account, peerId: peerId, participantId: memberId)
|> mapToSignal { currentParticipant -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
return account.postbox.transaction { transaction -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer), let _ = transaction.getPeer(account.peerId), let memberPeer = transaction.getPeer(memberId), let inputUser = apiInputUser(memberPeer) {
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer), let _ = transaction.getPeer(account.peerId), let memberPeer = transaction.getPeer(memberId), let inputPeer = apiInputPeer(memberPeer) {
let updatedParticipant: ChannelParticipant
if let currentParticipant = currentParticipant, case let .member(_, invitedAt, _, currentBanInfo, _) = currentParticipant {
let banInfo: ChannelParticipantBannedInfo?
@ -152,8 +157,23 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me
}
updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: banInfo, rank: nil)
}
let apiRights: Api.ChatBannedRights
if let rights = rights, !rights.flags.isEmpty {
if memberId.namespace == Namespaces.Peer.CloudChannel {
apiRights = .chatBannedRightsChannel(flags: 1 << 0)
} else {
apiRights = rights.apiBannedRights
}
} else {
if memberId.namespace == Namespaces.Peer.CloudChannel {
apiRights = .chatBannedRightsChannel(flags: 0)
} else {
apiRights = .chatBannedRights(flags: 0, untilDate: 0)
}
}
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: rights?.apiBannedRights ?? Api.ChatBannedRights.chatBannedRights(flags: 0, untilDate: 0)))
return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, participant: inputPeer, bannedRights: apiRights))
|> retryRequest
|> mapToSignal { result -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in
account.stateManager.addUpdates(result)

View File

@ -83,7 +83,7 @@ public func channelMembers(postbox: Postbox, network: Network, accountPeerId: Pe
return postbox.transaction { transaction -> [RenderedChannelParticipant]? in
var items: [RenderedChannelParticipant] = []
switch result {
case let .channelParticipants(_, participants, users):
case let .channelParticipants(_, participants, chats, users):
var peers: [PeerId: Peer] = [:]
var presences: [PeerId: PeerPresence] = [:]
for user in users {
@ -93,6 +93,11 @@ public func channelMembers(postbox: Postbox, network: Network, accountPeerId: Pe
presences[peer.id] = presence
}
}
for chat in chats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers[groupOrChannel.id] = groupOrChannel
}
}
updatePeers(transaction: transaction, peers: Array(peers.values), update: { _, updated in
return updated
})

View File

@ -38,7 +38,7 @@ func updateChannelParticipantsSummary(account: Account, peerId: PeerId) -> Signa
if let current = current as? CachedChannelData {
let adminCount: Int32
switch admins {
case let .channelParticipants(count, _, _):
case let .channelParticipants(count, _, _, _):
adminCount = count
case .channelParticipantsNotModified:
assertionFailure()
@ -46,7 +46,7 @@ func updateChannelParticipantsSummary(account: Account, peerId: PeerId) -> Signa
}
let memberCount: Int32
switch members {
case let .channelParticipants(count, _, _):
case let .channelParticipants(count, _, _, _):
memberCount = count
case .channelParticipantsNotModified:
assertionFailure()
@ -54,7 +54,7 @@ func updateChannelParticipantsSummary(account: Account, peerId: PeerId) -> Signa
}
let bannedCount: Int32
switch banned {
case let .channelParticipants(count, _, _):
case let .channelParticipants(count, _, _, _):
bannedCount = count
case .channelParticipantsNotModified:
assertionFailure()
@ -62,7 +62,7 @@ func updateChannelParticipantsSummary(account: Account, peerId: PeerId) -> Signa
}
let kickedCount: Int32
switch kicked {
case let .channelParticipants(count, _, _):
case let .channelParticipants(count, _, _, _):
kickedCount = count
case .channelParticipantsNotModified:
assertionFailure()

View File

@ -367,6 +367,7 @@ public enum JoinGroupCallError {
case generic
case anonymousNotAllowed
case tooManyParticipants
case invalidJoinAsPeer
}
public struct JoinGroupCallResult {
@ -408,6 +409,8 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
return .anonymousNotAllowed
} else if error.errorDescription == "GROUPCALL_PARTICIPANTS_TOO_MUCH" {
return .tooManyParticipants
} else if error.errorDescription == "JOIN_AS_PEER_INVALID" {
return .invalidJoinAsPeer
}
return .generic
}

View File

@ -38,7 +38,7 @@ public func joinChannel(account: Account, peerId: PeerId, hash: String?) -> Sign
|> mapToSignal { updates -> Signal<RenderedChannelParticipant?, JoinChannelError> in
account.stateManager.addUpdates(updates)
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, userId: .inputUserSelf))
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.channels.ChannelParticipant?, JoinChannelError> in
return .single(nil)
@ -59,7 +59,7 @@ public func joinChannel(account: Account, peerId: PeerId, hash: String?) -> Sign
}
let updatedParticipant: ChannelParticipant
switch result {
case let .channelParticipant(participant, _):
case let .channelParticipant(participant, _, _):
updatedParticipant = ChannelParticipant(apiParticipant: participant)
}
if case let .member(_, _, maybeAdminInfo, _, _) = updatedParticipant {

View File

@ -129,12 +129,12 @@ public enum UpdateChannelAdminRightsError {
public func fetchChannelParticipant(account: Account, peerId: PeerId, participantId: PeerId) -> Signal<ChannelParticipant?, NoError> {
return account.postbox.transaction { transaction -> Signal<ChannelParticipant?, NoError> in
if let peer = transaction.getPeer(peerId), let adminPeer = transaction.getPeer(participantId), let inputUser = apiInputUser(adminPeer) {
if let peer = transaction.getPeer(peerId), let adminPeer = transaction.getPeer(participantId), let inputPeer = apiInputPeer(adminPeer) {
if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, userId: inputUser))
return account.network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: inputPeer))
|> map { result -> ChannelParticipant? in
switch result {
case let .channelParticipant(participant, _):
case let .channelParticipant(participant, _, _):
return ChannelParticipant(apiParticipant: participant)
}
}

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 125
return 126
}
public func parseMessage(_ data: Data!) -> Any! {

View File

@ -9,6 +9,9 @@ extension TelegramChatBannedRights {
switch apiBannedRights {
case let .chatBannedRights(flags, untilDate):
self.init(flags: TelegramChatBannedRightsFlags(rawValue: flags), untilDate: untilDate)
case let .chatBannedRightsChannel(flags):
let isKicked = (flags & (1 << 0)) != 0
self.init(flags: [.banReadMessages], untilDate: Int32.max)
}
}

View File

@ -338,7 +338,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
}
return .single(nil)
}
let participantSignal = network.request(Api.functions.channels.getParticipant(channel: inputChannel, userId: .inputUserSelf))
let participantSignal = network.request(Api.functions.channels.getParticipant(channel: inputChannel, participant: .inputPeerSelf))
|> map(Optional.init)
|> `catch` { error -> Signal<Api.channels.ChannelParticipant?, NoError> in
return .single(nil)
@ -442,7 +442,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
if let participantResult = participantResult {
switch participantResult {
case let .channelParticipant(_, users):
case let .channelParticipant(_, chats, users):
for user in users {
if let telegramUser = TelegramUser.merge(transaction.getPeer(user.peerId) as? TelegramUser, rhs: user) {
peers.append(telegramUser)
@ -451,6 +451,11 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
}
}
}
for chat in chats {
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
peers.append(groupOrChannel)
}
}
}
}
@ -482,7 +487,7 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
var invitedBy: PeerId?
if let participantResult = participantResult {
switch participantResult {
case let.channelParticipant(participant, _):
case let.channelParticipant(participant, _, _):
switch participant {
case let .channelParticipantSelf(_, inviterId, _):
invitedBy = PeerId(namespace: Namespaces.Peer.CloudUser, id: inviterId)

View File

@ -32,6 +32,7 @@ import TelegramIntents
import AccountUtils
import CoreSpotlight
import LightweightAccountData
import TelegramAudio
#if canImport(BackgroundTasks)
import BackgroundTasks
@ -438,6 +439,11 @@ final class SharedApplicationContext {
let logsPath = rootPath + "/logs"
let _ = try? FileManager.default.createDirectory(atPath: logsPath, withIntermediateDirectories: true, attributes: nil)
Logger.setSharedLogger(Logger(rootPath: rootPath, basePath: logsPath))
setManagedAudioSessionLogger({ s in
Logger.shared.log("ManagedAudioSession", s)
Logger.shared.shortLog("ManagedAudioSession", s)
})
if let contents = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: rootPath + "/accounts-metadata"), includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants]) {
for url in contents {

View File

@ -512,6 +512,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let canReadHistory = Promise<Bool>()
private var canReadHistoryValue: Bool = false
private var canReadHistoryDisposable: Disposable?
private var messageIdsScheduledForMarkAsSeen = Set<MessageId>()
private var chatHistoryLocationValue: ChatHistoryLocationInput? {
didSet {
@ -669,12 +671,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.messageMentionProcessingManager.process = { [weak self, weak context] messageIds in
if let strongSelf = self {
let _ = (strongSelf.canReadHistory.get()
|> take(1)).start(next: { [weak context] canReadHistory in
if canReadHistory {
context?.account.viewTracker.updateMarkMentionsSeenForMessageIds(messageIds: messageIds)
}
})
if strongSelf.canReadHistoryValue {
context?.account.viewTracker.updateMarkMentionsSeenForMessageIds(messageIds: messageIds)
} else {
strongSelf.messageIdsScheduledForMarkAsSeen.formUnion(messageIds)
}
}
}
@ -1073,11 +1074,17 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
self.readHistoryDisposable.set(readHistory.start())
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).start(next: { [weak self] value in
self.canReadHistoryDisposable = (self.canReadHistory.get() |> deliverOnMainQueue).start(next: { [weak self, weak context] value in
if let strongSelf = self {
if strongSelf.canReadHistoryValue != value {
strongSelf.canReadHistoryValue = value
strongSelf.updateReadHistoryActions()
if strongSelf.canReadHistoryValue && !strongSelf.messageIdsScheduledForMarkAsSeen.isEmpty {
let messageIds = strongSelf.messageIdsScheduledForMarkAsSeen
strongSelf.messageIdsScheduledForMarkAsSeen.removeAll()
context?.account.viewTracker.updateMarkMentionsSeenForMessageIds(messageIds: messageIds)
}
}
}
})

View File

@ -196,6 +196,10 @@ final class ForwardAccessoryPanelNode: AccessoryPanelNode {
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
return CGSize(width: constrainedSize.width, height: 45.0)
}
override func updateState(size: CGSize, interfaceState: ChatPresentationInterfaceState) {
}
override func layout() {
super.layout()