Video Chat Improvements

This commit is contained in:
Ilya Laktyushin 2021-05-19 17:34:22 +04:00
parent 58ff9f0de6
commit 50bb3432ec
7 changed files with 49 additions and 40 deletions

View File

@ -3128,7 +3128,7 @@ public final class VoiceChatController: ViewController {
if !self.mainStageNode.animating {
transition.updateFrame(node: self.mainStageNode, frame: CGRect(origin: CGPoint(), size: videoFrame.size))
}
self.mainStageNode.update(size: videoFrame.size, bottomInset: bottomInset, isLandscape: true, transition: transition)
self.mainStageNode.update(size: videoFrame.size, sideInset: layout.safeInsets.left, bottomInset: bottomInset, isLandscape: true, transition: transition)
let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: size.width, height: layout.size.height))
@ -5414,7 +5414,7 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
private let titleNode: ImmediateTextNode
private let microphoneNode: VoiceChatMicrophoneNode
private var validLayout: (CGSize, CGFloat, Bool)?
private var validLayout: (CGSize, CGFloat, CGFloat, Bool)?
var tapped: (() -> Void)?
var back: (() -> Void)?
@ -5571,7 +5571,7 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
var animating = false
fileprivate func animateTransitionIn(from sourceNode: ASDisplayNode, transition: ContainedViewLayoutTransition) {
guard let sourceNode = sourceNode as? VoiceChatTileItemNode, let _ = sourceNode.item, let (_, bottomInset, _) = self.validLayout else {
guard let sourceNode = sourceNode as? VoiceChatTileItemNode, let _ = sourceNode.item, let (_, sideInset, bottomInset, _) = self.validLayout else {
return
}
@ -5583,21 +5583,21 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
alphaTransition.updateAlpha(node: self.microphoneNode, alpha: 1.0)
alphaTransition.updateAlpha(node: self.headerNode, alpha: 1.0)
sourceNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1)
sourceNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
self.animating = true
let targetFrame = self.frame
let startLocalFrame = sourceNode.view.convert(sourceNode.bounds, to: self.supernode?.view)
self.update(size: startLocalFrame.size, bottomInset: bottomInset, isLandscape: true, force: true, transition: .immediate)
self.update(size: startLocalFrame.size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: true, force: true, transition: .immediate)
self.frame = startLocalFrame
self.update(size: targetFrame.size, bottomInset: bottomInset, isLandscape: true, force: true, transition: transition)
self.update(size: targetFrame.size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: true, force: true, transition: transition)
transition.updateFrame(node: self, frame: targetFrame, completion: { [weak self] _ in
self?.animating = false
})
}
fileprivate func animateTransitionOut(to targetNode: ASDisplayNode?, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
guard let (_, bottomInset, _) = self.validLayout else {
guard let (_, sideInset, bottomInset, _) = self.validLayout else {
return
}
@ -5620,14 +5620,14 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
self.animating = true
let initialFrame = self.frame
let targetFrame = targetNode.view.convert(targetNode.bounds, to: self.supernode?.view)
self.update(size: targetFrame.size, bottomInset: bottomInset, isLandscape: true, force: true, transition: transition)
self.update(size: targetFrame.size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: true, force: true, transition: transition)
transition.updateFrame(node: self, frame: targetFrame, completion: { [weak self] _ in
if let strongSelf = self {
completion()
strongSelf.animating = false
strongSelf.frame = initialFrame
strongSelf.update(size: initialFrame.size, bottomInset: bottomInset, isLandscape: true, transition: .immediate)
strongSelf.update(size: initialFrame.size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: true, transition: .immediate)
}
})
}
@ -5651,8 +5651,8 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
previousAvatarNode.removeFromSupernode()
}
self.titleNode.attributedText = NSAttributedString(string: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), font: Font.semibold(15.0), textColor: .white)
if let (size, bottomInset, isLandscape) = self.validLayout {
self.update(size: size, bottomInset: bottomInset, isLandscape: isLandscape, transition: .immediate)
if let (size, sideInset, bottomInset, isLandscape) = self.validLayout {
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: isLandscape, transition: .immediate)
}
}
@ -5774,8 +5774,8 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
}
strongSelf.currentVideoNode = videoNode
strongSelf.insertSubnode(videoNode, aboveSubnode: strongSelf.backgroundNode)
if let (size, bottomInset, isLandscape) = strongSelf.validLayout {
strongSelf.update(size: size, bottomInset: bottomInset, isLandscape: isLandscape, transition: .immediate)
if let (size, sideInset, bottomInset, isLandscape) = strongSelf.validLayout {
strongSelf.update(size: size, sideInset: sideInset, bottomInset: bottomInset, isLandscape: isLandscape, transition: .immediate)
}
if waitForFullSize {
@ -5815,13 +5815,18 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
}
}
func update(size: CGSize, bottomInset: CGFloat, isLandscape: Bool, force: Bool = false, transition: ContainedViewLayoutTransition) {
self.validLayout = (size, bottomInset, isLandscape)
func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, isLandscape: Bool, force: Bool = false, transition: ContainedViewLayoutTransition) {
self.validLayout = (size, sideInset, bottomInset, isLandscape)
if self.animating && !force {
return
}
var bottomInset = bottomInset
if !sideInset.isZero {
bottomInset = 30.0
}
if let currentVideoNode = self.currentVideoNode {
transition.updateFrame(node: currentVideoNode, frame: CGRect(origin: CGPoint(), size: size))
currentVideoNode.updateLayout(size: size, isLandscape: isLandscape, transition: transition)
@ -5838,9 +5843,9 @@ final class VoiceChatMainStageContainerNode: ASDisplayNode {
let animationSize = CGSize(width: 36.0, height: 36.0)
let titleSize = self.titleNode.updateLayout(size)
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: 12.0 + animationSize.width, y: size.height - bottomInset - titleSize.height - 16.0), size: titleSize))
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: sideInset + 12.0 + animationSize.width, y: size.height - bottomInset - titleSize.height - 16.0), size: titleSize))
transition.updateFrame(node: self.microphoneNode, frame: CGRect(origin: CGPoint(x: 7.0, y: size.height - bottomInset - animationSize.height - 6.0), size: animationSize))
transition.updateFrame(node: self.microphoneNode, frame: CGRect(origin: CGPoint(x: sideInset + 7.0, y: size.height - bottomInset - animationSize.height - 6.0), size: animationSize))
var fadeHeight: CGFloat = 50.0
if size.width < size.height {

View File

@ -711,6 +711,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode {
let profileNode = VoiceChatPeerProfileNode(context: item.context, size: extractedRect.size, peer: item.peer, text: item.text, customNode: self.videoContainerNode, additionalEntry: .single(nil), requestDismiss: { [weak self] in
self?.contextSourceNode.requestDismiss?()
})
profileNode.frame = CGRect(origin: CGPoint(), size: extractedRect.size)
self.profileNode = profileNode
self.contextSourceNode.contentNode.addSubnode(profileNode)
@ -740,7 +741,7 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode {
let hasVideo = self.videoNode != nil
return { item, params, first, last in
let titleFont = Font.semibold(12.0)
let titleFont = Font.semibold(13.0)
var titleAttributedString: NSAttributedString?
var titleColor = item.presentationData.theme.list.itemPrimaryTextColor
@ -843,28 +844,15 @@ class VoiceChatFullscreenParticipantItemNode: ItemListRevealOptionsItemNode {
animationSize = CGSize(width: 36.0, height: 36.0)
animationScale = 0.66667
animationFrame = CGRect(x: layout.size.width - 29.0, y: 54.0, width: 24.0, height: 24.0)
animationFrame = CGRect(x: layout.size.width - 29.0, y: 55.0, width: 24.0, height: 24.0)
titleFrame = CGRect(origin: CGPoint(x: 8.0, y: 63.0), size: titleLayout.size)
var extractedRect = CGRect(origin: CGPoint(), size: layout.contentSize).insetBy(dx: 16.0 + params.leftInset, dy: 0.0)
var extractedHeight = extractedRect.height
var extractedVerticalOffset: CGFloat = 0.0
if item.peer.smallProfileImage != nil || strongSelf.videoNode != nil {
extractedVerticalOffset = extractedRect.width
extractedHeight += extractedVerticalOffset
}
extractedRect.size.height = extractedHeight
strongSelf.extractedVerticalOffset = extractedVerticalOffset
let extractedWidth = availableWidth
let extractedRect = CGRect(x: 0.0, y: 0.0, width: extractedWidth, height: extractedWidth + statusLayout.height + 39.0)
strongSelf.extractedRect = extractedRect
strongSelf.nonExtractedRect = nonExtractedRect
if strongSelf.isExtracted {
var extractedRect = extractedRect
if !extractedVerticalOffset.isZero {
extractedRect = CGRect(x: extractedRect.minX, y: extractedRect.minY + extractedVerticalOffset, width: extractedRect.width, height: extractedRect.height - extractedVerticalOffset)
}
strongSelf.backgroundImageNode.frame = extractedRect
} else {
strongSelf.backgroundImageNode.frame = nonExtractedRect

View File

@ -660,7 +660,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
var duration: Double = 0.2
var timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue
if case let .animated(transitionDuration, curve) = transition {
duration = transitionDuration
duration = transitionDuration + 0.08
timingFunction = curve.timingFunction
}
@ -690,6 +690,10 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
sourceNode.backgroundImageNode.layer.animatePosition(from: startContainerBackgroundPosition, to: targetContainerAvatarPosition, duration: duration, timingFunction: timingFunction, completion: { [weak sourceNode] _ in
if let sourceNode = sourceNode {
Queue.mainQueue().after(0.1, {
sourceNode.backgroundImageNode.layer.removeAllAnimations()
sourceNode.contentWrapperNode.layer.removeAllAnimations()
})
sourceNode.backgroundImageNode.alpha = 1.0
sourceNode.borderImageNode.alpha = 1.0
sourceNode.backgroundImageNode.position = initialBackgroundPosition
@ -717,9 +721,9 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
})
sourceNode.backgroundImageNode.layer.animateScale(from: 1.0, to: 0.001, duration: duration, timingFunction: timingFunction)
sourceNode.backgroundImageNode.layer.animateAlpha(from: sourceNode.backgroundImageNode.alpha, to: 0.0, duration: duration, timingFunction: timingFunction)
sourceNode.backgroundImageNode.layer.animateAlpha(from: sourceNode.backgroundImageNode.alpha, to: 0.0, duration: duration, timingFunction: timingFunction, removeOnCompletion: false)
sourceNode.contentWrapperNode.layer.animateScale(from: 1.0, to: 0.001, duration: duration, timingFunction: timingFunction)
sourceNode.contentWrapperNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: timingFunction)
sourceNode.contentWrapperNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: timingFunction, removeOnCompletion: false)
}
}

View File

@ -335,7 +335,7 @@ final class VoiceChatPeerProfileNode: ASDisplayNode {
self.infoNode.alpha = 0.0
self.infoNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
} else if let targetNode = targetNode as? VoiceChatFullscreenParticipantItemNode {
self.removeFromSupernode()
}
}
}

View File

@ -384,7 +384,7 @@ final class VoiceChatTileItemNode: ASDisplayNode {
var duration: Double = 0.2
var timingFunction: String = CAMediaTimingFunctionName.easeInEaseOut.rawValue
if case let .animated(transitionDuration, curve) = transition {
duration = transitionDuration
duration = transitionDuration + 0.05
timingFunction = curve.timingFunction
}
@ -411,7 +411,7 @@ final class VoiceChatTileItemNode: ASDisplayNode {
}
sourceNode.isHidden = true
Queue.mainQueue().after(0.25) {
Queue.mainQueue().after(0.4) {
sourceNode.isHidden = false
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "ic_sharescreen.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}