mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
150 lines
6.8 KiB
Swift
150 lines
6.8 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import TelegramPresentationData
|
|
import AccountContext
|
|
import Display
|
|
import RadialStatusNode
|
|
import Postbox
|
|
import TelegramCore
|
|
import PeerInfoAvatarListNode
|
|
import AvatarNode
|
|
import SwiftSignalKit
|
|
|
|
final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
|
private let context: AccountContext
|
|
|
|
private let imageNode: ImageNode
|
|
private let updatingAvatarOverlay: ASImageNode
|
|
private let iconNode: ASImageNode
|
|
private var statusNode: RadialStatusNode
|
|
|
|
private var currentRepresentation: TelegramMediaImageRepresentation?
|
|
|
|
init(context: AccountContext) {
|
|
self.context = context
|
|
|
|
self.imageNode = ImageNode(enableEmpty: true)
|
|
|
|
self.updatingAvatarOverlay = ASImageNode()
|
|
self.updatingAvatarOverlay.displayWithoutProcessing = true
|
|
self.updatingAvatarOverlay.displaysAsynchronously = false
|
|
self.updatingAvatarOverlay.alpha = 0.0
|
|
|
|
self.statusNode = RadialStatusNode(backgroundNodeColor: UIColor(rgb: 0x000000, alpha: 0.6))
|
|
self.statusNode.isUserInteractionEnabled = false
|
|
|
|
self.iconNode = ASImageNode()
|
|
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Avatar/EditAvatarIconLarge"), color: .white)
|
|
self.iconNode.alpha = 0.0
|
|
|
|
super.init()
|
|
|
|
self.imageNode.frame = CGRect(origin: CGPoint(x: -50.0, y: -50.0), size: CGSize(width: 100.0, height: 100.0))
|
|
self.updatingAvatarOverlay.frame = self.imageNode.frame
|
|
|
|
let radialStatusSize: CGFloat = 50.0
|
|
let imagePosition = self.imageNode.position
|
|
self.statusNode.frame = CGRect(origin: CGPoint(x: floor(imagePosition.x - radialStatusSize / 2.0), y: floor(imagePosition.y - radialStatusSize / 2.0)), size: CGSize(width: radialStatusSize, height: radialStatusSize))
|
|
|
|
if let image = self.iconNode.image {
|
|
self.iconNode.frame = CGRect(origin: CGPoint(x: floor(imagePosition.x - image.size.width / 2.0), y: floor(imagePosition.y - image.size.height / 2.0)), size: image.size)
|
|
}
|
|
|
|
self.addSubnode(self.imageNode)
|
|
self.addSubnode(self.updatingAvatarOverlay)
|
|
self.addSubnode(self.statusNode)
|
|
}
|
|
|
|
func updateTransitionFraction(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
|
transition.updateAlpha(node: self, alpha: 1.0 - fraction)
|
|
}
|
|
|
|
func update(peer: Peer?, threadData: MessageHistoryThreadData?, chatLocation: ChatLocation, item: PeerInfoAvatarListItem?, updatingAvatar: PeerInfoUpdatingAvatar?, uploadProgress: AvatarUploadProgress?, theme: PresentationTheme, avatarSize: CGFloat, isEditing: Bool) {
|
|
guard let peer = peer else {
|
|
return
|
|
}
|
|
|
|
self.imageNode.frame = CGRect(origin: CGPoint(x: -avatarSize / 2.0, y: -avatarSize / 2.0), size: CGSize(width: avatarSize, height: avatarSize))
|
|
self.updatingAvatarOverlay.frame = self.imageNode.frame
|
|
|
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .linear)
|
|
|
|
let clipStyle: AvatarNodeClipStyle
|
|
if let channel = peer as? TelegramChannel, channel.flags.contains(.isForum) {
|
|
clipStyle = .roundedRect
|
|
} else {
|
|
clipStyle = .round
|
|
}
|
|
|
|
var isPersonal = false
|
|
if let updatingAvatar, case let .image(image) = updatingAvatar, image.isPersonal {
|
|
isPersonal = true
|
|
}
|
|
|
|
if canEditPeerInfo(context: self.context, peer: peer, chatLocation: chatLocation, threadData: threadData)
|
|
|| isPersonal
|
|
|| self.currentRepresentation != nil && updatingAvatar == nil {
|
|
var overlayHidden = true
|
|
if let updatingAvatar = updatingAvatar {
|
|
overlayHidden = false
|
|
|
|
var cancelEnabled = true
|
|
let progressValue: CGFloat?
|
|
if let uploadProgress {
|
|
switch uploadProgress {
|
|
case let .value(value):
|
|
progressValue = max(0.027, value)
|
|
case .indefinite:
|
|
progressValue = nil
|
|
cancelEnabled = false
|
|
}
|
|
} else {
|
|
progressValue = 0.027
|
|
}
|
|
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: progressValue, cancelEnabled: cancelEnabled, animateRotation: true))
|
|
|
|
if case let .image(representation) = updatingAvatar {
|
|
if representation != self.currentRepresentation {
|
|
self.currentRepresentation = representation
|
|
|
|
if let signal = peerAvatarImage(account: context.account, peerReference: nil, authorOfMessage: nil, representation: representation, displayDimensions: CGSize(width: avatarSize, height: avatarSize), clipStyle: clipStyle, emptyColor: nil, synchronousLoad: false, provideUnrounded: false) {
|
|
self.imageNode.setSignal(signal |> map { $0?.0 })
|
|
}
|
|
}
|
|
}
|
|
|
|
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: 1.0)
|
|
} else {
|
|
let targetOverlayAlpha: CGFloat = 0.0
|
|
if self.updatingAvatarOverlay.alpha != targetOverlayAlpha {
|
|
let update = {
|
|
self.statusNode.transitionToState(.none)
|
|
self.currentRepresentation = nil
|
|
self.imageNode.setSignal(.single(nil))
|
|
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: overlayHidden ? 0.0 : 1.0)
|
|
}
|
|
Queue.mainQueue().after(0.3) {
|
|
update()
|
|
}
|
|
}
|
|
}
|
|
if !overlayHidden && self.updatingAvatarOverlay.image == nil {
|
|
switch clipStyle {
|
|
case .round:
|
|
self.updatingAvatarOverlay.image = generateFilledCircleImage(diameter: avatarSize, color: UIColor(white: 0.0, alpha: 0.4), backgroundColor: nil)
|
|
case .roundedRect:
|
|
self.updatingAvatarOverlay.image = generateFilledRoundedRectImage(size: CGSize(width: avatarSize, height: avatarSize), cornerRadius: avatarSize * 0.25, color: UIColor(white: 0.0, alpha: 0.4), backgroundColor: nil)
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
self.statusNode.transitionToState(.none)
|
|
self.currentRepresentation = nil
|
|
transition.updateAlpha(node: self.iconNode, alpha: 0.0)
|
|
transition.updateAlpha(node: self.updatingAvatarOverlay, alpha: 0.0)
|
|
}
|
|
}
|
|
}
|