mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
update api to 125 layer [skip ci]
This commit is contained in:
parent
796c77b11d
commit
a5e886559b
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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! {
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user