mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-01 12:17:53 +00:00
Video Chat Improvements
This commit is contained in:
parent
58ff9f0de6
commit
50bb3432ec
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
12
submodules/TelegramUI/Images.xcassets/Call/ShareScreen.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Call/ShareScreen.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_sharescreen.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Call/ShareScreen.imageset/ic_sharescreen.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/ShareScreen.imageset/ic_sharescreen.pdf
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user