Swiftgram/submodules/ListMessageItem/Sources/ListMessageHoleItem.swift

116 lines
4.7 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import Display
import TelegramCore
import SwiftSignalKit
import Postbox
final class ListMessageHoleItem: ListViewItem {
public init() {
}
public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
let configure = { () -> Void in
let node = ListMessageHoleItemNode()
let nodeLayout = node.asyncLayout()
let (top, bottom, dateAtBottom) = (false, false, false)
let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom)
node.updateSelectionState(animated: false)
node.contentSize = layout.contentSize
node.insets = layout.insets
Queue.mainQueue().async {
completion(node, {
return (nil, { _ in apply(.None) })
})
}
}
if Thread.isMainThread {
async {
configure()
}
} else {
configure()
}
}
public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
Queue.mainQueue().async {
if let nodeValue = node() as? ListMessageHoleItemNode {
nodeValue.updateSelectionState(animated: false)
let nodeLayout = nodeValue.asyncLayout()
async {
let (top, bottom, dateAtBottom) = (false, false, false)
let (layout, apply) = nodeLayout(self, params, top, bottom, dateAtBottom)
Queue.mainQueue().async {
completion(layout, { _ in
apply(animation)
})
}
}
} else {
assertionFailure()
}
}
}
}
final class ListMessageHoleItemNode: ListViewItemNode {
private var activityIndicator: UIActivityIndicatorView?
init() {
super.init(layerBacked: false, dynamicBounce: false)
}
override func didLoad() {
super.didLoad()
let activityIndicator = UIActivityIndicatorView(style: .gray)
self.activityIndicator = activityIndicator
self.view.addSubview(activityIndicator)
let size = activityIndicator.bounds.size
activityIndicator.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - size.width) / 2.0), y: floor((self.bounds.size.height - size.height) / 2.0)), size: size)
activityIndicator.startAnimating()
}
override public func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) {
if let item = item as? ListMessageHoleItem {
let doLayout = self.asyncLayout()
let merged = (top: false, bottom: false, dateAtBottom: false)
let (layout, apply) = doLayout(item, params, merged.top, merged.bottom, merged.dateAtBottom)
self.contentSize = layout.contentSize
self.insets = layout.insets
apply(.None)
}
}
func asyncLayout() -> (_ item: ListMessageHoleItem, _ params: ListViewItemLayoutParams, _ mergedTop: Bool, _ mergedBottom: Bool, _ dateAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) {
return { [weak self] _, params, _, _, _ in
return (ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 50.0), insets: UIEdgeInsets()), { _ in
if let strongSelf = self, let activityIndicator = strongSelf.activityIndicator {
let boundsSize = CGSize(width: params.width, height: 50.0)
let size = activityIndicator.bounds.size
activityIndicator.frame = CGRect(origin: CGPoint(x: floor((boundsSize.width - size.width) / 2.0), y: floor((boundsSize.height - size.height) / 2.0)), size: size)
}
})
}
}
func transitionNode(id: MessageId, media: Media) -> ASDisplayNode? {
return nil
}
func updateHiddenMedia() {
}
func updateSelectionState(animated: Bool) {
}
}