mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Refactor ChatListUI
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
|
||||
public enum ChatTitleActivityAnimationStyle {
|
||||
case none
|
||||
case crossfade
|
||||
case slide
|
||||
}
|
||||
|
||||
public enum ChatTitleActivityInfoType {
|
||||
case online
|
||||
case lastSeenTime
|
||||
case generic
|
||||
}
|
||||
|
||||
public enum ChatTitleActivityNodeState: Equatable {
|
||||
case none
|
||||
case info(NSAttributedString, ChatTitleActivityInfoType)
|
||||
case typingText(NSAttributedString, UIColor)
|
||||
case uploading(NSAttributedString, UIColor)
|
||||
case recordingVoice(NSAttributedString, UIColor)
|
||||
case recordingVideo(NSAttributedString, UIColor)
|
||||
case playingGame(NSAttributedString, UIColor)
|
||||
|
||||
func contentNode() -> ChatTitleActivityContentNode? {
|
||||
switch self {
|
||||
case .none:
|
||||
return nil
|
||||
case let .info(text, _):
|
||||
return ChatTitleActivityContentNode(text: text)
|
||||
case let .typingText(text, color):
|
||||
return ChatTypingActivityContentNode(text: text, color: color)
|
||||
case let .uploading(text, color):
|
||||
return ChatUploadingActivityContentNode(text: text, color: color)
|
||||
case let .recordingVoice(text, color):
|
||||
return ChatRecordingVoiceActivityContentNode(text: text, color: color)
|
||||
case let .recordingVideo(text, color):
|
||||
return ChatRecordingVideoActivityContentNode(text: text, color: color)
|
||||
case let .playingGame(text, color):
|
||||
return ChatPlayingActivityContentNode(text: text, color: color)
|
||||
}
|
||||
}
|
||||
|
||||
public var string: String? {
|
||||
if case let .info(text, _) = self {
|
||||
return text.string
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public class ChatTitleActivityNode: ASDisplayNode {
|
||||
public private(set) var state: ChatTitleActivityNodeState = .none
|
||||
|
||||
private var contentNode: ChatTitleActivityContentNode?
|
||||
private var nextContentNode: ChatTitleActivityContentNode?
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func transitionToState(_ state: ChatTitleActivityNodeState, animation: ChatTitleActivityAnimationStyle = .crossfade, completion: @escaping () -> Void = {}) -> Bool {
|
||||
if self.state != state {
|
||||
let currentState = self.state
|
||||
self.state = state
|
||||
|
||||
let contentNode = state.contentNode()
|
||||
if contentNode !== self.contentNode {
|
||||
self.transitionToContentNode(contentNode, state: state, fromState: currentState, animation: animation, completion: completion)
|
||||
}
|
||||
|
||||
return true
|
||||
} else {
|
||||
completion()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func transitionToContentNode(_ node: ChatTitleActivityContentNode?, state: ChatTitleActivityNodeState, fromState: ChatTitleActivityNodeState, animation: ChatTitleActivityAnimationStyle = .crossfade, completion: @escaping () -> Void) {
|
||||
if let previousContentNode = self.contentNode {
|
||||
if case .none = animation {
|
||||
previousContentNode.removeFromSupernode()
|
||||
self.contentNode = node
|
||||
if let contentNode = self.contentNode {
|
||||
self.addSubnode(contentNode)
|
||||
}
|
||||
} else {
|
||||
var animation = animation
|
||||
if case let .info(_, fromType) = fromState, case let .info(_, toType) = state, fromType == toType {
|
||||
animation = .none
|
||||
}
|
||||
if case .typingText = fromState, case .typingText = state {
|
||||
animation = .none
|
||||
}
|
||||
|
||||
self.contentNode = node
|
||||
if let contentNode = self.contentNode {
|
||||
self.addSubnode(contentNode)
|
||||
if self.isNodeLoaded {
|
||||
contentNode.animateIn(from: fromState, style: animation)
|
||||
}
|
||||
}
|
||||
previousContentNode.animateOut(to: state, style: animation) {
|
||||
previousContentNode.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.contentNode = node
|
||||
if let contentNode = self.contentNode {
|
||||
self.addSubnode(contentNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||
return CGSize(width: 0.0, height: self.contentNode?.updateLayout(constrainedSize, alignment: alignment).height ?? 0.0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user