mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Voice-based ordering
This commit is contained in:
parent
9d4482ac1a
commit
92a9bc6e07
@ -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} \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
))
|
))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user