update api to 125 layer [skip ci]

This commit is contained in:
overtake 2021-03-01 18:16:31 +04:00
parent 796c77b11d
commit a5e886559b
6 changed files with 313 additions and 212 deletions

View File

@ -2987,7 +2987,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
}) })
switch call { switch call {
case let .groupCall(flags, _, _, _, _, _): case let .groupCall(flags, _, _, _, _, _, _, _):
let isMuted = (flags & (1 << 1)) != 0 let isMuted = (flags & (1 << 1)) != 0
let canChange = (flags & (1 << 2)) != 0 let canChange = (flags & (1 << 2)) != 0
let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange) let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange)

View File

@ -9,17 +9,22 @@ public struct GroupCallInfo: Equatable {
public var accessHash: Int64 public var accessHash: Int64
public var participantCount: Int public var participantCount: Int
public var clientParams: String? public var clientParams: String?
public var streamDcId: Int32?
public var title: String?
public init( public init(
id: Int64, id: Int64,
accessHash: Int64, accessHash: Int64,
participantCount: Int, participantCount: Int,
clientParams: String? clientParams: String?,
streamDcId: Int32?,
title: String?
) { ) {
self.id = id self.id = id
self.accessHash = accessHash self.accessHash = accessHash
self.participantCount = participantCount self.participantCount = participantCount
self.clientParams = clientParams self.clientParams = clientParams
self.title = title
self.streamDcId = streamDcId
} }
} }
@ -31,7 +36,7 @@ public struct GroupCallSummary: Equatable {
extension GroupCallInfo { extension GroupCallInfo {
init?(_ call: Api.GroupCall) { init?(_ call: Api.GroupCall) {
switch call { switch call {
case let .groupCall(_, id, accessHash, participantCount, params, _): case let .groupCall(_, id, accessHash, participantCount, params, title, streamDcId, _):
var clientParams: String? var clientParams: String?
if let params = params { if let params = params {
switch params { switch params {
@ -43,7 +48,9 @@ extension GroupCallInfo {
id: id, id: id,
accessHash: accessHash, accessHash: accessHash,
participantCount: Int(participantCount), participantCount: Int(participantCount),
clientParams: clientParams clientParams: clientParams,
streamDcId: streamDcId,
title: title
) )
case .groupCallDiscarded: case .groupCallDiscarded:
return nil return nil
@ -88,8 +95,18 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
loop: for participant in participants { loop: for participant in participants {
switch participant { switch participant {
case let .groupCallParticipant(flags, userId, date, activeDate, source, volume): case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .peerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .peerChannel(channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
}
let ssrc = UInt32(bitPattern: source) let ssrc = UInt32(bitPattern: source)
guard let peer = transaction.getPeer(peerId) else { guard let peer = transaction.getPeer(peerId) else {
continue loop continue loop
@ -118,7 +135,8 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
activityRank: nil, activityRank: nil,
muteState: muteState, muteState: muteState,
volume: volume volume: volume,
about: about
)) ))
} }
} }
@ -139,17 +157,26 @@ public enum CreateGroupCallError {
case anonymousNotAllowed case anonymousNotAllowed
} }
public func createGroupCall(account: Account, peerId: PeerId) -> Signal<GroupCallInfo, CreateGroupCallError> { public func createGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?) -> Signal<GroupCallInfo, CreateGroupCallError> {
return account.postbox.transaction { transaction -> Api.InputPeer? in return account.postbox.transaction { transaction -> (Api.InputPeer?, Api.InputPeer?) in
return transaction.getPeer(peerId).flatMap(apiInputPeer) let callPeer = transaction.getPeer(peerId).flatMap(apiInputPeer)
if let joinAs = joinAs {
return (callPeer, transaction.getPeer(joinAs).flatMap(apiInputPeer))
} else {
return (callPeer, nil)
}
} }
|> castError(CreateGroupCallError.self) |> castError(CreateGroupCallError.self)
|> mapToSignal { inputPeer -> Signal<GroupCallInfo, CreateGroupCallError> in |> mapToSignal { (inputPeer, inputJoinAs) -> Signal<GroupCallInfo, CreateGroupCallError> in
guard let inputPeer = inputPeer else { guard let inputPeer = inputPeer else {
return .fail(.generic) return .fail(.generic)
} }
return account.network.request(Api.functions.phone.createGroupCall(peer: inputPeer, randomId: Int32.random(in: Int32.min ... Int32.max))) var flags: Int32 = 0
if let _ = inputJoinAs {
flags |= (1 << 0)
}
return account.network.request(Api.functions.phone.createGroupCall(flags: flags, peer: inputPeer, joinAs: inputJoinAs, randomId: Int32.random(in: Int32.min ... Int32.max)))
|> mapError { error -> CreateGroupCallError in |> mapError { error -> CreateGroupCallError in
if error.errorDescription == "ANONYMOUS_CALLS_DISABLED" { if error.errorDescription == "ANONYMOUS_CALLS_DISABLED" {
return .anonymousNotAllowed return .anonymousNotAllowed
@ -237,8 +264,17 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
loop: for participant in participants { loop: for participant in participants {
switch participant { switch participant {
case let .groupCallParticipant(flags, userId, date, activeDate, source, volume): case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .peerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .peerChannel(channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
}
let ssrc = UInt32(bitPattern: source) let ssrc = UInt32(bitPattern: source)
guard let peer = transaction.getPeer(peerId) else { guard let peer = transaction.getPeer(peerId) else {
continue loop continue loop
@ -267,7 +303,8 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
activityRank: nil, activityRank: nil,
muteState: muteState, muteState: muteState,
volume: volume volume: volume,
about: about
)) ))
} }
} }
@ -300,184 +337,202 @@ public struct JoinGroupCallResult {
public var state: GroupCallParticipantsContext.State public var state: GroupCallParticipantsContext.State
} }
public func joinGroupCall(account: Account, peerId: PeerId, callId: Int64, accessHash: Int64, preferMuted: Bool, joinPayload: String) -> Signal<JoinGroupCallResult, JoinGroupCallError> { public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, callId: Int64, accessHash: Int64, preferMuted: Bool, joinPayload: String) -> Signal<JoinGroupCallResult, JoinGroupCallError> {
var flags: Int32 = 0
if preferMuted { return account.postbox.transaction { transaction -> Api.InputPeer? in
flags |= (1 << 0) if let joinAs = joinAs {
} return transaction.getPeer(joinAs).flatMap(apiInputPeer)
return account.network.request(Api.functions.phone.joinGroupCall(flags: flags, call: .inputGroupCall(id: callId, accessHash: accessHash), params: .dataJSON(data: joinPayload)))
|> mapError { error -> JoinGroupCallError in
if error.errorDescription == "GROUPCALL_ANONYMOUS_FORBIDDEN" {
return .anonymousNotAllowed
} else if error.errorDescription == "GROUPCALL_PARTICIPANTS_TOO_MUCH" {
return .tooManyParticipants
}
return .generic
}
|> mapToSignal { updates -> Signal<JoinGroupCallResult, JoinGroupCallError> in
let admins: Signal<(Set<PeerId>, [Api.User]), JoinGroupCallError>
if peerId.namespace == Namespaces.Peer.CloudChannel {
admins = account.postbox.transaction { transaction -> Api.InputChannel? in
return transaction.getPeer(peerId).flatMap(apiInputChannel)
}
|> castError(JoinGroupCallError.self)
|> mapToSignal { inputChannel -> Signal<Api.channels.ChannelParticipants, JoinGroupCallError> in
guard let inputChannel = inputChannel else {
return .fail(.generic)
}
return account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: 0))
|> mapError { _ -> JoinGroupCallError in
return .generic
}
}
|> map { admins -> (Set<PeerId>, [Api.User]) in
var adminIds = Set<PeerId>()
var apiUsers: [Api.User] = []
switch admins {
case let .channelParticipants(_, participants, users):
apiUsers.append(contentsOf: users)
for participant in participants {
let parsedParticipant = ChannelParticipant(apiParticipant: participant)
switch parsedParticipant {
case .creator:
adminIds.insert(parsedParticipant.peerId)
case let .member(_, _, adminInfo, _, _):
if let adminInfo = adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
adminIds.insert(parsedParticipant.peerId)
}
}
}
default:
break
}
return (adminIds, apiUsers)
}
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
admins = account.postbox.transaction { transaction -> (Set<PeerId>, [Api.User]) in
var result = Set<PeerId>()
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedGroupData {
if let participants = cachedData.participants {
for participant in participants.participants {
if case .creator = participant {
result.insert(participant.peerId)
} else if case .admin = participant {
result.insert(participant.peerId)
}
}
}
}
return (result, [])
}
|> castError(JoinGroupCallError.self)
} else { } else {
admins = .fail(.generic) return nil
}
}
|> castError(JoinGroupCallError.self)
|> mapToSignal { inputJoinAs in
var flags: Int32 = 0
if preferMuted {
flags |= (1 << 0)
} }
let peer = account.postbox.transaction { transaction -> Peer? in if let _ = inputJoinAs {
return transaction.getPeer(peerId) flags |= (1 << 1)
} }
|> castError(JoinGroupCallError.self)
return combineLatest( return account.network.request(Api.functions.phone.joinGroupCall(flags: flags, call: .inputGroupCall(id: callId, accessHash: accessHash), joinAs: inputJoinAs, params: .dataJSON(data: joinPayload)))
account.network.request(Api.functions.phone.getGroupCall(call: .inputGroupCall(id: callId, accessHash: accessHash))) |> mapError { error -> JoinGroupCallError in
|> mapError { _ -> JoinGroupCallError in if error.errorDescription == "GROUPCALL_ANONYMOUS_FORBIDDEN" {
return .generic return .anonymousNotAllowed
}, } else if error.errorDescription == "GROUPCALL_PARTICIPANTS_TOO_MUCH" {
getGroupCallParticipants(account: account, callId: callId, accessHash: accessHash, offset: "", ssrcs: [], limit: 100) return .tooManyParticipants
|> mapError { _ -> JoinGroupCallError in
return .generic
},
admins,
peer
)
|> mapToSignal { result, state, admins, peer -> Signal<JoinGroupCallResult, JoinGroupCallError> in
guard let peer = peer else {
return .fail(.generic)
} }
return .generic
var state = state }
if let channel = peer as? TelegramChannel { |> mapToSignal { updates -> Signal<JoinGroupCallResult, JoinGroupCallError> in
state.isCreator = channel.flags.contains(.isCreator) let admins: Signal<(Set<PeerId>, [Api.User]), JoinGroupCallError>
} else if let group = peer as? TelegramGroup { if peerId.namespace == Namespaces.Peer.CloudChannel {
if case .creator = group.role { admins = account.postbox.transaction { transaction -> Api.InputChannel? in
state.isCreator = true return transaction.getPeer(peerId).flatMap(apiInputChannel)
} else {
state.isCreator = false
} }
} |> castError(JoinGroupCallError.self)
|> mapToSignal { inputChannel -> Signal<Api.channels.ChannelParticipants, JoinGroupCallError> in
account.stateManager.addUpdates(updates) guard let inputChannel = inputChannel else {
return .fail(.generic)
var maybeParsedCall: GroupCallInfo? }
loop: for update in updates.allUpdates {
switch update {
case let .updateGroupCall(_, call):
maybeParsedCall = GroupCallInfo(call)
switch call { return account.network.request(Api.functions.channels.getParticipants(channel: inputChannel, filter: .channelParticipantsAdmins, offset: 0, limit: 100, hash: 0))
case let .groupCall(flags, _, _, _, _, _): |> mapError { _ -> JoinGroupCallError in
let isMuted = (flags & (1 << 1)) != 0 return .generic
let canChange = (flags & (1 << 2)) != 0 }
state.defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange) }
|> map { admins -> (Set<PeerId>, [Api.User]) in
var adminIds = Set<PeerId>()
var apiUsers: [Api.User] = []
switch admins {
case let .channelParticipants(_, participants, users):
apiUsers.append(contentsOf: users)
for participant in participants {
let parsedParticipant = ChannelParticipant(apiParticipant: participant)
switch parsedParticipant {
case .creator:
adminIds.insert(parsedParticipant.peerId)
case let .member(_, _, adminInfo, _, _):
if let adminInfo = adminInfo, adminInfo.rights.rights.contains(.canManageCalls) {
adminIds.insert(parsedParticipant.peerId)
}
}
}
default: default:
break break
} }
break loop return (adminIds, apiUsers)
default:
break
} }
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
admins = account.postbox.transaction { transaction -> (Set<PeerId>, [Api.User]) in
var result = Set<PeerId>()
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedGroupData {
if let participants = cachedData.participants {
for participant in participants.participants {
if case .creator = participant {
result.insert(participant.peerId)
} else if case .admin = participant {
result.insert(participant.peerId)
}
}
}
}
return (result, [])
}
|> castError(JoinGroupCallError.self)
} else {
admins = .fail(.generic)
} }
guard let parsedCall = maybeParsedCall else { let peer = account.postbox.transaction { transaction -> Peer? in
return .fail(.generic) return transaction.getPeer(peerId)
} }
|> castError(JoinGroupCallError.self)
var apiUsers: [Api.User] = [] return combineLatest(
account.network.request(Api.functions.phone.getGroupCall(call: .inputGroupCall(id: callId, accessHash: accessHash)))
let (adminIds, adminUsers) = admins |> mapError { _ -> JoinGroupCallError in
apiUsers.append(contentsOf: adminUsers) return .generic
},
state.adminIds = adminIds getGroupCallParticipants(account: account, callId: callId, accessHash: accessHash, offset: "", ssrcs: [], limit: 100)
|> mapError { _ -> JoinGroupCallError in
switch result { return .generic
case let .groupCall(call, _, _, users): },
guard let _ = GroupCallInfo(call) else { admins,
peer
)
|> mapToSignal { result, state, admins, peer -> Signal<JoinGroupCallResult, JoinGroupCallError> in
guard let peer = peer else {
return .fail(.generic) return .fail(.generic)
} }
apiUsers.append(contentsOf: users) var state = state
if let channel = peer as? TelegramChannel {
var peers: [Peer] = [] state.isCreator = channel.flags.contains(.isCreator)
var peerPresences: [PeerId: PeerPresence] = [:] } else if let group = peer as? TelegramGroup {
if case .creator = group.role {
for user in apiUsers { state.isCreator = true
let telegramUser = TelegramUser(user: user) } else {
peers.append(telegramUser) state.isCreator = false
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
} }
} }
return account.postbox.transaction { transaction -> JoinGroupCallResult in account.stateManager.addUpdates(updates)
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
return updated var maybeParsedCall: GroupCallInfo?
}) loop: for update in updates.allUpdates {
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences) switch update {
case let .updateGroupCall(_, call):
return JoinGroupCallResult( maybeParsedCall = GroupCallInfo(call)
callInfo: parsedCall,
state: state switch call {
) case let .groupCall(flags, _, _, _, _, _, _, _):
let isMuted = (flags & (1 << 1)) != 0
let canChange = (flags & (1 << 2)) != 0
state.defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange)
default:
break
}
break loop
default:
break
}
}
guard let parsedCall = maybeParsedCall else {
return .fail(.generic)
}
var apiUsers: [Api.User] = []
let (adminIds, adminUsers) = admins
apiUsers.append(contentsOf: adminUsers)
state.adminIds = adminIds
switch result {
case let .groupCall(call, _, _, users):
guard let _ = GroupCallInfo(call) else {
return .fail(.generic)
}
apiUsers.append(contentsOf: users)
var peers: [Peer] = []
var peerPresences: [PeerId: PeerPresence] = [:]
for user in apiUsers {
let telegramUser = TelegramUser(user: user)
peers.append(telegramUser)
if let presence = TelegramUserPresence(apiUser: user) {
peerPresences[telegramUser.id] = presence
}
}
return account.postbox.transaction { transaction -> JoinGroupCallResult in
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
return updated
})
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
return JoinGroupCallResult(
callInfo: parsedCall,
state: state
)
}
|> castError(JoinGroupCallError.self)
} }
|> castError(JoinGroupCallError.self)
} }
} }
} }
} }
public enum LeaveGroupCallError { public enum LeaveGroupCallError {
@ -598,7 +653,7 @@ public final class GroupCallParticipantsContext {
public var activityRank: Int? public var activityRank: Int?
public var muteState: MuteState? public var muteState: MuteState?
public var volume: Int32? public var volume: Int32?
public var about: String?
public init( public init(
peer: Peer, peer: Peer,
ssrc: UInt32, ssrc: UInt32,
@ -607,7 +662,8 @@ public final class GroupCallParticipantsContext {
activityTimestamp: Double?, activityTimestamp: Double?,
activityRank: Int?, activityRank: Int?,
muteState: MuteState?, muteState: MuteState?,
volume: Int32? volume: Int32?,
about: String?
) { ) {
self.peer = peer self.peer = peer
self.ssrc = ssrc self.ssrc = ssrc
@ -617,6 +673,7 @@ public final class GroupCallParticipantsContext {
self.activityRank = activityRank self.activityRank = activityRank
self.muteState = muteState self.muteState = muteState
self.volume = volume self.volume = volume
self.about = about
} }
public static func ==(lhs: Participant, rhs: Participant) -> Bool { public static func ==(lhs: Participant, rhs: Participant) -> Bool {
@ -641,6 +698,9 @@ public final class GroupCallParticipantsContext {
if lhs.volume != rhs.volume { if lhs.volume != rhs.volume {
return false return false
} }
if lhs.about != rhs.about {
return false
}
return true return true
} }
@ -740,7 +800,7 @@ public final class GroupCallParticipantsContext {
public var muteState: Participant.MuteState? public var muteState: Participant.MuteState?
public var participationStatusChange: ParticipationStatusChange public var participationStatusChange: ParticipationStatusChange
public var volume: Int32? public var volume: Int32?
public var about: String?
init( init(
peerId: PeerId, peerId: PeerId,
ssrc: UInt32, ssrc: UInt32,
@ -749,7 +809,8 @@ public final class GroupCallParticipantsContext {
activityTimestamp: Double?, activityTimestamp: Double?,
muteState: Participant.MuteState?, muteState: Participant.MuteState?,
participationStatusChange: ParticipationStatusChange, participationStatusChange: ParticipationStatusChange,
volume: Int32? volume: Int32?,
about: String?
) { ) {
self.peerId = peerId self.peerId = peerId
self.ssrc = ssrc self.ssrc = ssrc
@ -759,6 +820,7 @@ public final class GroupCallParticipantsContext {
self.muteState = muteState self.muteState = muteState
self.participationStatusChange = participationStatusChange self.participationStatusChange = participationStatusChange
self.volume = volume self.volume = volume
self.about = about
} }
} }
@ -1213,7 +1275,8 @@ public final class GroupCallParticipantsContext {
activityTimestamp: activityTimestamp, activityTimestamp: activityTimestamp,
activityRank: previousActivityRank, activityRank: previousActivityRank,
muteState: participantUpdate.muteState, muteState: participantUpdate.muteState,
volume: participantUpdate.volume volume: participantUpdate.volume,
about: participantUpdate.about
) )
updatedParticipants.append(participant) updatedParticipants.append(participant)
} }
@ -1300,11 +1363,11 @@ public final class GroupCallParticipantsContext {
let id = self.id let id = self.id
let accessHash = self.accessHash let accessHash = self.accessHash
let signal: Signal<Api.Updates?, NoError> = self.account.postbox.transaction { transaction -> Api.InputUser? in let signal: Signal<Api.Updates?, NoError> = self.account.postbox.transaction { transaction -> Api.InputPeer? in
return transaction.getPeer(peerId).flatMap(apiInputUser) return transaction.getPeer(peerId).flatMap(apiInputPeer)
} }
|> mapToSignal { inputUser -> Signal<Api.Updates?, NoError> in |> mapToSignal { inputPeer -> Signal<Api.Updates?, NoError> in
guard let inputUser = inputUser else { guard let inputPeer = inputPeer else {
return .single(nil) return .single(nil)
} }
var flags: Int32 = 0 var flags: Int32 = 0
@ -1314,8 +1377,8 @@ public final class GroupCallParticipantsContext {
if let muteState = muteState, (!muteState.canUnmute || peerId == account.peerId || muteState.mutedByYou) { if let muteState = muteState, (!muteState.canUnmute || peerId == account.peerId || muteState.mutedByYou) {
flags |= 1 << 0 flags |= 1 << 0
} }
return account.network.request(Api.functions.phone.editGroupCallMember(flags: flags, call: .inputGroupCall(id: id, accessHash: accessHash), userId: inputUser, volume: volume)) return account.network.request(Api.functions.phone.editGroupCallParticipant(flags: flags, call: .inputGroupCall(id: id, accessHash: accessHash), participant: inputPeer, volume: volume))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.Updates?, NoError> in |> `catch` { _ -> Signal<Api.Updates?, NoError> in
return .single(nil) return .single(nil)
@ -1407,8 +1470,16 @@ public final class GroupCallParticipantsContext {
extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate { extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
init(_ apiParticipant: Api.GroupCallParticipant) { init(_ apiParticipant: Api.GroupCallParticipant) {
switch apiParticipant { switch apiParticipant {
case let .groupCallParticipant(flags, userId, date, activeDate, source, volume): case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .peerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .peerChannel(channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
}
let ssrc = UInt32(bitPattern: source) let ssrc = UInt32(bitPattern: source)
let muted = (flags & (1 << 0)) != 0 let muted = (flags & (1 << 0)) != 0
let mutedByYou = (flags & (1 << 9)) != 0 let mutedByYou = (flags & (1 << 9)) != 0
@ -1447,7 +1518,8 @@ extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
muteState: muteState, muteState: muteState,
participationStatusChange: participationStatusChange, participationStatusChange: participationStatusChange,
volume: volume volume: volume,
about: about
) )
} }
} }
@ -1458,8 +1530,16 @@ extension GroupCallParticipantsContext.Update.StateUpdate {
var participantUpdates: [GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate] = [] var participantUpdates: [GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate] = []
for participant in participants { for participant in participants {
switch participant { switch participant {
case let .groupCallParticipant(flags, userId, date, activeDate, source, volume): case let .groupCallParticipant(flags, apiPeerId, date, activeDate, source, volume, about):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) let peerId: PeerId
switch apiPeerId {
case let .peerUser(userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .peerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .peerChannel(channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
}
let ssrc = UInt32(bitPattern: source) let ssrc = UInt32(bitPattern: source)
let muted = (flags & (1 << 0)) != 0 let muted = (flags & (1 << 0)) != 0
let mutedByYou = (flags & (1 << 9)) != 0 let mutedByYou = (flags & (1 << 9)) != 0
@ -1498,7 +1578,8 @@ extension GroupCallParticipantsContext.Update.StateUpdate {
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
muteState: muteState, muteState: muteState,
participationStatusChange: participationStatusChange, participationStatusChange: participationStatusChange,
volume: volume volume: volume,
about: about
)) ))
} }
} }
@ -1540,6 +1621,20 @@ public func inviteToGroupCall(account: Account, callId: Int64, accessHash: Int64
} }
} }
public enum EditGroupCallTitleError {
case generic
}
public func editGroupCallTitle(account: Account, callId: Int64, accessHash: Int64, title: String) -> Signal<Never, EditGroupCallTitleError> {
return account.network.request(Api.functions.phone.editGroupCallTitle(call: .inputGroupCall(id: callId, accessHash: accessHash), title: title)) |> mapError { _ -> EditGroupCallTitleError in
return .generic
}
|> mapToSignal { result -> Signal<Never, EditGroupCallTitleError> in
account.stateManager.addUpdates(result)
return .complete()
}
}
public func updatedCurrentPeerGroupCall(account: Account, peerId: PeerId) -> Signal<CachedChannelData.ActiveCall?, NoError> { public func updatedCurrentPeerGroupCall(account: Account, peerId: PeerId) -> Signal<CachedChannelData.ActiveCall?, NoError> {
return fetchAndUpdateCachedPeerData(accountPeerId: account.peerId, peerId: peerId, network: account.network, postbox: account.postbox) return fetchAndUpdateCachedPeerData(accountPeerId: account.peerId, peerId: peerId, network: account.network, postbox: account.postbox)
|> mapToSignal { _ -> Signal<CachedChannelData.ActiveCall?, NoError> in |> mapToSignal { _ -> Signal<CachedChannelData.ActiveCall?, NoError> in

View File

@ -188,14 +188,17 @@ public func requestMessageActionUrlAuth(account: Account, subject: MessageAction
|> castError(MTRpcError.self) |> castError(MTRpcError.self)
|> mapToSignal { peer -> Signal<Api.UrlAuthResult?, MTRpcError> in |> mapToSignal { peer -> Signal<Api.UrlAuthResult?, MTRpcError> in
if let inputPeer = apiInputPeer(peer) { if let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.requestUrlAuth(peer: inputPeer, msgId: messageId.id, buttonId: buttonId)) let flags: Int32 = 1 << 1
return account.network.request(Api.functions.messages.requestUrlAuth(flags: flags, peer: inputPeer, msgId: messageId.id, buttonId: buttonId, url: nil))
|> map(Optional.init) |> map(Optional.init)
} else { } else {
return .single(nil) return .single(nil)
} }
} }
case let .url(url): case let .url(url):
request = account.network.request(Api.functions.messages.requestUrlAuth(peer: .inputPeerEmpty, msgId: 0, buttonId: 0)) var flags: Int32 = 1 << 1
flags |= (1 << 2)
request = account.network.request(Api.functions.messages.requestUrlAuth(flags: flags, peer: .inputPeerEmpty, msgId: 0, buttonId: 0, url: url))
|> map(Optional.init) |> map(Optional.init)
} }
@ -232,14 +235,17 @@ public func acceptMessageActionUrlAuth(account: Account, subject: MessageActionU
|> castError(MTRpcError.self) |> castError(MTRpcError.self)
|> mapToSignal { peer -> Signal<Api.UrlAuthResult?, MTRpcError> in |> mapToSignal { peer -> Signal<Api.UrlAuthResult?, MTRpcError> in
if let inputPeer = apiInputPeer(peer) { if let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.acceptUrlAuth(flags: flags, peer: inputPeer, msgId: messageId.id, buttonId: buttonId)) let flags: Int32 = 1 << 1
return account.network.request(Api.functions.messages.acceptUrlAuth(flags: flags, peer: inputPeer, msgId: messageId.id, buttonId: buttonId, url: nil))
|> map(Optional.init) |> map(Optional.init)
} else { } else {
return .single(nil) return .single(nil)
} }
} }
case let .url(url): case let .url(url):
request = account.network.request(Api.functions.messages.acceptUrlAuth(flags: flags, peer: .inputPeerEmpty, msgId: 0, buttonId: 0)) var flags: Int32 = 1 << 1
flags |= (1 << 2)
request = account.network.request(Api.functions.messages.acceptUrlAuth(flags: flags, peer: .inputPeerEmpty, msgId: 0, buttonId: 0, url: url))
|> map(Optional.init) |> map(Optional.init)
} }

View File

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

View File

@ -1,8 +1,8 @@
import Foundation import Foundation
import SwiftSignalKit import SwiftSignalKit
import TgVoipWebrtc import TgVoipWebrtc
import UniversalMediaPlayer //import UniversalMediaPlayer
import AppBundle //import AppBundle
import OpusBinding import OpusBinding
private final class ContextQueueImpl: NSObject, OngoingCallThreadLocalContextQueueWebrtc { private final class ContextQueueImpl: NSObject, OngoingCallThreadLocalContextQueueWebrtc {
@ -62,17 +62,17 @@ private final class DemoBroadcastPacketSource {
var packets: [OngoingGroupCallBroadcastPacket] = [] var packets: [OngoingGroupCallBroadcastPacket] = []
let fileName = String(format: "%04d", index) // let fileName = String(format: "%04d", index)
if let path = getAppBundle().path(forResource: fileName, ofType: "ogg") { // if let path = getAppBundle().path(forResource: fileName, ofType: "ogg") {
let source = SoftwareAudioSource(path: path) // let source = SoftwareAudioSource(path: path)
while true { // while true {
if let frame = source.readFrame() { // if let frame = source.readFrame() {
packets.append(OngoingGroupCallBroadcastPacket(numSamples: Int32(frame.count / 2), data: frame)) // packets.append(OngoingGroupCallBroadcastPacket(numSamples: Int32(frame.count / 2), data: frame))
} else { // } else {
break // break
} // }
} // }
} // }
if !packets.isEmpty { if !packets.isEmpty {
self.enqueuedPackets.append(contentsOf: packets) self.enqueuedPackets.append(contentsOf: packets)

View File

@ -1402,16 +1402,16 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
if (!_instance) { if (!_instance) {
return; return;
} }
//
std::vector<tgcalls::BroadcastPacket> parsedPackets; // std::vector<tgcalls::BroadcastPacket> parsedPackets;
for (OngoingGroupCallBroadcastPacket *packet in packets) { // for (OngoingGroupCallBroadcastPacket *packet in packets) {
tgcalls::BroadcastPacket parsedPacket; // tgcalls::BroadcastPacket parsedPacket;
parsedPacket.numSamples = packet.numSamples; // parsedPacket.numSamples = packet.numSamples;
parsedPacket.data.resize(packet.data.length); // parsedPacket.data.resize(packet.data.length);
[packet.data getBytes:parsedPacket.data.data() length:packet.data.length]; // [packet.data getBytes:parsedPacket.data.data() length:packet.data.length];
parsedPackets.push_back(std::move(parsedPacket)); // parsedPackets.push_back(std::move(parsedPacket));
} // }
((tgcalls::GroupInstanceCustomImpl *)(_instance.get()))->addBroadcastPackets(std::move(parsedPackets)); // ((tgcalls::GroupInstanceCustomImpl *)(_instance.get()))->addBroadcastPackets(std::move(parsedPackets));
} }
@end @end