mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-02 00:17:02 +00:00
Video avatar fixes
This commit is contained in:
parent
118422e26c
commit
65c6e51e2c
@ -437,7 +437,8 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
})
|
})
|
||||||
} else if case let .roundRect(cornerRadius) = self.sourceCorners {
|
} else if case let .roundRect(cornerRadius) = self.sourceCorners {
|
||||||
let scale = scaledLocalImageViewBounds.width / transformedCopyViewFinalFrame.width
|
let scale = scaledLocalImageViewBounds.width / transformedCopyViewFinalFrame.width
|
||||||
self.contentNode.layer.animate(from: (cornerRadius * scale) as NSNumber, to: 0.0 as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18, removeOnCompletion: false, completion: { [weak self] value in
|
let selfScale = transformedCopyViewFinalFrame.width / transformedSelfFrame.width
|
||||||
|
self.contentNode.layer.animate(from: (cornerRadius * scale * selfScale) as NSNumber, to: 0.0 as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18, removeOnCompletion: false, completion: { [weak self] value in
|
||||||
if value {
|
if value {
|
||||||
self?.contentNode.clipsToBounds = false
|
self?.contentNode.clipsToBounds = false
|
||||||
}
|
}
|
||||||
@ -466,13 +467,19 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
|
|
||||||
let copyView = maybeCopyView!
|
let copyView = maybeCopyView!
|
||||||
|
|
||||||
if case .round = self.sourceCorners {
|
var sourceHasRoundCorners = false
|
||||||
|
if case .none = self.sourceCorners {
|
||||||
|
} else {
|
||||||
|
sourceHasRoundCorners = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if sourceHasRoundCorners {
|
||||||
self.view.insertSubview(copyView, belowSubview: self.scrollNode.view)
|
self.view.insertSubview(copyView, belowSubview: self.scrollNode.view)
|
||||||
}
|
}
|
||||||
copyView.frame = transformedSelfFrame
|
copyView.frame = transformedSelfFrame
|
||||||
|
|
||||||
let surfaceCopyView = node.2().0!
|
let surfaceCopyView = node.2().0!
|
||||||
if case .none = self.sourceCorners {
|
if !sourceHasRoundCorners {
|
||||||
addToTransitionSurface(surfaceCopyView)
|
addToTransitionSurface(surfaceCopyView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +546,8 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
self.contentNode.layer.animate(from: 0.0 as NSNumber, to: (self.contentNode.frame.width / 2.0) as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18 * durationFactor, removeOnCompletion: false)
|
self.contentNode.layer.animate(from: 0.0 as NSNumber, to: (self.contentNode.frame.width / 2.0) as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18 * durationFactor, removeOnCompletion: false)
|
||||||
} else if case let .roundRect(cornerRadius) = self.sourceCorners {
|
} else if case let .roundRect(cornerRadius) = self.sourceCorners {
|
||||||
let scale = scaledLocalImageViewBounds.width / transformedCopyViewInitialFrame.width
|
let scale = scaledLocalImageViewBounds.width / transformedCopyViewInitialFrame.width
|
||||||
self.contentNode.layer.animate(from: 0.0 as NSNumber, to: (cornerRadius * scale) as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18 * durationFactor, removeOnCompletion: false)
|
let selfScale = transformedCopyViewInitialFrame.width / transformedSelfFrame.width
|
||||||
|
self.contentNode.layer.animate(from: 0.0 as NSNumber, to: (cornerRadius * scale * selfScale) as NSNumber, keyPath: "cornerRadius", timingFunction: CAMediaTimingFunctionName.default.rawValue, duration: 0.18 * durationFactor, removeOnCompletion: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
self.statusNodeContainer.layer.animatePosition(from: self.statusNodeContainer.position, to: CGPoint(x: transformedSuperFrame.midX, y: transformedSuperFrame.midY), duration: 0.25, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
|
||||||
|
@ -263,11 +263,12 @@ public func updatePeerPhotoInternal(postbox: Postbox, network: Network, stateMan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> mapToSignal { result, resource, videoResource -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
|> mapToSignal { result, resource, videoResource -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
||||||
if case .complete = result, let videoResource = videoResource {
|
if case .complete = result {
|
||||||
return fetchAndUpdateCachedPeerData(accountPeerId: accountPeerId, peerId: peer.id, network: network, postbox: postbox)
|
return fetchAndUpdateCachedPeerData(accountPeerId: accountPeerId, peerId: peer.id, network: network, postbox: postbox)
|
||||||
|> castError(UploadPeerPhotoError.self)
|
|> castError(UploadPeerPhotoError.self)
|
||||||
|> mapToSignal { status -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
|> mapToSignal { status -> Signal<UpdatePeerPhotoStatus, UploadPeerPhotoError> in
|
||||||
return postbox.transaction { transaction in
|
return postbox.transaction { transaction in
|
||||||
|
if let videoResource = videoResource {
|
||||||
let cachedData = transaction.getPeerCachedData(peerId: peer.id)
|
let cachedData = transaction.getPeerCachedData(peerId: peer.id)
|
||||||
if let cachedData = cachedData as? CachedChannelData {
|
if let cachedData = cachedData as? CachedChannelData {
|
||||||
if let photo = cachedData.photo {
|
if let photo = cachedData.photo {
|
||||||
@ -282,6 +283,7 @@ public func updatePeerPhotoInternal(postbox: Postbox, network: Network, stateMan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|> castError(UploadPeerPhotoError.self)
|
|> castError(UploadPeerPhotoError.self)
|
||||||
|
@ -1237,7 +1237,6 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.imageNode)
|
self.addSubnode(self.imageNode)
|
||||||
self.addSubnode(self.updatingAvatarOverlay)
|
self.addSubnode(self.updatingAvatarOverlay)
|
||||||
self.addSubnode(self.statusNode)
|
self.addSubnode(self.statusNode)
|
||||||
self.addSubnode(self.iconNode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTransitionFraction(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
func updateTransitionFraction(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
@ -1255,11 +1254,9 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|||||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .linear)
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .linear)
|
||||||
|
|
||||||
if canEditPeerInfo(context: self.context, peer: peer) {
|
if canEditPeerInfo(context: self.context, peer: peer) {
|
||||||
var overlayHidden = false
|
var overlayHidden = true
|
||||||
var iconHidden = false
|
|
||||||
if let updatingAvatar = updatingAvatar {
|
if let updatingAvatar = updatingAvatar {
|
||||||
overlayHidden = false
|
overlayHidden = false
|
||||||
iconHidden = true
|
|
||||||
|
|
||||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true))
|
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true))
|
||||||
|
|
||||||
@ -1272,38 +1269,21 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateAlpha(node: self.iconNode, alpha: iconHidden ? 0.0 : 1.0)
|
|
||||||
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: overlayHidden ? 0.0 : 1.0)
|
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: overlayHidden ? 0.0 : 1.0)
|
||||||
} else {
|
} else {
|
||||||
var immediately = self.currentRepresentation == nil
|
|
||||||
if isEditing {
|
|
||||||
immediately = immediately || peer.profileImageRepresentations.isEmpty
|
|
||||||
iconHidden = peer.profileImageRepresentations.isEmpty
|
|
||||||
overlayHidden = peer.profileImageRepresentations.isEmpty
|
|
||||||
} else {
|
|
||||||
iconHidden = true
|
|
||||||
overlayHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let targetIconAlpha: CGFloat = iconHidden ? 0.0 : 1.0
|
|
||||||
let targetOverlayAlpha: CGFloat = overlayHidden ? 0.0 : 1.0
|
let targetOverlayAlpha: CGFloat = overlayHidden ? 0.0 : 1.0
|
||||||
if self.updatingAvatarOverlay.alpha != targetOverlayAlpha || self.iconNode.alpha != targetIconAlpha {
|
if self.updatingAvatarOverlay.alpha != targetOverlayAlpha {
|
||||||
let update = {
|
let update = {
|
||||||
self.statusNode.transitionToState(.none)
|
self.statusNode.transitionToState(.none)
|
||||||
self.currentRepresentation = nil
|
self.currentRepresentation = nil
|
||||||
self.imageNode.setSignal(.single(nil))
|
self.imageNode.setSignal(.single(nil))
|
||||||
transition.updateAlpha(node: self.iconNode, alpha: iconHidden ? 0.0 : 1.0)
|
|
||||||
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: overlayHidden ? 0.0 : 1.0)
|
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: overlayHidden ? 0.0 : 1.0)
|
||||||
}
|
}
|
||||||
if immediately {
|
|
||||||
update()
|
|
||||||
} else {
|
|
||||||
Queue.mainQueue().after(0.3) {
|
Queue.mainQueue().after(0.3) {
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@ -2121,6 +2101,8 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
|
|||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let requestUpdateLayout: () -> Void
|
private let requestUpdateLayout: () -> Void
|
||||||
|
|
||||||
|
var requestEditing: (() -> Void)?
|
||||||
|
|
||||||
let avatarNode: PeerInfoEditingAvatarNode
|
let avatarNode: PeerInfoEditingAvatarNode
|
||||||
let avatarTextNode: ImmediateTextNode
|
let avatarTextNode: ImmediateTextNode
|
||||||
let avatarButtonNode: HighlightableButtonNode
|
let avatarButtonNode: HighlightableButtonNode
|
||||||
@ -2145,7 +2127,7 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func textPressed() {
|
@objc private func textPressed() {
|
||||||
self.avatarNode.tapped?(true)
|
self.requestEditing?()
|
||||||
}
|
}
|
||||||
|
|
||||||
func editingTextForKey(_ key: PeerInfoHeaderTextFieldNodeKey) -> String? {
|
func editingTextForKey(_ key: PeerInfoHeaderTextFieldNodeKey) -> String? {
|
||||||
@ -2414,10 +2396,13 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.separatorNode)
|
self.addSubnode(self.separatorNode)
|
||||||
|
|
||||||
self.avatarListNode.avatarContainerNode.tapped = { [weak self] in
|
self.avatarListNode.avatarContainerNode.tapped = { [weak self] in
|
||||||
self?.initiateAvatarExpansion()
|
self?.initiateAvatarExpansion(gallery: false)
|
||||||
}
|
}
|
||||||
self.editingContentNode.avatarNode.tapped = { [weak self] confirm in
|
self.editingContentNode.avatarNode.tapped = { [weak self] confirm in
|
||||||
self?.requestOpenAvatarForEditing?(confirm)
|
self?.initiateAvatarExpansion(gallery: true)
|
||||||
|
}
|
||||||
|
self.editingContentNode.requestEditing = { [weak self] in
|
||||||
|
self?.requestOpenAvatarForEditing?(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.avatarListNode.itemsUpdated = { [weak self] items in
|
self.avatarListNode.itemsUpdated = { [weak self] items in
|
||||||
@ -2450,8 +2435,8 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initiateAvatarExpansion() {
|
func initiateAvatarExpansion(gallery: Bool) {
|
||||||
if self.isAvatarExpanded {
|
if self.isAvatarExpanded || gallery {
|
||||||
if let currentEntry = self.avatarListNode.listContainerNode.currentEntry {
|
if let currentEntry = self.avatarListNode.listContainerNode.currentEntry {
|
||||||
self.requestAvatarExpansion?(true, self.avatarListNode.listContainerNode.galleryEntries, self.avatarListNode.listContainerNode.currentEntry, self.avatarTransitionArguments(entry: currentEntry))
|
self.requestAvatarExpansion?(true, self.avatarListNode.listContainerNode.galleryEntries, self.avatarListNode.listContainerNode.currentEntry, self.avatarTransitionArguments(entry: currentEntry))
|
||||||
}
|
}
|
||||||
@ -2493,8 +2478,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
func updateAvatarIsHidden(entry: AvatarGalleryEntry?) {
|
func updateAvatarIsHidden(entry: AvatarGalleryEntry?) {
|
||||||
if let entry = entry {
|
if let entry = entry {
|
||||||
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||||
|
self.editingContentNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||||
} else {
|
} else {
|
||||||
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = false
|
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = false
|
||||||
|
self.editingContentNode.avatarNode.isHidden = false
|
||||||
}
|
}
|
||||||
self.avatarListNode.listContainerNode.updateEntryIsHidden(entry: entry)
|
self.avatarListNode.listContainerNode.updateEntryIsHidden(entry: entry)
|
||||||
}
|
}
|
||||||
|
@ -2074,7 +2074,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.headerNode.requestAvatarExpansion = { [weak self] gallery, entries, centralEntry, _ in
|
self.headerNode.requestAvatarExpansion = { [weak self] gallery, entries, centralEntry, _ in
|
||||||
guard let strongSelf = self, let peer = strongSelf.data?.peer, peer.smallProfileImage != nil else {
|
guard let strongSelf = self, let peer = strongSelf.data?.peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2085,7 +2085,13 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if !gallery {
|
}
|
||||||
|
|
||||||
|
guard peer.smallProfileImage != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !gallery {
|
||||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
||||||
strongSelf.headerNode.updateIsAvatarExpanded(true, transition: transition)
|
strongSelf.headerNode.updateIsAvatarExpanded(true, transition: transition)
|
||||||
strongSelf.updateNavigationExpansionPresentation(isExpanded: true, animated: true)
|
strongSelf.updateNavigationExpansionPresentation(isExpanded: true, animated: true)
|
||||||
@ -5282,20 +5288,17 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
let _ = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: layout.safeInsets.left, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : offsetY, presentationData: self.presentationData, peer: self.data?.peer, cachedData: self.data?.cachedData, notificationSettings: self.data?.notificationSettings, statusData: self.data?.status, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, transition: transition, additive: additive)
|
let _ = self.headerNode.update(width: layout.size.width, containerHeight: layout.size.height, containerInset: layout.safeInsets.left, statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, isModalOverlay: layout.isModalOverlay, isMediaOnly: self.isMediaOnly, contentOffset: self.isMediaOnly ? 212.0 : offsetY, presentationData: self.presentationData, peer: self.data?.peer, cachedData: self.data?.cachedData, notificationSettings: self.data?.notificationSettings, statusData: self.data?.status, isContact: self.data?.isContact ?? false, isSettings: self.isSettings, state: self.state, transition: transition, additive: additive)
|
||||||
}
|
}
|
||||||
|
|
||||||
let effectiveAreaExpansionFraction: CGFloat
|
|
||||||
if self.isSettings {
|
|
||||||
let paneAreaExpansionDistance: CGFloat = 32.0
|
let paneAreaExpansionDistance: CGFloat = 32.0
|
||||||
|
let effectiveAreaExpansionFraction: CGFloat
|
||||||
|
if self.state.isEditing {
|
||||||
|
effectiveAreaExpansionFraction = 0.0
|
||||||
|
} else if self.isSettings {
|
||||||
var paneAreaExpansionDelta = (self.headerNode.frame.maxY - navigationHeight) - self.scrollNode.view.contentOffset.y
|
var paneAreaExpansionDelta = (self.headerNode.frame.maxY - navigationHeight) - self.scrollNode.view.contentOffset.y
|
||||||
paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance))
|
paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance))
|
||||||
|
|
||||||
effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance
|
effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance
|
||||||
} else if self.state.isEditing {
|
|
||||||
effectiveAreaExpansionFraction = 0.0
|
|
||||||
} else {
|
} else {
|
||||||
let paneAreaExpansionDistance: CGFloat = 32.0
|
|
||||||
var paneAreaExpansionDelta = (self.paneContainerNode.frame.minY - navigationHeight) - self.scrollNode.view.contentOffset.y
|
var paneAreaExpansionDelta = (self.paneContainerNode.frame.minY - navigationHeight) - self.scrollNode.view.contentOffset.y
|
||||||
paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance))
|
paneAreaExpansionDelta = max(0.0, min(paneAreaExpansionDelta, paneAreaExpansionDistance))
|
||||||
|
|
||||||
effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance
|
effectiveAreaExpansionFraction = 1.0 - paneAreaExpansionDelta / paneAreaExpansionDistance
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5396,7 +5399,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
self.canOpenAvatarByDragging = false
|
self.canOpenAvatarByDragging = false
|
||||||
let contentOffset = scrollView.contentOffset.y
|
let contentOffset = scrollView.contentOffset.y
|
||||||
scrollView.panGestureRecognizer.isEnabled = false
|
scrollView.panGestureRecognizer.isEnabled = false
|
||||||
self.headerNode.initiateAvatarExpansion()
|
self.headerNode.initiateAvatarExpansion(gallery: true)
|
||||||
scrollView.panGestureRecognizer.isEnabled = true
|
scrollView.panGestureRecognizer.isEnabled = true
|
||||||
scrollView.contentOffset = CGPoint(x: 0.0, y: contentOffset)
|
scrollView.contentOffset = CGPoint(x: 0.0, y: contentOffset)
|
||||||
UIView.animate(withDuration: 0.1) {
|
UIView.animate(withDuration: 0.1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user