mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 01:10:09 +00:00
Voice chat fixes
This commit is contained in:
parent
5f19374c9d
commit
fab42fd01d
@ -302,6 +302,8 @@ public protocol PresentationGroupCall: class {
|
|||||||
func invitePeer(_ peerId: PeerId) -> Bool
|
func invitePeer(_ peerId: PeerId) -> Bool
|
||||||
func removedPeer(_ peerId: PeerId)
|
func removedPeer(_ peerId: PeerId)
|
||||||
var invitedPeers: Signal<[PeerId], NoError> { get }
|
var invitedPeers: Signal<[PeerId], NoError> { get }
|
||||||
|
|
||||||
|
func loadMoreMembers(token: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol PresentationCallManager: class {
|
public protocol PresentationCallManager: class {
|
||||||
|
|||||||
@ -57,7 +57,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
|
|||||||
groupCall: nil
|
groupCall: nil
|
||||||
)))
|
)))
|
||||||
|
|
||||||
self.disposable = (getGroupCallParticipants(account: account, callId: call.id, accessHash: call.accessHash, offset: "", limit: 100)
|
self.disposable = (getGroupCallParticipants(account: account, callId: call.id, accessHash: call.accessHash, offset: "", peerIds: [], limit: 100)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<GroupCallParticipantsContext.State?, NoError> in
|
|> `catch` { _ -> Signal<GroupCallParticipantsContext.State?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
@ -1476,4 +1476,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
public func updateDefaultParticipantsAreMuted(isMuted: Bool) {
|
public func updateDefaultParticipantsAreMuted(isMuted: Bool) {
|
||||||
self.participantsContext?.updateDefaultParticipantsAreMuted(isMuted: isMuted)
|
self.participantsContext?.updateDefaultParticipantsAreMuted(isMuted: isMuted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func loadMoreMembers(token: String) {
|
||||||
|
self.participantsContext?.loadMore(token: token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -375,14 +375,14 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func preparedTransition(from fromEntries: [ListEntry], to toEntries: [ListEntry], isLoading: Bool, isEmpty: Bool, crossFade: Bool, context: AccountContext, presentationData: PresentationData, interaction: Interaction) -> ListTransition {
|
private func preparedTransition(from fromEntries: [ListEntry], to toEntries: [ListEntry], isLoading: Bool, isEmpty: Bool, crossFade: Bool, animated: Bool, context: AccountContext, presentationData: PresentationData, interaction: Interaction) -> ListTransition {
|
||||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||||
|
|
||||||
return ListTransition(deletions: deletions, insertions: insertions, updates: updates, isLoading: isLoading, isEmpty: isEmpty, crossFade: crossFade, count: toEntries.count, animated: true)
|
return ListTransition(deletions: deletions, insertions: insertions, updates: updates, isLoading: isLoading, isEmpty: isEmpty, crossFade: crossFade, count: toEntries.count, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
private weak var controller: VoiceChatController?
|
private weak var controller: VoiceChatController?
|
||||||
@ -424,7 +424,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
|
|
||||||
private var currentTitle: String = ""
|
private var currentTitle: String = ""
|
||||||
private var currentSubtitle: String = ""
|
private var currentSubtitle: String = ""
|
||||||
private var currentCallMembers: [GroupCallParticipantsContext.Participant]?
|
private var currentCallMembers: ([GroupCallParticipantsContext.Participant], String?)?
|
||||||
private var currentInvitedPeers: [Peer]?
|
private var currentInvitedPeers: [Peer]?
|
||||||
private var currentSpeakingPeers: Set<PeerId>?
|
private var currentSpeakingPeers: Set<PeerId>?
|
||||||
private var currentContentOffset: CGFloat?
|
private var currentContentOffset: CGFloat?
|
||||||
@ -445,6 +445,8 @@ public final class VoiceChatController: ViewController {
|
|||||||
|
|
||||||
private var callState: PresentationGroupCallState?
|
private var callState: PresentationGroupCallState?
|
||||||
|
|
||||||
|
private var currentLoadToken: String?
|
||||||
|
|
||||||
private var effectiveMuteState: GroupCallParticipantsContext.Participant.MuteState? {
|
private var effectiveMuteState: GroupCallParticipantsContext.Participant.MuteState? {
|
||||||
if self.pushingToTalk {
|
if self.pushingToTalk {
|
||||||
return nil
|
return nil
|
||||||
@ -577,7 +579,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var filters: [ChannelMembersSearchFilter] = []
|
var filters: [ChannelMembersSearchFilter] = []
|
||||||
if let currentCallMembers = strongSelf.currentCallMembers {
|
if let (currentCallMembers, _) = strongSelf.currentCallMembers {
|
||||||
filters.append(.disable(Array(currentCallMembers.map { $0.peer.id })))
|
filters.append(.disable(Array(currentCallMembers.map { $0.peer.id })))
|
||||||
}
|
}
|
||||||
if let groupPeer = groupPeer as? TelegramChannel {
|
if let groupPeer = groupPeer as? TelegramChannel {
|
||||||
@ -1030,7 +1032,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: callMembers?.participants ?? [], invitedPeers: invitedPeers, speakingPeers: callMembers?.speakingParticipants ?? [])
|
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: (callMembers?.participants ?? [], callMembers?.loadMoreToken), invitedPeers: invitedPeers, speakingPeers: callMembers?.speakingParticipants ?? [])
|
||||||
|
|
||||||
let subtitle = strongSelf.presentationData.strings.VoiceChat_Panel_Members(Int32(max(1, callMembers?.totalCount ?? 0)))
|
let subtitle = strongSelf.presentationData.strings.VoiceChat_Panel_Members(Int32(max(1, callMembers?.totalCount ?? 0)))
|
||||||
strongSelf.currentSubtitle = subtitle
|
strongSelf.currentSubtitle = subtitle
|
||||||
@ -1059,7 +1061,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
if !strongSelf.didSetDataReady {
|
if !strongSelf.didSetDataReady {
|
||||||
strongSelf.accountPeer = accountPeer
|
strongSelf.accountPeer = accountPeer
|
||||||
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: strongSelf.currentCallMembers ?? [], invitedPeers: strongSelf.currentInvitedPeers ?? [], speakingPeers: strongSelf.currentSpeakingPeers ?? Set())
|
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: strongSelf.currentCallMembers ?? ([], nil), invitedPeers: strongSelf.currentInvitedPeers ?? [], speakingPeers: strongSelf.currentSpeakingPeers ?? Set())
|
||||||
|
|
||||||
strongSelf.didSetDataReady = true
|
strongSelf.didSetDataReady = true
|
||||||
strongSelf.controller?.dataReady.set(true)
|
strongSelf.controller?.dataReady.set(true)
|
||||||
@ -1223,6 +1225,18 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.listNode.visibleBottomContentOffsetChanged = { [weak self] offset in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if case let .known(value) = offset, value < 100.0 {
|
||||||
|
if let loadMoreToken = strongSelf.currentCallMembers?.1 {
|
||||||
|
strongSelf.currentLoadToken = loadMoreToken
|
||||||
|
strongSelf.call.loadMoreMembers(token: loadMoreToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.memberEventsDisposable.set((self.call.memberEvents
|
self.memberEventsDisposable.set((self.call.memberEvents
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] event in
|
|> deliverOnMainQueue).start(next: { [weak self] event in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -1336,7 +1350,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring))
|
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring))
|
||||||
}
|
}
|
||||||
|
|
||||||
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? [], invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set())
|
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? ([], nil), invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set())
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func actionButtonPressGesture(_ gestureRecognizer: UILongPressGestureRecognizer) {
|
@objc private func actionButtonPressGesture(_ gestureRecognizer: UILongPressGestureRecognizer) {
|
||||||
@ -1381,7 +1395,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
if let (layout, navigationHeight) = self.validLayout {
|
if let (layout, navigationHeight) = self.validLayout {
|
||||||
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring))
|
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring))
|
||||||
}
|
}
|
||||||
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? [], invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set())
|
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? ([], nil), invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set())
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -2030,7 +2044,12 @@ public final class VoiceChatController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: [GroupCallParticipantsContext.Participant], invitedPeers: [Peer], speakingPeers: Set<PeerId>) {
|
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: ([GroupCallParticipantsContext.Participant], String?), invitedPeers: [Peer], speakingPeers: Set<PeerId>) {
|
||||||
|
var disableAnimation = false
|
||||||
|
if self.currentCallMembers?.1 != callMembers.1 {
|
||||||
|
disableAnimation = true
|
||||||
|
}
|
||||||
|
|
||||||
self.currentCallMembers = callMembers
|
self.currentCallMembers = callMembers
|
||||||
self.currentSpeakingPeers = speakingPeers
|
self.currentSpeakingPeers = speakingPeers
|
||||||
self.currentInvitedPeers = invitedPeers
|
self.currentInvitedPeers = invitedPeers
|
||||||
@ -2044,7 +2063,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
|
|
||||||
entries.append(.invite(self.presentationData.theme, self.presentationData.strings, self.presentationData.strings.VoiceChat_InviteMember))
|
entries.append(.invite(self.presentationData.theme, self.presentationData.strings, self.presentationData.strings.VoiceChat_InviteMember))
|
||||||
|
|
||||||
for member in callMembers {
|
for member in callMembers.0 {
|
||||||
if processedPeerIds.contains(member.peer.id) {
|
if processedPeerIds.contains(member.peer.id) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -2109,7 +2128,7 @@ public final class VoiceChatController: ViewController {
|
|||||||
self.currentEntries = entries
|
self.currentEntries = entries
|
||||||
|
|
||||||
let presentationData = self.presentationData.withUpdated(theme: self.darkTheme)
|
let presentationData = self.presentationData.withUpdated(theme: self.darkTheme)
|
||||||
let transition = preparedTransition(from: previousEntries, to: entries, isLoading: false, isEmpty: false, crossFade: false, context: self.context, presentationData: presentationData, interaction: self.itemInteraction!)
|
let transition = preparedTransition(from: previousEntries, to: entries, isLoading: false, isEmpty: false, crossFade: false, animated: !disableAnimation, context: self.context, presentationData: presentationData, interaction: self.itemInteraction!)
|
||||||
self.enqueueTransition(transition)
|
self.enqueueTransition(transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -187,8 +187,8 @@ public enum GetGroupCallParticipantsError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, limit: Int32) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> {
|
public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, peerIds: [PeerId], limit: Int32) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> {
|
||||||
return account.network.request(Api.functions.phone.getGroupParticipants(call: .inputGroupCall(id: callId, accessHash: accessHash), ids: [], sources: [], offset: offset, limit: limit))
|
return account.network.request(Api.functions.phone.getGroupParticipants(call: .inputGroupCall(id: callId, accessHash: accessHash), ids: peerIds.map { $0.id }, sources: [], offset: offset, limit: limit))
|
||||||
|> mapError { _ -> GetGroupCallParticipantsError in
|
|> mapError { _ -> GetGroupCallParticipantsError in
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, callId: Int64, acces
|
|||||||
|> mapError { _ -> JoinGroupCallError in
|
|> mapError { _ -> JoinGroupCallError in
|
||||||
return .generic
|
return .generic
|
||||||
},
|
},
|
||||||
getGroupCallParticipants(account: account, callId: callId, accessHash: accessHash, offset: "", limit: 100)
|
getGroupCallParticipants(account: account, callId: callId, accessHash: accessHash, offset: "", peerIds: [], limit: 100)
|
||||||
|> mapError { _ -> JoinGroupCallError in
|
|> mapError { _ -> JoinGroupCallError in
|
||||||
return .generic
|
return .generic
|
||||||
},
|
},
|
||||||
@ -718,7 +718,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
private let id: Int64
|
private let id: Int64
|
||||||
private let accessHash: Int64
|
private let accessHash: Int64
|
||||||
|
|
||||||
private var hasReceivedSpeackingParticipantsReport: Bool = false
|
private var hasReceivedSpeakingParticipantsReport: Bool = false
|
||||||
|
|
||||||
private var stateValue: InternalState {
|
private var stateValue: InternalState {
|
||||||
didSet {
|
didSet {
|
||||||
@ -770,6 +770,10 @@ public final class GroupCallParticipantsContext {
|
|||||||
private let updatesDisposable = MetaDisposable()
|
private let updatesDisposable = MetaDisposable()
|
||||||
private var activitiesDisposable: Disposable?
|
private var activitiesDisposable: Disposable?
|
||||||
|
|
||||||
|
private var isLoadingMore: Bool = false
|
||||||
|
private var shouldResetStateFromServer: Bool = false
|
||||||
|
private var missingPeerIds = Set<PeerId>()
|
||||||
|
|
||||||
private let updateDefaultMuteDisposable = MetaDisposable()
|
private let updateDefaultMuteDisposable = MetaDisposable()
|
||||||
|
|
||||||
public init(account: Account, peerId: PeerId, id: Int64, accessHash: Int64, state: State) {
|
public init(account: Account, peerId: PeerId, id: Int64, accessHash: Int64, state: State) {
|
||||||
@ -802,11 +806,14 @@ public final class GroupCallParticipantsContext {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.activeSpeakersValue = Set(activities.map { item -> PeerId in
|
let peerIds = Set(activities.map { item -> PeerId in
|
||||||
item.0
|
item.0
|
||||||
})
|
})
|
||||||
|
strongSelf.activeSpeakersValue = peerIds
|
||||||
|
|
||||||
if !strongSelf.hasReceivedSpeackingParticipantsReport {
|
strongSelf.ensureHaveParticipants(peerIds: peerIds)
|
||||||
|
|
||||||
|
if !strongSelf.hasReceivedSpeakingParticipantsReport {
|
||||||
var updatedParticipants = strongSelf.stateValue.state.participants
|
var updatedParticipants = strongSelf.stateValue.state.participants
|
||||||
var indexMap: [PeerId: Int] = [:]
|
var indexMap: [PeerId: Int] = [:]
|
||||||
for i in 0 ..< updatedParticipants.count {
|
for i in 0 ..< updatedParticipants.count {
|
||||||
@ -885,7 +892,7 @@ public final class GroupCallParticipantsContext {
|
|||||||
|
|
||||||
public func reportSpeakingParticipants(ids: [PeerId]) {
|
public func reportSpeakingParticipants(ids: [PeerId]) {
|
||||||
if !ids.isEmpty {
|
if !ids.isEmpty {
|
||||||
self.hasReceivedSpeackingParticipantsReport = true
|
self.hasReceivedSpeakingParticipantsReport = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let strongSelf = self
|
let strongSelf = self
|
||||||
@ -942,6 +949,75 @@ public final class GroupCallParticipantsContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func ensureHaveParticipants(peerIds: Set<PeerId>) {
|
||||||
|
var missingPeerIds = Set<PeerId>()
|
||||||
|
|
||||||
|
var existingParticipantIds = Set<PeerId>()
|
||||||
|
for participant in self.stateValue.state.participants {
|
||||||
|
existingParticipantIds.insert(participant.peer.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
for peerId in peerIds {
|
||||||
|
if !existingParticipantIds.contains(peerId) {
|
||||||
|
missingPeerIds.insert(peerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !missingPeerIds.isEmpty {
|
||||||
|
self.missingPeerIds.formUnion(missingPeerIds)
|
||||||
|
self.loadMissingPeers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadMissingPeers() {
|
||||||
|
if self.missingPeerIds.isEmpty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.isLoadingMore {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.isLoadingMore = true
|
||||||
|
|
||||||
|
let peerIds = self.missingPeerIds
|
||||||
|
|
||||||
|
self.disposable.set((getGroupCallParticipants(account: self.account, callId: self.id, accessHash: self.accessHash, offset: "", peerIds: Array(peerIds), limit: 100)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.isLoadingMore = false
|
||||||
|
|
||||||
|
strongSelf.missingPeerIds.subtract(peerIds)
|
||||||
|
|
||||||
|
var updatedState = strongSelf.stateValue.state
|
||||||
|
|
||||||
|
var existingParticipantIds = Set<PeerId>()
|
||||||
|
for participant in updatedState.participants {
|
||||||
|
existingParticipantIds.insert(participant.peer.id)
|
||||||
|
}
|
||||||
|
for participant in state.participants {
|
||||||
|
if existingParticipantIds.contains(participant.peer.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
existingParticipantIds.insert(participant.peer.id)
|
||||||
|
updatedState.participants.append(participant)
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedState.participants.sort()
|
||||||
|
|
||||||
|
updatedState.totalCount = max(updatedState.totalCount, state.totalCount)
|
||||||
|
updatedState.version = max(updatedState.version, updatedState.version)
|
||||||
|
|
||||||
|
strongSelf.stateValue.state = updatedState
|
||||||
|
|
||||||
|
if strongSelf.shouldResetStateFromServer {
|
||||||
|
strongSelf.resetStateFromServer()
|
||||||
|
} else {
|
||||||
|
strongSelf.loadMissingPeers()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
private func beginProcessingUpdatesIfNeeded() {
|
private func beginProcessingUpdatesIfNeeded() {
|
||||||
if self.isProcessingUpdate {
|
if self.isProcessingUpdate {
|
||||||
return
|
return
|
||||||
@ -1080,13 +1156,22 @@ public final class GroupCallParticipantsContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func resetStateFromServer() {
|
private func resetStateFromServer() {
|
||||||
|
if self.isLoadingMore {
|
||||||
|
self.shouldResetStateFromServer = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.isLoadingMore = true
|
||||||
|
|
||||||
self.updateQueue.removeAll()
|
self.updateQueue.removeAll()
|
||||||
|
|
||||||
self.disposable.set((getGroupCallParticipants(account: self.account, callId: self.id, accessHash: self.accessHash, offset: "", limit: 100)
|
self.disposable.set((getGroupCallParticipants(account: self.account, callId: self.id, accessHash: self.accessHash, offset: "", peerIds: [], limit: 100)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] state in
|
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
strongSelf.isLoadingMore = false
|
||||||
|
strongSelf.shouldResetStateFromServer = false
|
||||||
strongSelf.stateValue.state = state
|
strongSelf.stateValue.state = state
|
||||||
strongSelf.endedProcessingUpdate()
|
strongSelf.endedProcessingUpdate()
|
||||||
}))
|
}))
|
||||||
@ -1189,6 +1274,49 @@ public final class GroupCallParticipantsContext {
|
|||||||
strongSelf.account.stateManager.addUpdates(updates)
|
strongSelf.account.stateManager.addUpdates(updates)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func loadMore(token: String) {
|
||||||
|
if token != self.stateValue.state.nextParticipantsFetchOffset {
|
||||||
|
Logger.shared.log("GroupCallParticipantsContext", "loadMore called with an invalid token \(token) (the valid one is \(String(describing: self.stateValue.state.nextParticipantsFetchOffset)))")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.isLoadingMore {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.isLoadingMore = true
|
||||||
|
|
||||||
|
self.disposable.set((getGroupCallParticipants(account: self.account, callId: self.id, accessHash: self.accessHash, offset: token, peerIds: [], limit: 100)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] state in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.isLoadingMore = false
|
||||||
|
|
||||||
|
var updatedState = strongSelf.stateValue.state
|
||||||
|
|
||||||
|
var existingParticipantIds = Set<PeerId>()
|
||||||
|
for participant in updatedState.participants {
|
||||||
|
existingParticipantIds.insert(participant.peer.id)
|
||||||
|
}
|
||||||
|
for participant in state.participants {
|
||||||
|
if existingParticipantIds.contains(participant.peer.id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
existingParticipantIds.insert(participant.peer.id)
|
||||||
|
updatedState.participants.append(participant)
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedState.nextParticipantsFetchOffset = state.nextParticipantsFetchOffset
|
||||||
|
updatedState.totalCount = max(updatedState.totalCount, state.totalCount)
|
||||||
|
updatedState.version = max(updatedState.version, updatedState.version)
|
||||||
|
|
||||||
|
strongSelf.stateValue.state = updatedState
|
||||||
|
|
||||||
|
if strongSelf.shouldResetStateFromServer {
|
||||||
|
strongSelf.resetStateFromServer()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
|
extension GroupCallParticipantsContext.Update.StateUpdate.ParticipantUpdate {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user