Video avatar fixes

This commit is contained in:
Ilya Laktyushin 2020-07-09 22:35:29 +03:00
parent 7487835711
commit b504bf8771
2 changed files with 90 additions and 25 deletions

View File

@ -312,7 +312,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|> take(1) |> take(1)
|> deliverOnMainQueue).start(completed: { [weak self] in |> deliverOnMainQueue).start(completed: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
Queue.mainQueue().after(0.03) { Queue.mainQueue().after(0.1) {
strongSelf.videoNode?.isHidden = false strongSelf.videoNode?.isHidden = false
} }
} }
@ -409,7 +409,12 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
self.contentNode.layer.animatePosition(from: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), to: self.contentNode.layer.position, duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in self.contentNode.layer.animatePosition(from: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), to: self.contentNode.layer.position, duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, completion: { _ in
completion() completion()
}) })
if let _ = self.videoNode {
self.contentNode.view.superview?.bringSubviewToFront(self.contentNode.view)
} else {
self.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.07) self.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.07)
}
transformedFrame.origin = CGPoint() transformedFrame.origin = CGPoint()
//self.imageNode.layer.animateBounds(from: transformedFrame, to: self.imageNode.layer.bounds, duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring) //self.imageNode.layer.animateBounds(from: transformedFrame, to: self.imageNode.layer.bounds, duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring)
@ -493,7 +498,6 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
intermediateCompletion() intermediateCompletion()
}) })
if let _ = self.videoNode { if let _ = self.videoNode {
self.contentNode.view.superview?.bringSubviewToFront(self.contentNode.view) self.contentNode.view.superview?.bringSubviewToFront(self.contentNode.view)
} else { } else {

View File

@ -288,7 +288,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|> take(1) |> take(1)
|> deliverOnMainQueue).start(completed: { [weak self] in |> deliverOnMainQueue).start(completed: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
Queue.mainQueue().after(0.03) { Queue.mainQueue().after(0.1) {
strongSelf.videoNode?.isHidden = false strongSelf.videoNode?.isHidden = false
} }
} }
@ -365,6 +365,15 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
private var transitionFraction: CGFloat = 0.0 private var transitionFraction: CGFloat = 0.0
private var validLayout: CGSize? private var validLayout: CGSize?
var isCollapsing = false {
didSet {
if oldValue != self.isCollapsing && !self.isCollapsing {
for (_, itemNode) in self.itemNodes {
itemNode.isExpanded = self.isExpanded
}
}
}
}
private var isExpanded = false private var isExpanded = false
private let disposable = MetaDisposable() private let disposable = MetaDisposable()
@ -816,8 +825,11 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
func update(size: CGSize, peer: Peer?, isExpanded: Bool, transition: ContainedViewLayoutTransition) { func update(size: CGSize, peer: Peer?, isExpanded: Bool, transition: ContainedViewLayoutTransition) {
self.validLayout = size self.validLayout = size
let previousExpanded = self.isExpanded
self.isExpanded = isExpanded self.isExpanded = isExpanded
if !isExpanded && previousExpanded {
self.isCollapsing = true
}
self.leftHighlightNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width * 1.0 / 5.0), height: size.height)) self.leftHighlightNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: floor(size.width * 1.0 / 5.0), height: size.height))
self.rightHighlightNode.frame = CGRect(origin: CGPoint(x: size.width - floor(size.width * 1.0 / 5.0), y: 0.0), size: CGSize(width: floor(size.width * 1.0 / 5.0), height: size.height)) self.rightHighlightNode.frame = CGRect(origin: CGPoint(x: size.width - floor(size.width * 1.0 / 5.0), y: 0.0), size: CGSize(width: floor(size.width * 1.0 / 5.0), height: size.height))
@ -884,14 +896,14 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
var wasAdded = false var wasAdded = false
if let current = self.itemNodes[self.items[i].id] { if let current = self.itemNodes[self.items[i].id] {
itemNode = current itemNode = current
itemNode.isExpanded = self.isExpanded itemNode.isExpanded = self.isExpanded || self.isCollapsing
if update { if update {
itemNode.setup(item: self.items[i], synchronous: synchronous && i == self.currentIndex) itemNode.setup(item: self.items[i], synchronous: synchronous && i == self.currentIndex)
} }
} else { } else {
wasAdded = true wasAdded = true
itemNode = PeerInfoAvatarListItemNode(context: self.context) itemNode = PeerInfoAvatarListItemNode(context: self.context)
itemNode.isExpanded = self.isExpanded itemNode.isExpanded = self.isExpanded || self.isCollapsing
itemNode.setup(item: self.items[i], synchronous: synchronous && i == self.currentIndex) itemNode.setup(item: self.items[i], synchronous: synchronous && i == self.currentIndex)
self.itemNodes[self.items[i].id] = itemNode self.itemNodes[self.items[i].id] = itemNode
self.contentNode.addSubnode(itemNode) self.contentNode.addSubnode(itemNode)
@ -1009,12 +1021,21 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
private var videoContent: NativeVideoContent? private var videoContent: NativeVideoContent?
private var videoStartTimestamp: Double? private var videoStartTimestamp: Double?
var canAttachVideo: Bool = true var isExpanded: Bool = false
var canAttachVideo: Bool = true {
didSet {
if oldValue != self.canAttachVideo {
self.videoNode?.canAttachContent = !self.isExpanded && self.canAttachVideo
}
}
}
var tapped: (() -> Void)? var tapped: (() -> Void)?
private var isFirstAvatarLoading = true private var isFirstAvatarLoading = true
private let playbackStatusDisposable = MetaDisposable()
init(context: AccountContext) { init(context: AccountContext) {
self.context = context self.context = context
let avatarFont = avatarPlaceholderFont(size: floor(100.0 * 16.0 / 37.0)) let avatarFont = avatarPlaceholderFont(size: floor(100.0 * 16.0 / 37.0))
@ -1028,6 +1049,10 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
self.avatarNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) self.avatarNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
} }
deinit {
self.playbackStatusDisposable.dispose()
}
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state { if case .ended = recognizer.state {
self.tapped?() self.tapped?()
@ -1083,11 +1108,35 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
let mediaManager = self.context.sharedContext.mediaManager let mediaManager = self.context.sharedContext.mediaManager
let videoNode = UniversalVideoNode(postbox: self.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .embedded) let videoNode = UniversalVideoNode(postbox: self.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .embedded)
videoNode.isUserInteractionEnabled = false videoNode.isUserInteractionEnabled = false
videoNode.ownsContentNodeUpdated = { [weak self] owns in videoNode.isHidden = true
if let startTimestamp = video.startTimestamp {
self.videoStartTimestamp = startTimestamp
self.playbackStatusDisposable.set((videoNode.status
|> map { status -> Bool in
if let status = status, case .playing = status.status {
return true
} else {
return false
}
}
|> filter { playing in
return playing
}
|> take(1)
|> deliverOnMainQueue).start(completed: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
strongSelf.videoNode?.isHidden = !owns Queue.mainQueue().after(0.1) {
strongSelf.videoNode?.isHidden = false
} }
} }
}))
} else {
self.videoStartTimestamp = nil
self.playbackStatusDisposable.set(nil)
videoNode.isHidden = false
}
self.videoContent = videoContent self.videoContent = videoContent
self.videoNode = videoNode self.videoNode = videoNode
@ -1112,14 +1161,15 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
videoNode.frame = self.avatarNode.frame videoNode.frame = self.avatarNode.frame
if isExpanded == videoNode.canAttachContent { if isExpanded == videoNode.canAttachContent {
self.isExpanded = isExpanded
let update = { let update = {
videoNode.canAttachContent = !isExpanded && self.canAttachVideo videoNode.canAttachContent = !self.isExpanded && self.canAttachVideo
if videoNode.canAttachContent { if videoNode.canAttachContent {
if let videoStartTimestamp = self.videoStartTimestamp { // if let videoStartTimestamp = self.videoStartTimestamp {
videoNode.seek(videoStartTimestamp) // videoNode.seek(videoStartTimestamp)
} else { // } else {
videoNode.seek(0.0) // videoNode.seek(0.0)
} // }
videoNode.play() videoNode.play()
} }
} }
@ -1206,22 +1256,26 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
} }
} }
} }
self.iconNode.isHidden = iconHidden
self.updatingAvatarOverlay.isHidden = overlayHidden
} else { } else {
if isEditing { if isEditing {
self.iconNode.isHidden = false iconHidden = false
} else { } else {
iconHidden = true iconHidden = true
overlayHidden = true overlayHidden = true
} }
self.statusNode.transitionToState(.none) Queue.mainQueue().after(0.1) { [weak self] in
self.currentRepresentation = nil self?.statusNode.transitionToState(.none)
self.imageNode.setSignal(.single(nil)) self?.currentRepresentation = nil
self?.imageNode.setSignal(.single(nil))
self?.iconNode.isHidden = iconHidden
self?.updatingAvatarOverlay.isHidden = overlayHidden
}
} }
self.iconNode.isHidden = iconHidden
if !overlayHidden && self.updatingAvatarOverlay.image == nil { if !overlayHidden && self.updatingAvatarOverlay.image == nil {
self.updatingAvatarOverlay.image = generateFilledCircleImage(diameter: avatarSize, color: UIColor(white: 0.0, alpha: 0.4), backgroundColor: nil) self.updatingAvatarOverlay.image = generateFilledCircleImage(diameter: avatarSize, color: UIColor(white: 0.0, alpha: 0.4), backgroundColor: nil)
} }
self.updatingAvatarOverlay.isHidden = overlayHidden
} else { } else {
self.statusNode.transitionToState(.none) self.statusNode.transitionToState(.none)
self.iconNode.isHidden = true self.iconNode.isHidden = true
@ -1241,7 +1295,7 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
var tapped: ((Bool) -> Void)? var tapped: ((Bool) -> Void)?
var canAttachVideo = true var canAttachVideo: Bool = true
init(context: AccountContext) { init(context: AccountContext) {
self.context = context self.context = context
@ -2564,7 +2618,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
strongSelf.avatarListNode.avatarContainerNode.canAttachVideo = true
strongSelf.avatarListNode.listContainerNode.isHidden = true strongSelf.avatarListNode.listContainerNode.isHidden = true
DispatchQueue.main.async {
strongSelf.avatarListNode.listContainerNode.isCollapsing = false
}
}) })
} }
@ -2647,6 +2705,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
} }
self.avatarListNode.listContainerNode.update(size: expandedAvatarListSize, peer: peer, isExpanded: self.isAvatarExpanded, transition: transition) self.avatarListNode.listContainerNode.update(size: expandedAvatarListSize, peer: peer, isExpanded: self.isAvatarExpanded, transition: transition)
if self.avatarListNode.listContainerNode.isCollapsing {
self.avatarListNode.avatarContainerNode.canAttachVideo = false
}
var panelWithAvatarHeight: CGFloat = (self.isSettings ? 40.0 : 112.0) + avatarSize var panelWithAvatarHeight: CGFloat = (self.isSettings ? 40.0 : 112.0) + avatarSize
if twoLineInfo { if twoLineInfo {