mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
93 lines
4.0 KiB
Swift
93 lines
4.0 KiB
Swift
import Foundation
|
|
import Display
|
|
import AsyncDisplayKit
|
|
import Postbox
|
|
import TelegramCore
|
|
|
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 13.0)!
|
|
|
|
final class MultipleAvatarsNode: ASDisplayNode {
|
|
private var nodes: [(Peer, AvatarNode)] = []
|
|
|
|
static func asyncLayout(_ current: MultipleAvatarsNode?) -> (Account, PresentationTheme, [Peer], CGSize) -> (Bool) -> MultipleAvatarsNode {
|
|
let currentNodes: [(Peer, AvatarNode)] = current?.nodes ?? []
|
|
return { account, theme, peers, size in
|
|
var node: MultipleAvatarsNode
|
|
if let current = current {
|
|
node = current
|
|
} else {
|
|
node = MultipleAvatarsNode()
|
|
}
|
|
|
|
var resultNodes: [(Peer, AvatarNode)] = []
|
|
for peer in peers {
|
|
var found = false
|
|
inner: for (currentPeer, currentNode) in currentNodes {
|
|
if currentPeer.id == peer.id {
|
|
resultNodes.append((peer, currentNode))
|
|
found = true
|
|
break inner
|
|
}
|
|
}
|
|
if !found {
|
|
resultNodes.append((peer, AvatarNode(font: avatarFont)))
|
|
}
|
|
if resultNodes.count == 4 {
|
|
break
|
|
}
|
|
}
|
|
|
|
return { animated in
|
|
let partitionSize = floor(size.width / 2.0)
|
|
let singleSize = partitionSize - 1.0
|
|
|
|
var index = 0
|
|
for (peer, avatarNode) in resultNodes {
|
|
let xPosition: CGFloat = index % 2 == 0 ? 0.0 : size.width - singleSize
|
|
let yPosition = index / 2 == 0 ? 0.0 : size.height - singleSize
|
|
let avatarFrame = CGRect(origin: CGPoint(x: xPosition, y: yPosition), size: CGSize(width: singleSize, height: singleSize))
|
|
if avatarNode.supernode == nil {
|
|
node.addSubnode(avatarNode)
|
|
avatarNode.frame = avatarFrame
|
|
if animated {
|
|
avatarNode.layer.animateScale(from: 0.2, to: 1.0, duration: 0.2)
|
|
avatarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
|
}
|
|
} else {
|
|
let distance = CGPoint(x: avatarNode.frame.midX - avatarFrame.midX, y: avatarNode.frame.midY - avatarFrame.midY)
|
|
avatarNode.frame = avatarFrame
|
|
if animated {
|
|
avatarNode.layer.animatePosition(from: distance, to: CGPoint(), duration: 0.2, timingFunction: kCAMediaTimingFunctionEaseInEaseOut, additive: true)
|
|
}
|
|
}
|
|
avatarNode.setPeer(account: account, theme: theme, peer: peer)
|
|
index += 1
|
|
}
|
|
index += 1
|
|
for (_, currentNode) in node.nodes {
|
|
var found = false
|
|
inner: for (_, resultNode) in resultNodes {
|
|
if currentNode === resultNode {
|
|
found = true
|
|
break inner
|
|
}
|
|
}
|
|
if !found {
|
|
if animated {
|
|
currentNode.layer.animateScale(from: 1.0, to: 0.4, duration: 0.2, removeOnCompletion: false)
|
|
currentNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak currentNode] _ in
|
|
currentNode?.removeFromSupernode()
|
|
})
|
|
} else {
|
|
currentNode.removeFromSupernode()
|
|
}
|
|
}
|
|
}
|
|
node.nodes = resultNodes
|
|
|
|
return node
|
|
}
|
|
}
|
|
}
|
|
}
|