mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Video Chats Improvements
This commit is contained in:
@@ -678,7 +678,7 @@ final class CallListControllerNode: ASDisplayNode {
|
||||
self.emptyAnimationNode.alpha = alpha
|
||||
self.emptyAnimationNode.layer.animateAlpha(from: previousAlpha, to: alpha, duration: 0.2, completion: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
if !previousAlpha.isZero && alpha.isZero {
|
||||
if !previousAlpha.isZero && strongSelf.emptyAnimationNode.alpha.isZero {
|
||||
strongSelf.emptyAnimationNode.visibility = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +664,11 @@ public final class VoiceChatController: ViewController {
|
||||
if case .list = peerEntry.style {
|
||||
interaction.peerContextAction(peerEntry, node, nil)
|
||||
} else {
|
||||
interaction.pinPeer(peer.id, peerEntry.ssrc)
|
||||
if peerEntry.pinned {
|
||||
interaction.peerContextAction(peerEntry, node, nil)
|
||||
} else {
|
||||
interaction.pinPeer(peer.id, peerEntry.ssrc)
|
||||
}
|
||||
}
|
||||
}, contextAction: peerEntry.style == .list ? { node, gesture in
|
||||
interaction.peerContextAction(peerEntry, node, gesture)
|
||||
@@ -703,6 +707,7 @@ public final class VoiceChatController: ViewController {
|
||||
private let mainVideoClippingNode: ASDisplayNode
|
||||
private var mainVideoContainerNode: MainVideoContainerNode?
|
||||
private var mainParticipantNode: VoiceChatParticipantItemNode
|
||||
private var minimizeButton: HighlightTrackingButtonNode
|
||||
private let listNode: ListView
|
||||
private let tileListNode: ListView
|
||||
private let topPanelNode: ASDisplayNode
|
||||
@@ -869,7 +874,10 @@ public final class VoiceChatController: ViewController {
|
||||
}
|
||||
|
||||
self.mainParticipantNode = VoiceChatParticipantItemNode()
|
||||
self.minimizeButton = HighlightTrackingButtonNode()
|
||||
self.minimizeButton.alpha = 0.65
|
||||
|
||||
self.minimizeButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/Minimize"), color: .white), for: .normal)
|
||||
self.listNode = ListView()
|
||||
self.listNode.alpha = self.isScheduling ? 0.0 : 1.0
|
||||
self.listNode.isUserInteractionEnabled = !self.isScheduling
|
||||
@@ -1665,6 +1673,7 @@ public final class VoiceChatController: ViewController {
|
||||
self.contentContainer.addSubnode(self.mainVideoClippingNode)
|
||||
self.mainVideoClippingNode.addSubnode(mainVideoContainer)
|
||||
self.mainVideoClippingNode.addSubnode(self.mainParticipantNode)
|
||||
self.mainVideoClippingNode.addSubnode(self.minimizeButton)
|
||||
}
|
||||
self.contentContainer.addSubnode(self.listNode)
|
||||
self.contentContainer.addSubnode(self.topPanelNode)
|
||||
@@ -1677,6 +1686,8 @@ public final class VoiceChatController: ViewController {
|
||||
self.contentContainer.addSubnode(self.tileListNode)
|
||||
self.addSubnode(self.transitionContainerNode)
|
||||
|
||||
self.minimizeButton.addTarget(self, action: #selector(self.minimizePressed), forControlEvents: .touchUpInside)
|
||||
|
||||
let invitedPeers: Signal<[Peer], NoError> = self.call.invitedPeers
|
||||
|> mapToSignal { ids -> Signal<[Peer], NoError> in
|
||||
return context.account.postbox.transaction { transaction -> [Peer] in
|
||||
@@ -2162,6 +2173,18 @@ public final class VoiceChatController: ViewController {
|
||||
strongSelf.dismissScheduled()
|
||||
}
|
||||
}
|
||||
|
||||
self.minimizeButton.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.minimizeButton.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.minimizeButton.alpha = 0.26
|
||||
} else {
|
||||
strongSelf.minimizeButton.alpha = 0.65
|
||||
strongSelf.minimizeButton.layer.animateAlpha(from: 0.26, to: 0.65, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
@@ -2182,6 +2205,11 @@ public final class VoiceChatController: ViewController {
|
||||
self.updateAvatarDisposable.dispose()
|
||||
self.ignoreConnectingTimer?.invalidate()
|
||||
}
|
||||
|
||||
@objc private func minimizePressed() {
|
||||
self.displayMode = .fullscreen(controlsHidden: true)
|
||||
self.mainVideoContainerNode?.tapped?()
|
||||
}
|
||||
|
||||
private func openContextMenu(sourceNode: ASDisplayNode, gesture: ContextGesture?) {
|
||||
let canManageCall = !self.optionsButtonIsAvatar
|
||||
@@ -3285,27 +3313,25 @@ public final class VoiceChatController: ViewController {
|
||||
|
||||
let offset: CGFloat
|
||||
var mainParticipantNodeWidth = videoClippingFrame.width
|
||||
if case let .fullscreen(controlsHidden) = effectiveDisplayMode, !isLandscape {
|
||||
offset = controlsHidden ? 66.0 : 140.0
|
||||
mainParticipantNodeWidth -= 50.0
|
||||
} else {
|
||||
if case let .fullscreen(controlsHidden) = effectiveDisplayMode {
|
||||
if isLandscape {
|
||||
mainParticipantNodeWidth -= 50.0
|
||||
offset = 56.0 + 6.0 + layout.intrinsicInsets.bottom
|
||||
mainParticipantNodeWidth -= controlsHidden ? 66.0 : 140.0
|
||||
} else {
|
||||
offset = 56.0 + 6.0
|
||||
offset = controlsHidden ? 66.0 : 140.0
|
||||
mainParticipantNodeWidth -= 50.0
|
||||
}
|
||||
} else {
|
||||
offset = 56.0 + 6.0
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.mainParticipantNode, frame: CGRect(x: 0.0, y: videoClippingFrame.height - offset, width: mainParticipantNodeWidth, height: 56.0))
|
||||
|
||||
|
||||
if let entry = self.pinnedEntry, let interaction = self.itemInteraction {
|
||||
self.mainParticipantNode.isHidden = false
|
||||
let item = entry.item(context: self.context, presentationData: self.presentationData, interaction: interaction, transparent: true)
|
||||
let itemNode = self.mainParticipantNode
|
||||
item.updateNode(async: { $0() }, node: {
|
||||
return itemNode
|
||||
}, params: ListViewItemLayoutParams(width: mainParticipantNodeWidth, leftInset: 0.0, rightInset: 0.0, availableHeight: self.bounds.height), previousItem: nil, nextItem: nil, animation: .Crossfade, completion: { (layout, apply) in
|
||||
}, params: ListViewItemLayoutParams(width: mainParticipantNodeWidth, leftInset: 0.0, rightInset: 0.0, availableHeight: self.bounds.height), previousItem: nil, nextItem: nil, animation: .None, completion: { (layout, apply) in
|
||||
itemNode.contentSize = layout.contentSize
|
||||
itemNode.insets = layout.insets
|
||||
itemNode.isUserInteractionEnabled = false
|
||||
@@ -3316,6 +3342,9 @@ public final class VoiceChatController: ViewController {
|
||||
self.mainParticipantNode.isHidden = true
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.mainParticipantNode, frame: CGRect(x: 0.0, y: videoClippingFrame.height - offset, width: mainParticipantNodeWidth, height: 56.0))
|
||||
transition.updateFrame(node: self.minimizeButton, frame: CGRect(x: mainParticipantNodeWidth + 1.0, y: videoClippingFrame.height - offset + 7.0, width: 44.0, height: 44.0))
|
||||
|
||||
transition.updateFrame(node: self.mainVideoClippingNode, frame: videoClippingFrame)
|
||||
transition.updateFrame(node: mainVideoContainer, frame: videoContainerFrame, completion: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
|
||||
@@ -164,13 +164,17 @@ private let tileSize = CGSize(width: 84.0, height: 84.0)
|
||||
private let backgroundCornerRadius: CGFloat = 14.0
|
||||
private let avatarSize: CGFloat = 40.0
|
||||
|
||||
private let accentColor: UIColor = UIColor(rgb: 0x007aff)
|
||||
private let constructiveColor: UIColor = UIColor(rgb: 0x34c759)
|
||||
private let destructiveColor: UIColor = UIColor(rgb: 0xff3b30)
|
||||
|
||||
private let borderLineWidth: CGFloat = 2.0
|
||||
private let borderImage = generateImage(CGSize(width: tileSize.width, height: tileSize.height), rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
context.setLineWidth(borderLineWidth)
|
||||
context.setStrokeColor(UIColor(rgb: 0x007aff).cgColor)
|
||||
context.setStrokeColor(accentColor.cgColor)
|
||||
|
||||
context.addPath(UIBezierPath(roundedRect: bounds.insetBy(dx: (borderLineWidth - UIScreenPixel) / 2.0, dy: (borderLineWidth - UIScreenPixel) / 2.0), cornerRadius: backgroundCornerRadius - UIScreenPixel).cgPath)
|
||||
context.strokePath()
|
||||
@@ -841,6 +845,23 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
if item.transparent && item.style == .list {
|
||||
titleFont = Font.semibold(17.0)
|
||||
titleColor = UIColor(rgb: 0xffffff, alpha: 0.65)
|
||||
} else if case .tile = item.style {
|
||||
switch item.text {
|
||||
case let .text(_, textColor):
|
||||
switch textColor {
|
||||
case .generic:
|
||||
titleColor = item.presentationData.theme.list.itemPrimaryTextColor
|
||||
case .accent:
|
||||
titleColor = item.presentationData.theme.list.itemAccentColor
|
||||
case .constructive:
|
||||
titleColor = constructiveColor
|
||||
case .destructive:
|
||||
titleColor = destructiveColor
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
let currentBoldFont: UIFont = titleFont
|
||||
|
||||
@@ -862,14 +883,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
}
|
||||
titleAttributedString = string
|
||||
case .tile:
|
||||
let textColor: UIColor
|
||||
switch item.icon {
|
||||
case .wantsToSpeak:
|
||||
textColor = item.presentationData.theme.list.itemAccentColor
|
||||
default:
|
||||
textColor = titleColor
|
||||
}
|
||||
titleAttributedString = NSAttributedString(string: firstName, font: titleFont, textColor: textColor)
|
||||
titleAttributedString = NSAttributedString(string: firstName, font: titleFont, textColor: titleColor)
|
||||
}
|
||||
} else if let firstName = user.firstName, !firstName.isEmpty {
|
||||
titleAttributedString = NSAttributedString(string: firstName, font: currentBoldFont, textColor: titleColor)
|
||||
@@ -914,9 +928,9 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
textColorValue = item.presentationData.theme.list.itemAccentColor
|
||||
wavesColor = textColorValue
|
||||
case .constructive:
|
||||
textColorValue = UIColor(rgb: 0x34c759)
|
||||
textColorValue = constructiveColor
|
||||
case .destructive:
|
||||
textColorValue = UIColor(rgb: 0xff3b30)
|
||||
textColorValue = destructiveColor
|
||||
wavesColor = textColorValue
|
||||
}
|
||||
if item.transparent && item.style == .list {
|
||||
@@ -935,9 +949,9 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
case .accent:
|
||||
textColorValue = item.presentationData.theme.list.itemAccentColor
|
||||
case .constructive:
|
||||
textColorValue = UIColor(rgb: 0x34c759)
|
||||
textColorValue = constructiveColor
|
||||
case .destructive:
|
||||
textColorValue = UIColor(rgb: 0xff3b30)
|
||||
textColorValue = destructiveColor
|
||||
}
|
||||
expandedStatusAttributedString = NSAttributedString(string: text, font: statusFont, textColor: textColorValue)
|
||||
} else {
|
||||
@@ -1167,10 +1181,14 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
|
||||
if updatedTitle, let snapshotView = strongSelf.titleNode.view.snapshotContentTree() {
|
||||
strongSelf.titleNode.view.superview?.insertSubview(snapshotView, aboveSubview: strongSelf.titleNode.view)
|
||||
|
||||
if item.transparent {
|
||||
snapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -20.0), duration: 0.2, removeOnCompletion: false, additive: true)
|
||||
strongSelf.titleNode.layer.animatePosition(from: CGPoint(x: 0.0, y: 20.0), to: CGPoint(), duration: 0.2, additive: true)
|
||||
}
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
|
||||
strongSelf.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user