Video Chat Improvements

This commit is contained in:
Ilya Laktyushin 2021-05-23 16:12:43 +04:00
parent b64860e116
commit 6fc89c71a5
2 changed files with 69 additions and 17 deletions

View File

@ -747,6 +747,7 @@ public final class VoiceChatController: ViewController {
private var currentNormalButtonColor: UIColor?
private var currentActiveButtonColor: UIColor?
private var mainEntry: VoiceChatPeerEntry?
private var currentEntries: [ListEntry] = []
private var currentFullscreenEntries: [ListEntry] = []
@ -1840,7 +1841,7 @@ public final class VoiceChatController: ViewController {
} else if strongSelf.peerIdToEndpoint.count > 0 {
for entry in strongSelf.currentFullscreenEntries {
if case let .peer(peerEntry, _) = entry {
if let videoEndpointId = peerEntry.effectiveVideoEndpointId {
if let _ = peerEntry.effectiveVideoEndpointId {
maxLevelWithVideo = (peerEntry.peer.id, 0.0)
break
}
@ -4162,11 +4163,11 @@ public final class VoiceChatController: ViewController {
})
}
private func updateMembers() {
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? ([], nil), invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set())
private func updateMembers(maybeUpdateVideo: Bool = true) {
self.updateMembers(muteState: self.effectiveMuteState, callMembers: self.currentCallMembers ?? ([], nil), invitedPeers: self.currentInvitedPeers ?? [], speakingPeers: self.currentSpeakingPeers ?? Set(), maybeUpdateVideo: maybeUpdateVideo)
}
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: ([GroupCallParticipantsContext.Participant], String?), invitedPeers: [Peer], speakingPeers: Set<PeerId>, updatePinnedPeer: Bool = true) {
private func updateMembers(muteState: GroupCallParticipantsContext.Participant.MuteState?, callMembers: ([GroupCallParticipantsContext.Participant], String?), invitedPeers: [Peer], speakingPeers: Set<PeerId>, maybeUpdateVideo: Bool = true) {
var disableAnimation = false
if self.currentCallMembers?.1 != callMembers.1 {
disableAnimation = true
@ -4193,6 +4194,7 @@ public final class VoiceChatController: ViewController {
var entryByPeerId: [PeerId: VoiceChatPeerEntry] = [:]
var latestWideVideo: String? = nil
var mainEntry: VoiceChatPeerEntry?
for member in callMembers.0 {
if processedPeerIds.contains(member.peer.id) {
continue
@ -4270,7 +4272,7 @@ public final class VoiceChatController: ViewController {
isLandscape: self.isLandscape
)
if peerEntry.active {
self.mainStageNode.update(peerEntry: peerEntry, pinned: self.currentForcedSpeaker != nil)
mainEntry = peerEntry
}
entryByPeerId[peerEntry.peer.id] = peerEntry
@ -4392,6 +4394,19 @@ public final class VoiceChatController: ViewController {
return
}
let previousMainEntry = self.mainEntry
self.mainEntry = mainEntry
if let mainEntry = mainEntry {
self.mainStageNode.update(peerEntry: mainEntry, pinned: self.currentForcedSpeaker != nil)
if let previousMainEntry = previousMainEntry, maybeUpdateVideo {
if previousMainEntry.effectiveVideoEndpointId != mainEntry.effectiveVideoEndpointId {
self.updateMainVideo(waitForFullSize: true, entries: fullscreenEntries, force: true)
return
}
}
}
self.updateRequestedVideoChannels()
self.endpointToPeerId = endpointIdToPeerId
@ -4557,13 +4572,13 @@ public final class VoiceChatController: ViewController {
}
}
private func updateMainVideo(waitForFullSize: Bool, updateMembers: Bool = true, force: Bool = false, completion: (() -> Void)? = nil) {
private func updateMainVideo(waitForFullSize: Bool, entries: [ListEntry]? = nil, updateMembers: Bool = true, force: Bool = false, completion: (() -> Void)? = nil) {
let effectiveMainSpeaker = self.currentForcedSpeaker ?? self.currentDominantSpeaker.flatMap { ($0.0, $0.1) }
guard effectiveMainSpeaker?.0 != self.effectiveSpeaker?.0 || effectiveMainSpeaker?.1 != self.effectiveSpeaker?.1 || force else {
return
}
let currentEntries = self.currentFullscreenEntries
let currentEntries = entries ?? self.currentFullscreenEntries
var effectiveSpeaker: (PeerId, String?)? = nil
var anySpeakerWithVideo: (PeerId, String?)? = nil
var anySpeaker: PeerId? = nil
@ -4600,7 +4615,7 @@ public final class VoiceChatController: ViewController {
self.effectiveSpeaker = effectiveSpeaker
if updateMembers {
self.updateMembers()
self.updateMembers(maybeUpdateVideo: false)
}
self.mainStageNode.update(peer: effectiveSpeaker, waitForFullSize: waitForFullSize, completion: {
completion?()

View File

@ -284,10 +284,13 @@ final class VoiceChatMainStageNode: ASDisplayNode {
}
private var animatingIn = false
private var animatingOut = false
private var appeared = false
func animateTransitionIn(from sourceNode: ASDisplayNode, transition: ContainedViewLayoutTransition) {
guard let sourceNode = sourceNode as? VoiceChatTileItemNode, let _ = sourceNode.item, let (_, sideInset, bottomInset, isLandscape) = self.validLayout else {
return
}
self.appeared = true
let alphaTransition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
alphaTransition.updateAlpha(node: self.backgroundNode, alpha: 1.0)
@ -327,6 +330,8 @@ final class VoiceChatMainStageNode: ASDisplayNode {
return
}
self.appeared = false
let alphaTransition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
alphaTransition.updateAlpha(node: self.backgroundNode, alpha: 0.0)
alphaTransition.updateAlpha(node: self.topFadeNode, alpha: 0.0)
@ -543,14 +548,13 @@ final class VoiceChatMainStageNode: ASDisplayNode {
self.audioLevelNode.startAnimating(immediately: true)
if let getAudioLevel = self.getAudioLevel, previousPeerEntry?.peer.id != peerEntry.peer.id {
self.audioLevelNode.isHidden = self.currentPeer?.1 != nil
self.audioLevelDisposable.set((getAudioLevel(peerEntry.peer.id)
|> deliverOnMainQueue).start(next: { [weak self] value in
guard let strongSelf = self else {
return
}
strongSelf.audioLevelNode.isHidden = strongSelf.currentPeer?.1 != nil
let level = min(1.5, max(0.0, CGFloat(value)))
strongSelf.audioLevelNode.updateLevel(CGFloat(value))
@ -590,7 +594,14 @@ final class VoiceChatMainStageNode: ASDisplayNode {
if let (_, endpointId) = peer {
if endpointId != previousPeer?.1 {
if let endpointId = endpointId {
self.setAvatarHidden(true)
var delayTransition = false
if previousPeer?.0 == peer?.0 && self.appeared {
delayTransition = true
}
if !delayTransition {
self.setAvatarHidden(true)
}
self.call.makeIncomingVideoView(endpointId: endpointId, completion: { [weak self] videoView in
Queue.mainQueue().async {
@ -630,6 +641,9 @@ final class VoiceChatMainStageNode: ASDisplayNode {
strongSelf.currentVideoNode = videoNode
strongSelf.insertSubnode(videoNode, aboveSubnode: strongSelf.backgroundNode)
if delayTransition {
videoNode.alpha = 0.0
}
if waitForFullSize {
strongSelf.videoReadyDisposable.set((videoNode.ready
|> filter { $0 }
@ -643,8 +657,23 @@ final class VoiceChatMainStageNode: ASDisplayNode {
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: isLandscape, transition: .immediate)
}
}
if let previousVideoNode = previousVideoNode {
previousVideoNode.removeFromSupernode()
if delayTransition {
if let videoNode = strongSelf.currentVideoNode {
videoNode.alpha = 1.0
videoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, completion: { [weak self] _ in
if let strongSelf = self {
strongSelf.setAvatarHidden(true)
if let previousVideoNode = previousVideoNode {
previousVideoNode.removeFromSupernode()
}
}
})
}
} else {
if let previousVideoNode = previousVideoNode {
previousVideoNode.removeFromSupernode()
}
}
}
}))
@ -664,9 +693,17 @@ final class VoiceChatMainStageNode: ASDisplayNode {
})
} else {
self.setAvatarHidden(false)
if let currentVideoNode = self.currentVideoNode {
currentVideoNode.removeFromSupernode()
self.currentVideoNode = nil
if self.appeared {
if let currentVideoNode = self.currentVideoNode {
currentVideoNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak currentVideoNode] _ in
currentVideoNode?.removeFromSupernode()
})
}
} else {
if let currentVideoNode = self.currentVideoNode {
currentVideoNode.removeFromSupernode()
self.currentVideoNode = nil
}
}
}
} else {