AzureCommunicationUI/sdk/AzureCommunicationUICalling/Sources/Presentation/Manager/RemoteParticipantsManager.swift (66 lines of code) (raw):
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
import AzureCommunicationCalling
import Combine
import Foundation
protocol RemoteParticipantsManagerProtocol {
}
class RemoteParticipantsManager: RemoteParticipantsManagerProtocol {
private let store: Store<AppState, Action>
private let eventsHandler: CallComposite.Events
private let avatarViewManager: AvatarViewManagerProtocol
private var participantsLastUpdateTimeStamp = Date()
private var participantsIds: Set<String> = []
var cancellables = Set<AnyCancellable>()
init(store: Store<AppState, Action>,
callCompositeEventsHandler: CallComposite.Events,
avatarViewManager: AvatarViewManagerProtocol) {
self.store = store
self.eventsHandler = callCompositeEventsHandler
self.avatarViewManager = avatarViewManager
store.$state
.receive(on: DispatchQueue.main)
.sink { [weak self] state in
self?.receive(state)
}.store(in: &cancellables)
}
private func receive(_ state: AppState) {
guard participantsLastUpdateTimeStamp != state.remoteParticipantsState.lastUpdateTimeStamp else {
return
}
participantsLastUpdateTimeStamp = state.remoteParticipantsState.lastUpdateTimeStamp
let updatedParticipantsIds = Set(state.remoteParticipantsState.participantInfoList.map { $0.userIdentifier })
let joinedParticipantsIds = updatedParticipantsIds.subtracting(participantsIds)
let removedParticipantsIds = participantsIds.subtracting(updatedParticipantsIds)
participantsIds = updatedParticipantsIds
postRemoteParticipantsJoinedEvent(joinedParticipantsIds)
postRemoteParticipantsRemovedEvent(removedParticipantsIds)
postRemoteParticipantsLeftEvent(removedParticipantsIds)
}
private func postRemoteParticipantsRemovedEvent(_ removedParticipantsIds: Set<String>) {
// check if participants were removed from a call
guard !removedParticipantsIds.isEmpty else {
return
}
avatarViewManager.updateStorage(with: Array(removedParticipantsIds))
}
private func postRemoteParticipantsJoinedEvent(_ joinedParticipantsIds: Set<String>) {
guard let didRemoteParticipantsJoin = eventsHandler.onRemoteParticipantJoined else {
return
}
// check if new participants joined a call
guard !joinedParticipantsIds.isEmpty else {
return
}
let joinedParticipantsCommunicationIds: [CommunicationIdentifier] = joinedParticipantsIds
.compactMap { createCommunicationIdentifier(fromRawId: $0) }
didRemoteParticipantsJoin(joinedParticipantsCommunicationIds)
}
private func postRemoteParticipantsLeftEvent(_ leftOrRemovedParticipantIds: Set<String>) {
guard !leftOrRemovedParticipantIds.isEmpty else {
return
}
guard let didRemoteParticipantsLeft = eventsHandler.onRemoteParticipantLeft else {
return
}
let leftParticipantsCommunicationIds: [CommunicationIdentifier] = leftOrRemovedParticipantIds
.compactMap { createCommunicationIdentifier(fromRawId: $0) }
didRemoteParticipantsLeft(leftParticipantsCommunicationIds)
}
}