Video Chats Improvements

This commit is contained in:
Ilya Laktyushin
2021-04-23 20:45:30 +04:00
parent a57ab2d9aa
commit 5b5e3f22de
3 changed files with 73 additions and 26 deletions

View File

@@ -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
}
}

View File

@@ -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 {

View File

@@ -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)
}