Voice-based ordering

This commit is contained in:
Ali 2020-12-01 18:40:14 +04:00
parent 9d4482ac1a
commit 92a9bc6e07
4 changed files with 192 additions and 60 deletions

View File

@ -51,7 +51,6 @@ BAZEL_OPTIONS=(\
--spawn_strategy=standalone \ --spawn_strategy=standalone \
--strategy=SwiftCompile=standalone \ --strategy=SwiftCompile=standalone \
--features=swift.enable_batch_mode \ --features=swift.enable_batch_mode \
--apple_generate_dsym \
--swiftcopt=-j${CORE_COUNT_MINUS_ONE} \ --swiftcopt=-j${CORE_COUNT_MINUS_ONE} \
) )

View File

@ -191,6 +191,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private let speakingParticipantsContext = SpeakingParticipantsContext() private let speakingParticipantsContext = SpeakingParticipantsContext()
private var speakingParticipantsReportTimestamp: [PeerId: Double] = [:]
private var participantsContextStateDisposable = MetaDisposable() private var participantsContextStateDisposable = MetaDisposable()
private var participantsContext: GroupCallParticipantsContext? private var participantsContext: GroupCallParticipantsContext?
@ -382,8 +383,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
removedSsrc.append(participantUpdate.ssrc) removedSsrc.append(participantUpdate.ssrc)
if participantUpdate.peerId == strongSelf.accountContext.account.peerId { if participantUpdate.peerId == strongSelf.accountContext.account.peerId {
if case let .estabilished(_, _, ssrc, _) = strongSelf.internalState, ssrc == participantUpdate.ssrc {
strongSelf._canBeRemoved.set(.single(true)) strongSelf._canBeRemoved.set(.single(true))
} }
}
} else if participantUpdate.peerId == strongSelf.accountContext.account.peerId { } else if participantUpdate.peerId == strongSelf.accountContext.account.peerId {
if case let .estabilished(_, _, ssrc, _) = strongSelf.internalState, ssrc != participantUpdate.ssrc { if case let .estabilished(_, _, ssrc, _) = strongSelf.internalState, ssrc != participantUpdate.ssrc {
strongSelf._canBeRemoved.set(.single(true)) strongSelf._canBeRemoved.set(.single(true))
@ -601,9 +604,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
) )
self.participantsContext = participantsContext self.participantsContext = participantsContext
self.participantsContextStateDisposable.set(combineLatest(queue: .mainQueue(), self.participantsContextStateDisposable.set(combineLatest(queue: .mainQueue(),
participantsContext.state, participantsContext.state |> beforeNext { state in
participantsContext.numberOfActiveSpeakers, print("before received members")
self.speakingParticipantsContext.get() for member in state.participants {
print(" \(member.peer.debugDisplayTitle) \(member.activityTimestamp ?? 0.0)")
}
},
participantsContext.numberOfActiveSpeakers |> deliverOnMainQueue,
self.speakingParticipantsContext.get() |> deliverOnMainQueue
).start(next: { [weak self] state, numberOfActiveSpeakers, speakingParticipants in ).start(next: { [weak self] state, numberOfActiveSpeakers, speakingParticipants in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
@ -611,6 +619,25 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
var topParticipants: [GroupCallParticipantsContext.Participant] = [] var topParticipants: [GroupCallParticipantsContext.Participant] = []
var reportSpeakingParticipants: [PeerId] = []
let timestamp = CACurrentMediaTime()
for peerId in speakingParticipants {
let shouldReport: Bool
if let previousTimestamp = strongSelf.speakingParticipantsReportTimestamp[peerId] {
shouldReport = previousTimestamp + 1.0 < timestamp
} else {
shouldReport = true
}
if shouldReport {
strongSelf.speakingParticipantsReportTimestamp[peerId] = timestamp
reportSpeakingParticipants.append(peerId)
}
}
if !reportSpeakingParticipants.isEmpty {
strongSelf.participantsContext?.reportSpeakingParticipants(ids: reportSpeakingParticipants)
}
var members = PresentationGroupCallMembers( var members = PresentationGroupCallMembers(
participants: [], participants: [],
speakingParticipants: speakingParticipants, speakingParticipants: speakingParticipants,
@ -640,6 +667,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
members.totalCount = state.totalCount members.totalCount = state.totalCount
members.loadMoreToken = state.nextParticipantsFetchOffset members.loadMoreToken = state.nextParticipantsFetchOffset
print("received members")
for member in members.participants {
print(" \(member.peer.debugDisplayTitle) \(member.activityTimestamp ?? 0.0)")
}
print("received state members")
for member in state.participants {
print(" \(member.peer.debugDisplayTitle) \(member.activityTimestamp ?? 0.0)")
}
strongSelf.membersValue = members strongSelf.membersValue = members
strongSelf.stateValue.adminIds = state.adminIds strongSelf.stateValue.adminIds = state.adminIds

View File

@ -493,6 +493,11 @@ public final class VoiceChatController: ViewController {
return return
} }
if let groupMembers = strongSelf.currentGroupMembers { if let groupMembers = strongSelf.currentGroupMembers {
print("update UI members")
for member in callMembers.participants {
print(" \(member.peer.debugDisplayTitle) \(member.activityTimestamp ?? 0.0)")
}
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, groupMembers: groupMembers, callMembers: callMembers.participants, speakingPeers: callMembers.speakingParticipants, invitedPeers: strongSelf.currentInvitedPeers ?? Set()) strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, groupMembers: groupMembers, callMembers: callMembers.participants, speakingPeers: callMembers.speakingParticipants, invitedPeers: strongSelf.currentInvitedPeers ?? Set())
} else { } else {
strongSelf.currentCallMembers = callMembers.participants strongSelf.currentCallMembers = callMembers.participants
@ -604,7 +609,7 @@ public final class VoiceChatController: ViewController {
return return
} }
var effectiveLevel: Float = 0.0 var effectiveLevel: Float = 0.0
if let state = strongSelf.callState, state.muteState == nil { if let state = strongSelf.callState, state.muteState == nil, !strongSelf.pushingToTalk {
effectiveLevel = level effectiveLevel = level
} }
strongSelf.itemInteraction?.updateAudioLevels([(strongSelf.context.account.peerId, effectiveLevel)]) strongSelf.itemInteraction?.updateAudioLevels([(strongSelf.context.account.peerId, effectiveLevel)])
@ -1226,18 +1231,20 @@ public final class VoiceChatController: ViewController {
return lhs.peer.id < rhs.peer.id return lhs.peer.id < rhs.peer.id
}) })
var callMembers = callMembers var sortedCallMembers = callMembers
callMembers.sort() sortedCallMembers.sort()
for i in 0 ..< callMembers.count { /*for i in 0 ..< sortedCallMembers.count {
if callMembers[i].peer.id == self.context.account.peerId { if sortedCallMembers[i].peer.id == self.context.account.peerId {
let member = callMembers[i] let member = sortedCallMembers[i]
callMembers.remove(at: i) sortedCallMembers.remove(at: i)
callMembers.insert(member, at: 0) sortedCallMembers.insert(member, at: 0)
break break
} }
} }*/
//assert(sortedCallMembers == callMembers)
self.currentGroupMembers = groupMembers self.currentGroupMembers = groupMembers
self.currentCallMembers = callMembers self.currentCallMembers = callMembers
@ -1251,12 +1258,15 @@ public final class VoiceChatController: ViewController {
var processedPeerIds = Set<PeerId>() var processedPeerIds = Set<PeerId>()
print("UI members")
for member in callMembers { for member in callMembers {
if processedPeerIds.contains(member.peer.id) { if processedPeerIds.contains(member.peer.id) {
continue continue
} }
processedPeerIds.insert(member.peer.id) processedPeerIds.insert(member.peer.id)
print(" \(member.peer.debugDisplayTitle) \(member.activityTimestamp ?? 0.0)")
let memberState: PeerEntry.State let memberState: PeerEntry.State
var memberMuteState: GroupCallParticipantsContext.Participant.MuteState? var memberMuteState: GroupCallParticipantsContext.Participant.MuteState?
if member.peer.id == self.context.account.peerId { if member.peer.id == self.context.account.peerId {

View File

@ -232,7 +232,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
peer: peer, peer: peer,
ssrc: ssrc, ssrc: ssrc,
joinTimestamp: date, joinTimestamp: date,
activityTimestamp: activeDate, activityTimestamp: activeDate.flatMap(Double.init),
muteState: muteState muteState: muteState
)) ))
} }
@ -494,7 +494,7 @@ public final class GroupCallParticipantsContext {
public var peer: Peer public var peer: Peer
public var ssrc: UInt32 public var ssrc: UInt32
public var joinTimestamp: Int32 public var joinTimestamp: Int32
public var activityTimestamp: Int32? public var activityTimestamp: Double?
public var muteState: MuteState? public var muteState: MuteState?
public static func ==(lhs: Participant, rhs: Participant) -> Bool { public static func ==(lhs: Participant, rhs: Participant) -> Bool {
@ -587,7 +587,7 @@ public final class GroupCallParticipantsContext {
public var peerId: PeerId public var peerId: PeerId
public var ssrc: UInt32 public var ssrc: UInt32
public var joinTimestamp: Int32 public var joinTimestamp: Int32
public var activityTimestamp: Int32? public var activityTimestamp: Double?
public var muteState: Participant.MuteState? public var muteState: Participant.MuteState?
public var isRemoved: Bool public var isRemoved: Bool
} }
@ -606,11 +606,22 @@ 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 stateValue: InternalState { private var stateValue: InternalState {
didSet { didSet {
if self.stateValue != oldValue {
if self.hasReceivedSpeackingParticipantsReport {
print("set stateValue")
for participant in self.stateValue.state.participants {
print(" \(participant.peer.debugDisplayTitle) \(participant.activityTimestamp ?? 0)")
}
}
self.statePromise.set(self.stateValue) self.statePromise.set(self.stateValue)
} }
} }
}
private let statePromise: ValuePromise<InternalState> private let statePromise: ValuePromise<InternalState>
public var state: Signal<State, NoError> { public var state: Signal<State, NoError> {
@ -682,6 +693,7 @@ public final class GroupCallParticipantsContext {
strongSelf.numberOfActiveSpeakersValue = activities.count strongSelf.numberOfActiveSpeakersValue = activities.count
if !strongSelf.hasReceivedSpeackingParticipantsReport {
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 {
@ -690,7 +702,9 @@ public final class GroupCallParticipantsContext {
var updated = false var updated = false
for (activityPeerId, activity) in activities { for (activityPeerId, activity) in activities {
if case let .speakingInGroupCall(timestamp) = activity { if case let .speakingInGroupCall(intTimestamp) = activity {
let timestamp = Double(intTimestamp)
if let index = indexMap[activityPeerId] { if let index = indexMap[activityPeerId] {
if let activityTimestamp = updatedParticipants[index].activityTimestamp { if let activityTimestamp = updatedParticipants[index].activityTimestamp {
if activityTimestamp < timestamp { if activityTimestamp < timestamp {
@ -729,6 +743,7 @@ public final class GroupCallParticipantsContext {
overlayState: strongSelf.stateValue.overlayState overlayState: strongSelf.stateValue.overlayState
) )
} }
}
}) })
} }
@ -755,6 +770,71 @@ public final class GroupCallParticipantsContext {
} }
} }
public func reportSpeakingParticipants(ids: [PeerId]) {
if !ids.isEmpty {
self.hasReceivedSpeackingParticipantsReport = true
}
let strongSelf = self
var updatedParticipants = strongSelf.stateValue.state.participants
var indexMap: [PeerId: Int] = [:]
for i in 0 ..< updatedParticipants.count {
indexMap[updatedParticipants[i].peer.id] = i
}
var updated = false
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
for activityPeerId in ids {
if let index = indexMap[activityPeerId] {
var updateTimestamp = false
if let activityTimestamp = updatedParticipants[index].activityTimestamp {
if activityTimestamp < timestamp {
updateTimestamp = true
}
} else {
updateTimestamp = true
}
if updateTimestamp {
updatedParticipants[index].activityTimestamp = timestamp
updated = true
print("update \(updatedParticipants[index].peer.debugDisplayTitle) to \(timestamp)")
}
}
}
if updated {
updatedParticipants.sort()
for i in 0 ..< updatedParticipants.count {
if updatedParticipants[i].peer.id == strongSelf.account.peerId {
let member = updatedParticipants[i]
updatedParticipants.remove(at: i)
updatedParticipants.insert(member, at: 0)
break
}
}
for participant in updatedParticipants {
print(" \(participant.peer.debugDisplayTitle) \(participant.activityTimestamp ?? 0)")
}
strongSelf.stateValue = InternalState(
state: State(
participants: updatedParticipants,
nextParticipantsFetchOffset: strongSelf.stateValue.state.nextParticipantsFetchOffset,
adminIds: strongSelf.stateValue.state.adminIds,
isCreator: strongSelf.stateValue.state.isCreator,
defaultParticipantsAreMuted: strongSelf.stateValue.state.defaultParticipantsAreMuted,
totalCount: strongSelf.stateValue.state.totalCount,
version: strongSelf.stateValue.state.version
),
overlayState: strongSelf.stateValue.overlayState
)
}
}
private func beginProcessingUpdatesIfNeeded() { private func beginProcessingUpdatesIfNeeded() {
if self.isProcessingUpdate { if self.isProcessingUpdate {
return return
@ -824,7 +904,7 @@ public final class GroupCallParticipantsContext {
assertionFailure() assertionFailure()
continue continue
} }
var previousActivityTimestamp: Int32? var previousActivityTimestamp: Double?
if let index = updatedParticipants.firstIndex(where: { $0.peer.id == participantUpdate.peerId }) { if let index = updatedParticipants.firstIndex(where: { $0.peer.id == participantUpdate.peerId }) {
previousActivityTimestamp = updatedParticipants[index].activityTimestamp previousActivityTimestamp = updatedParticipants[index].activityTimestamp
updatedParticipants.remove(at: index) updatedParticipants.remove(at: index)
@ -832,7 +912,7 @@ public final class GroupCallParticipantsContext {
updatedTotalCount += 1 updatedTotalCount += 1
} }
var activityTimestamp: Int32? var activityTimestamp: Double?
if let previousActivityTimestamp = previousActivityTimestamp, let updatedActivityTimestamp = participantUpdate.activityTimestamp { if let previousActivityTimestamp = previousActivityTimestamp, let updatedActivityTimestamp = participantUpdate.activityTimestamp {
activityTimestamp = max(updatedActivityTimestamp, previousActivityTimestamp) activityTimestamp = max(updatedActivityTimestamp, previousActivityTimestamp)
} else { } else {
@ -870,6 +950,13 @@ public final class GroupCallParticipantsContext {
} }
} }
if strongSelf.hasReceivedSpeackingParticipantsReport {
print("processUpdate participants")
for participant in updatedParticipants {
print(" \(participant.peer.debugDisplayTitle) \(participant.activityTimestamp ?? 0)")
}
}
strongSelf.stateValue = InternalState( strongSelf.stateValue = InternalState(
state: State( state: State(
participants: updatedParticipants, participants: updatedParticipants,
@ -1014,7 +1101,7 @@ extension GroupCallParticipantsContext.Update.StateUpdate {
peerId: peerId, peerId: peerId,
ssrc: ssrc, ssrc: ssrc,
joinTimestamp: date, joinTimestamp: date,
activityTimestamp: activeDate, activityTimestamp: activeDate.flatMap(Double.init),
muteState: muteState, muteState: muteState,
isRemoved: isRemoved isRemoved: isRemoved
)) ))