Refactoring [skip ci]

This commit is contained in:
Ali 2023-10-15 14:47:43 +04:00
parent 76719a7c95
commit 8e566ed820
23 changed files with 417 additions and 144 deletions

View File

@ -383,6 +383,9 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatSwipeToReplyRecognizer",
"//submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageTransitionNode",
"//submodules/TelegramUI/Components/Chat/ManagedDiceAnimationNode",
] + select({
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
"//build-system:ios_sim_arm64": [],

View File

@ -0,0 +1,60 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ChatMessageAnimatedStickerItemNode",
module_name = "ChatMessageAnimatedStickerItemNode",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/AsyncDisplayKit",
"//submodules/Display",
"//submodules/SSignalKit/SwiftSignalKit",
"//submodules/Postbox",
"//submodules/TelegramCore",
"//submodules/TelegramPresentationData",
"//submodules/TextFormat",
"//submodules/AccountContext",
"//submodules/MediaResources",
"//submodules/StickerResources",
"//submodules/ContextUI",
"//submodules/AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode",
"//submodules/Emoji",
"//submodules/Markdown",
"//submodules/ManagedAnimationNode",
"//submodules/SlotMachineAnimationNode",
"//submodules/MediaPlayer:UniversalMediaPlayer",
"//submodules/ShimmerEffect",
"//submodules/WallpaperBackgroundNode",
"//submodules/LocalMediaResources",
"//submodules/AppBundle",
"//submodules/ChatPresentationInterfaceState",
"//submodules/TelegramUI/Components/TextNodeWithEntities",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
"//submodules/TelegramUI/Components/Chat/ChatMessageForwardInfoNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItem",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemView",
"//submodules/TelegramUI/Components/Chat/ChatMessageSwipeToReplyNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageSelectionNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageDeliveryFailedNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageShareButton",
"//submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode",
"//submodules/TelegramUI/Components/Chat/ChatSwipeToReplyRecognizer",
"//submodules/TelegramUI/Components/Chat/ChatMessageReactionsFooterContentNode",
"//submodules/TelegramUI/Components/Chat/ManagedDiceAnimationNode",
"//submodules/TelegramUI/Components/Chat/MessageHaptics",
"//submodules/TelegramUI/Components/Chat/ChatMessageTransitionNode",
],
visibility = [
"//visibility:public",
],
)

View File

@ -43,12 +43,15 @@ import ChatMessageThreadInfoNode
import ChatMessageActionButtonsNode
import ChatSwipeToReplyRecognizer
import ChatMessageReactionsFooterContentNode
import ManagedDiceAnimationNode
import MessageHaptics
import ChatMessageTransitionNode
private let nameFont = Font.medium(14.0)
private let inlineBotPrefixFont = Font.regular(14.0)
private let inlineBotNameFont = nameFont
protocol GenericAnimatedStickerNode: ASDisplayNode {
public protocol GenericAnimatedStickerNode: ASDisplayNode {
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool)
var currentFrameIndex: Int { get }
@ -56,29 +59,32 @@ protocol GenericAnimatedStickerNode: ASDisplayNode {
}
extension DefaultAnimatedStickerNodeImpl: GenericAnimatedStickerNode {
func setFrameIndex(_ frameIndex: Int) {
public func setFrameIndex(_ frameIndex: Int) {
self.stop()
self.play(fromIndex: frameIndex)
}
}
extension SlotMachineAnimationNode: GenericAnimatedStickerNode {
var currentFrameIndex: Int {
public var currentFrameIndex: Int {
return 0
}
func setFrameIndex(_ frameIndex: Int) {
public func setFrameIndex(_ frameIndex: Int) {
}
}
class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let contextSourceNode: ContextExtractedContentContainingNode
extension ManagedDiceAnimationNode: GenericAnimatedStickerNode {
}
public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
public let contextSourceNode: ContextExtractedContentContainingNode
private let containerNode: ContextControllerSourceNode
let imageNode: TransformImageNode
public let imageNode: TransformImageNode
private var enableSynchronousImageApply: Bool = false
private var backgroundNode: WallpaperBubbleBackgroundNode?
private(set) var placeholderNode: StickerShimmerEffectNode
private(set) var animationNode: GenericAnimatedStickerNode?
public private(set) var placeholderNode: StickerShimmerEffectNode
public private(set) var animationNode: GenericAnimatedStickerNode?
private var animationSize: CGSize?
private var didSetUpAnimationNode = false
private var isPlaying = false
@ -86,7 +92,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private let textNode: TextNodeWithEntities
private var additionalAnimationNodes: [ChatMessageTransitionNode.DecorationItemNode] = []
private var overlayMeshAnimationNode: ChatMessageTransitionNode.DecorationItemNode?
private var enqueuedAdditionalAnimations: [(Int, Double)] = []
private var additionalAnimationsCommitTimer: SwiftSignalKit.Timer?
@ -97,10 +102,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private var deliveryFailedNode: ChatMessageDeliveryFailedNode?
private var shareButtonNode: ChatMessageShareButton?
var telegramFile: TelegramMediaFile?
var emojiFile: TelegramMediaFile?
var telegramDice: TelegramMediaDice?
var emojiString: String?
public var telegramFile: TelegramMediaFile?
public var emojiFile: TelegramMediaFile?
public var telegramDice: TelegramMediaDice?
public var emojiString: String?
private let disposable = MetaDisposable()
private let disposables = DisposableSet()
@ -136,7 +141,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private var wasPending: Bool = false
private var didChangeFromPendingToSent: Bool = false
required init() {
required public init() {
self.contextSourceNode = ContextExtractedContentContainingNode()
self.containerNode = ContextControllerSourceNode()
self.imageNode = TransformImageNode()
@ -233,7 +238,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.additionalAnimationsCommitTimer?.invalidate()
}
required init?(coder aDecoder: NSCoder) {
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@ -248,7 +253,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func didLoad() {
override public func didLoad() {
super.didLoad()
let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:)))
@ -325,7 +330,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.view.addGestureRecognizer(replyRecognizer)
}
override var visibility: ListViewItemNodeVisibility {
override public var visibility: ListViewItemNodeVisibility {
didSet {
let wasVisible = oldValue != .none
let isVisible = self.visibility != .none
@ -425,7 +430,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) {
override public func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) {
super.setupItem(item, synchronousLoad: synchronousLoad)
if item.message.id.namespace == Namespaces.Message.Local || item.message.id.namespace == Namespaces.Message.ScheduledLocal {
@ -587,13 +592,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
let isPlaying = self.visibilityStatus == true && !self.forceStopAnimations
if !isPlaying {
self.removeAdditionalAnimations()
if let overlayMeshAnimationNode = self.overlayMeshAnimationNode {
self.overlayMeshAnimationNode = nil
if let transitionNode = item.controllerInteraction.getMessageTransitionNode() as? ChatMessageTransitionNode {
transitionNode.remove(decorationNode: overlayMeshAnimationNode)
}
}
}
if let animationNode = self.animationNode as? AnimatedStickerNode {
if self.isPlaying != isPlaying || (isPlaying && !self.didSetUpAnimationNode) {
@ -663,13 +661,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func updateStickerSettings(forceStopAnimations: Bool) {
override public func updateStickerSettings(forceStopAnimations: Bool) {
self.forceStopAnimations = forceStopAnimations
self.updateVisibility()
}
private var absoluteRect: (CGRect, CGSize)?
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
self.absoluteRect = (rect, containerSize)
if !self.contextSourceNode.isExtractedToContextPreview {
var rect = rect
@ -723,7 +721,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
override public func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
if let backgroundNode = self.backgroundNode {
backgroundNode.offset(value: value, animationCurve: animationCurve, duration: duration)
}
@ -733,7 +731,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) {
override public func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) {
super.updateAccessibilityData(accessibilityData)
self.messageAccessibilityArea.accessibilityLabel = accessibilityData.label
@ -764,7 +762,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) {
override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) {
var displaySize = CGSize(width: 180.0, height: 180.0)
let telegramFile = self.telegramFile
let emojiFile = self.emojiFile
@ -1761,7 +1759,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
item.controllerInteraction.commitEmojiInteraction(item.message.id, item.message.text.strippedEmoji, EmojiInteraction(animations: animations), file)
}
func playEmojiInteraction(_ interaction: EmojiInteraction) {
public func playEmojiInteraction(_ interaction: EmojiInteraction) {
guard interaction.animations.count <= 7 else {
return
}
@ -1807,7 +1805,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
func playAdditionalEmojiAnimation(index: Int) {
public func playAdditionalEmojiAnimation(index: Int) {
guard let item = self.item else {
return
}
@ -1846,7 +1844,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.playEffectAnimation(resource: effect.resource, isStickerEffect: true)
}
func playEffectAnimation(resource: MediaResource, isStickerEffect: Bool = false) {
public func playEffectAnimation(resource: MediaResource, isStickerEffect: Bool = false) {
guard let item = self.item else {
return
}
@ -2282,7 +2280,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
private var playedSwipeToReplyHaptic = false
@objc func swipeToReplyGesture(_ recognizer: ChatSwipeToReplyRecognizer) {
@objc private func swipeToReplyGesture(_ recognizer: ChatSwipeToReplyRecognizer) {
var offset: CGFloat = 0.0
var leftOffset: CGFloat = 0.0
var swipeOffset: CGFloat = 45.0
@ -2406,7 +2404,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if let shareButtonNode = self.shareButtonNode, shareButtonNode.frame.contains(point) {
return shareButtonNode.view
}
@ -2421,7 +2419,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
return super.hitTest(point, with: event)
}
override func updateSelectionState(animated: Bool) {
override public func updateSelectionState(animated: Bool) {
guard let item = self.item else {
return
}
@ -2503,7 +2501,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func updateHighlightedState(animated: Bool) {
override public func updateHighlightedState(animated: Bool) {
super.updateHighlightedState(animated: animated)
if let item = self.item {
@ -2528,11 +2526,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func cancelInsertionAnimations() {
override public func cancelInsertionAnimations() {
self.layer.removeAllAnimations()
}
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
super.animateInsertion(currentTimestamp, duration: duration, short: short)
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
@ -2550,27 +2548,41 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
override public func animateRemoved(_ currentTimestamp: Double, duration: Double) {
super.animateRemoved(currentTimestamp, duration: duration)
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
}
override func animateAdded(_ currentTimestamp: Double, duration: Double) {
override public func animateAdded(_ currentTimestamp: Double, duration: Double) {
super.animateAdded(currentTimestamp, duration: duration)
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
}
override func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? {
override public func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? {
return self.contextSourceNode
}
override func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) {
override public func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) {
self.contextSourceNode.contentNode.addSubnode(accessoryItemNode)
}
func animateContentFromTextInputField(textInput: ChatMessageTransitionNode.Source.TextInput, transition: CombinedTransition) {
public final class AnimationTransitionTextInput {
public let backgroundView: UIView
public let contentView: UIView
public let sourceRect: CGRect
public let scrollOffset: CGFloat
public init(backgroundView: UIView, contentView: UIView, sourceRect: CGRect, scrollOffset: CGFloat) {
self.backgroundView = backgroundView
self.contentView = contentView
self.sourceRect = sourceRect
self.scrollOffset = scrollOffset
}
}
public func animateContentFromTextInputField(textInput: AnimationTransitionTextInput, transition: CombinedTransition) {
guard let _ = self.item else {
return
}
@ -2630,7 +2642,55 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.dateAndStatusNode.layer.animateAlpha(from: 0.0, to: self.dateAndStatusNode.alpha, duration: 0.15, delay: 0.16)
}
func animateContentFromStickerGridItem(stickerSource: ChatMessageTransitionNode.Sticker, transition: CombinedTransition) {
public final class AnimationTransitionSticker {
public let imageNode: TransformImageNode?
public let animationNode: ASDisplayNode?
public let placeholderNode: ASDisplayNode?
public let imageLayer: CALayer?
public let relativeSourceRect: CGRect
var sourceFrame: CGRect {
if let imageNode = self.imageNode {
return imageNode.frame
} else if let imageLayer = self.imageLayer {
return imageLayer.bounds
} else {
return CGRect(origin: CGPoint(), size: relativeSourceRect.size)
}
}
var sourceLayer: CALayer? {
if let imageNode = self.imageNode {
return imageNode.layer
} else if let imageLayer = self.imageLayer {
return imageLayer
} else {
return nil
}
}
func snapshotContentTree() -> UIView? {
if let animationNode = self.animationNode {
return animationNode.view.snapshotContentTree()
} else if let imageNode = self.imageNode {
return imageNode.view.snapshotContentTree()
} else if let sourceLayer = self.imageLayer {
return sourceLayer.snapshotContentTreeAsView()
} else {
return nil
}
}
public init(imageNode: TransformImageNode?, animationNode: ASDisplayNode?, placeholderNode: ASDisplayNode?, imageLayer: CALayer?, relativeSourceRect: CGRect) {
self.imageNode = imageNode
self.animationNode = animationNode
self.placeholderNode = placeholderNode
self.imageLayer = imageLayer
self.relativeSourceRect = relativeSourceRect
}
}
public func animateContentFromStickerGridItem(stickerSource: AnimationTransitionSticker, transition: CombinedTransition) {
guard let _ = self.item else {
return
}
@ -2717,7 +2777,25 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNode.ReplyPanel, transition: CombinedTransition) {
public final class AnimationTransitionReplyPanel {
public let titleNode: ASDisplayNode
public let textNode: ASDisplayNode
public let lineNode: ASDisplayNode
public let imageNode: ASDisplayNode
public let relativeSourceRect: CGRect
public let relativeTargetRect: CGRect
public init(titleNode: ASDisplayNode, textNode: ASDisplayNode, lineNode: ASDisplayNode, imageNode: ASDisplayNode, relativeSourceRect: CGRect, relativeTargetRect: CGRect) {
self.titleNode = titleNode
self.textNode = textNode
self.lineNode = lineNode
self.imageNode = imageNode
self.relativeSourceRect = relativeSourceRect
self.relativeTargetRect = relativeTargetRect
}
}
public func animateReplyPanel(sourceReplyPanel: AnimationTransitionReplyPanel, transition: CombinedTransition) {
if let replyInfoNode = self.replyInfoNode {
let localRect = self.contextSourceNode.contentNode.view.convert(sourceReplyPanel.relativeSourceRect, to: replyInfoNode.view)
@ -2737,7 +2815,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) {
public func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) {
guard let item = self.item else {
return
}
@ -2747,14 +2825,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
transition.animateTransformScale(node: self, from: CGPoint(x: 0.85, y: 0.85), delay: delay)
}
override func openMessageContextMenu() {
override public func openMessageContextMenu() {
guard let item = self.item else {
return
}
item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, nil, nil)
}
override func targetReactionView(value: MessageReaction.Reaction) -> UIView? {
override public func targetReactionView(value: MessageReaction.Reaction) -> UIView? {
if let result = self.reactionButtonsNode?.reactionTargetView(value: value) {
return result
}
@ -2764,7 +2842,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
return nil
}
override func targetForStoryTransition(id: StoryId) -> UIView? {
override public func targetForStoryTransition(id: StoryId) -> UIView? {
guard let item = self.item else {
return nil
}
@ -2780,17 +2858,17 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
return nil
}
override func unreadMessageRangeUpdated() {
override public func unreadMessageRangeUpdated() {
self.updateVisibility()
}
override func contentFrame() -> CGRect {
override public func contentFrame() -> CGRect {
return self.imageNode.frame
}
}
struct AnimatedEmojiSoundsConfiguration {
static var defaultValue: AnimatedEmojiSoundsConfiguration {
public struct AnimatedEmojiSoundsConfiguration {
public static var defaultValue: AnimatedEmojiSoundsConfiguration {
return AnimatedEmojiSoundsConfiguration(sounds: [:])
}
@ -2800,7 +2878,7 @@ struct AnimatedEmojiSoundsConfiguration {
self.sounds = sounds
}
static func with(appConfiguration: AppConfiguration, account: Account) -> AnimatedEmojiSoundsConfiguration {
public static func with(appConfiguration: AppConfiguration, account: Account) -> AnimatedEmojiSoundsConfiguration {
if let data = appConfiguration.data, let values = data["emojies_sounds"] as? [String: Any] {
var sounds: [String: TelegramMediaFile] = [:]
for (key, value) in values {

View File

@ -0,0 +1,19 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ChatMessageTransitionNode",
module_name = "ChatMessageTransitionNode",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/AsyncDisplayKit",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemView",
],
visibility = [
"//visibility:public",
],
)

View File

@ -0,0 +1,15 @@
import Foundation
import UIKit
import ChatMessageItemView
import AsyncDisplayKit
public protocol ChatMessageTransitionNodeDecorationItemNode: ASDisplayNode {
var contentView: UIView { get }
}
public protocol ChatMessageTransitionNode: AnyObject {
typealias DecorationItemNode = ChatMessageTransitionNodeDecorationItemNode
func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode
func remove(decorationNode: DecorationItemNode)
}

View File

@ -0,0 +1,25 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ManagedDiceAnimationNode",
module_name = "ManagedDiceAnimationNode",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/Display",
"//submodules/AsyncDisplayKit",
"//submodules/Postbox",
"//submodules/TelegramCore",
"//submodules/SSignalKit/SwiftSignalKit",
"//submodules/AccountContext",
"//submodules/StickerResources",
"//submodules/ManagedAnimationNode",
],
visibility = [
"//visibility:public",
],
)

View File

@ -8,7 +8,7 @@ import AccountContext
import StickerResources
import ManagedAnimationNode
enum ManagedDiceAnimationState: Equatable {
public enum ManagedDiceAnimationState: Equatable {
case rolling
case value(Int32, Bool)
}
@ -86,7 +86,7 @@ private struct InteractiveEmojiSuccessParameters {
}
public struct InteractiveEmojiConfiguration {
static var defaultValue: InteractiveEmojiConfiguration {
public static var defaultValue: InteractiveEmojiConfiguration {
return InteractiveEmojiConfiguration(emojis: [], successParameters: [:])
}
@ -98,7 +98,7 @@ public struct InteractiveEmojiConfiguration {
self.successParameters = successParameters
}
static func with(appConfiguration: AppConfiguration) -> InteractiveEmojiConfiguration {
public static func with(appConfiguration: AppConfiguration) -> InteractiveEmojiConfiguration {
if let data = appConfiguration.data, let emojis = data["emojies_send_dice"] as? [String] {
var successParameters: [String: InteractiveEmojiSuccessParameters] = [:]
if let success = data["emojies_send_dice_success"] as? [String: [String: Double]] {
@ -115,7 +115,7 @@ public struct InteractiveEmojiConfiguration {
}
}
final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStickerNode {
public final class ManagedDiceAnimationNode: ManagedAnimationNode {
private let context: AccountContext
private let emoji: String
@ -125,9 +125,9 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
private let configuration = Promise<InteractiveEmojiConfiguration?>()
private let emojis = Promise<[TelegramMediaFile]>()
var success: (() -> Void)?
public var success: (() -> Void)?
init(context: AccountContext, emoji: String) {
public init(context: AccountContext, emoji: String) {
self.context = context
self.emoji = emoji
@ -157,7 +157,7 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
self.disposable.dispose()
}
func setState(_ diceState: ManagedDiceAnimationState) {
public func setState(_ diceState: ManagedDiceAnimationState) {
let previousState = self.diceState
self.diceState = diceState
@ -203,13 +203,13 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
}
}
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool) {
public func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool) {
}
func setFrameIndex(_ frameIndex: Int) {
public func setFrameIndex(_ frameIndex: Int) {
}
var currentFrameIndex: Int {
public var currentFrameIndex: Int {
return 0
}
}

View File

@ -0,0 +1,19 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "MessageHaptics",
module_name = "MessageHaptics",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/Display",
"//submodules/SSignalKit/SwiftSignalKit",
],
visibility = [
"//visibility:public",
],
)

View File

@ -5,11 +5,11 @@ import SwiftSignalKit
private let firstImpactTime: Double = 0.4
private let secondImpactTime: Double = 0.6
final class CoffinHaptic: EmojiHaptic {
public final class CoffinHaptic: EmojiHaptic {
private var hapticFeedback = HapticFeedback()
private var timer: SwiftSignalKit.Timer?
private var time: Double = 0.0
var enabled: Bool = false {
public var enabled: Bool = false {
didSet {
if !self.enabled {
self.reset()
@ -17,10 +17,13 @@ final class CoffinHaptic: EmojiHaptic {
}
}
var active: Bool {
public var active: Bool {
return self.timer != nil
}
public init() {
}
private func reset() {
if let timer = self.timer {
self.time = 0.0
@ -36,7 +39,7 @@ final class CoffinHaptic: EmojiHaptic {
}
}
func start(time: Double) {
public func start(time: Double) {
self.hapticFeedback.prepareImpact()
if time > firstImpactTime {

View File

@ -2,18 +2,18 @@ import Foundation
import Display
import SwiftSignalKit
protocol EmojiHaptic {
public protocol EmojiHaptic {
var enabled: Bool { get set }
var active: Bool { get }
func start(time: Double)
}
final class HeartbeatHaptic: EmojiHaptic {
public final class HeartbeatHaptic: EmojiHaptic {
private var hapticFeedback = HapticFeedback()
private var timer: SwiftSignalKit.Timer?
private var time: Double = 0.0
var enabled: Bool = false {
public var enabled: Bool = false {
didSet {
if !self.enabled {
self.reset()
@ -21,10 +21,13 @@ final class HeartbeatHaptic: EmojiHaptic {
}
}
var active: Bool {
public var active: Bool {
return self.timer != nil
}
public init() {
}
private func reset() {
if let timer = self.timer {
self.time = 0.0
@ -42,7 +45,7 @@ final class HeartbeatHaptic: EmojiHaptic {
}
}
func start(time: Double) {
public func start(time: Double) {
self.hapticFeedback.prepareImpact()
if time > 2.0 {

View File

@ -4,11 +4,11 @@ import SwiftSignalKit
private let impactTime: Double = 0.6
final class PeachHaptic: EmojiHaptic {
public final class PeachHaptic: EmojiHaptic {
private var hapticFeedback = HapticFeedback()
private var timer: SwiftSignalKit.Timer?
private var time: Double = 0.0
var enabled: Bool = false {
public var enabled: Bool = false {
didSet {
if !self.enabled {
self.reset()
@ -16,10 +16,13 @@ final class PeachHaptic: EmojiHaptic {
}
}
var active: Bool {
public var active: Bool {
return self.timer != nil
}
public init() {
}
private func reset() {
if let timer = self.timer {
self.time = 0.0
@ -35,7 +38,7 @@ final class PeachHaptic: EmojiHaptic {
}
}
func start(time: Double) {
public func start(time: Double) {
self.hapticFeedback.prepareImpact()
if time > impactTime {

View File

@ -110,6 +110,7 @@ import ChatMessagePollBubbleContentNode
import ChatMessageItem
import ChatMessageItemView
import ChatMessageItemCommon
import ChatMessageAnimatedStickerItemNode
public enum ChatControllerPeekActions {
case standard
@ -8089,9 +8090,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
isScheduledMessages = false
}
let duration: Double = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.animationDuration : 0.18
let curve: ContainedViewLayoutTransitionCurve = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.verticalAnimationCurve : .easeInOut
let controlPoints: (Float, Float, Float, Float) = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.verticalAnimationControlPoints : (0.5, 0.33, 0.0, 0.0)
let duration: Double = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.animationDuration : 0.18
let curve: ContainedViewLayoutTransitionCurve = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.verticalAnimationCurve : .easeInOut
let controlPoints: (Float, Float, Float, Float) = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.verticalAnimationControlPoints : (0.5, 0.33, 0.0, 0.0)
let shouldUseFastMessageSendAnimation = strongSelf.chatDisplayNode.shouldUseFastMessageSendAnimation
@ -15533,15 +15534,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if addedTransitions.count > 1 {
var transitions: [(Int64, ChatMessageTransitionNode.Source, () -> Void)] = []
var transitions: [(Int64, ChatMessageTransitionNodeImpl.Source, () -> Void)] = []
for (correlationId, uniqueIds, initiated) in addedTransitions {
var source: ChatMessageTransitionNode.Source?
var source: ChatMessageTransitionNodeImpl.Source?
if uniqueIds.count > 1 {
source = .groupedMediaInput(ChatMessageTransitionNode.Source.GroupedMediaInput(extractSnapshots: {
source = .groupedMediaInput(ChatMessageTransitionNodeImpl.Source.GroupedMediaInput(extractSnapshots: {
return uniqueIds.compactMap({ getAnimatedTransitionSource?($0) })
}))
} else if let uniqueId = uniqueIds.first {
source = .mediaInput(ChatMessageTransitionNode.Source.MediaInput(extractSnapshot: {
source = .mediaInput(ChatMessageTransitionNodeImpl.Source.MediaInput(extractSnapshot: {
return getAnimatedTransitionSource?(uniqueId)
}))
}
@ -15551,13 +15552,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
strongSelf.chatDisplayNode.messageTransitionNode.add(grouped: transitions)
} else if let (correlationId, uniqueIds, initiated) = addedTransitions.first {
var source: ChatMessageTransitionNode.Source?
var source: ChatMessageTransitionNodeImpl.Source?
if uniqueIds.count > 1 {
source = .groupedMediaInput(ChatMessageTransitionNode.Source.GroupedMediaInput(extractSnapshots: {
source = .groupedMediaInput(ChatMessageTransitionNodeImpl.Source.GroupedMediaInput(extractSnapshots: {
return uniqueIds.compactMap({ getAnimatedTransitionSource?($0) })
}))
} else if let uniqueId = uniqueIds.first {
source = .mediaInput(ChatMessageTransitionNode.Source.MediaInput(extractSnapshot: {
source = .mediaInput(ChatMessageTransitionNodeImpl.Source.MediaInput(extractSnapshot: {
return getAnimatedTransitionSource?(uniqueId)
}))
}
@ -15825,7 +15826,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if strongSelf.chatDisplayNode.shouldAnimateMessageTransition, let extractedView = videoController.extractVideoSnapshot() {
usedCorrelationId = true
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .videoMessage(ChatMessageTransitionNode.Source.VideoMessage(view: extractedView)), initiated: { [weak videoController] in
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .videoMessage(ChatMessageTransitionNodeImpl.Source.VideoMessage(view: extractedView)), initiated: { [weak videoController] in
videoController?.hideVideoSnapshot()
guard let strongSelf = self else {
return
@ -15937,7 +15938,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if strongSelf.chatDisplayNode.shouldAnimateMessageTransition, let textInputPanelNode = strongSelf.chatDisplayNode.textInputPanelNode, let micButton = textInputPanelNode.micButton {
usedCorrelationId = true
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .audioMicInput(ChatMessageTransitionNode.Source.AudioMicInput(micButton: micButton)), initiated: {
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .audioMicInput(ChatMessageTransitionNodeImpl.Source.AudioMicInput(micButton: micButton)), initiated: {
guard let strongSelf = self else {
return
}

View File

@ -34,6 +34,8 @@ import TextSelectionNode
import ReplyAccessoryPanelNode
import ChatMessageItemView
import ChatMessageSelectionNode
import ManagedDiceAnimationNode
import ChatMessageTransitionNode
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
let itemNode: OverlayMediaItemNode
@ -267,7 +269,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
private var dropDimNode: ASDisplayNode?
let messageTransitionNode: ChatMessageTransitionNode
let messageTransitionNode: ChatMessageTransitionNodeImpl
private let presentationContextMarker = ASDisplayNode()
@ -589,7 +591,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
source = .default
}
var getMessageTransitionNode: (() -> ChatMessageTransitionNode?)?
var getMessageTransitionNode: (() -> ChatMessageTransitionNodeImpl?)?
self.historyNode = ChatHistoryListNode(context: context, updatedPresentationData: controller?.updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: nil, source: source, subject: subject, controllerInteraction: controllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), messageTransitionNode: {
return getMessageTransitionNode?()
})
@ -605,7 +607,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
var getContentAreaInScreenSpaceImpl: (() -> CGRect)?
var onTransitionEventImpl: ((ContainedViewLayoutTransition) -> Void)?
self.messageTransitionNode = ChatMessageTransitionNode(listNode: self.historyNode, getContentAreaInScreenSpace: {
self.messageTransitionNode = ChatMessageTransitionNodeImpl(listNode: self.historyNode, getContentAreaInScreenSpace: {
return getContentAreaInScreenSpaceImpl?() ?? CGRect()
}, onTransitionEvent: { transition in
onTransitionEventImpl?(transition)
@ -3472,7 +3474,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
}
if self.shouldAnimateMessageTransition, let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode, let textInput = inputPanelNode.makeSnapshotForTransition() {
usedCorrelationId = correlationId
let source: ChatMessageTransitionNode.Source = .textInput(textInput: textInput, replyPanel: replyPanel)
let source: ChatMessageTransitionNodeImpl.Source = .textInput(textInput: textInput, replyPanel: replyPanel)
self.messageTransitionNode.add(correlationId: correlationId, source: source, initiated: {
})
}

View File

@ -28,6 +28,7 @@ import ChatOverscrollControl
import ChatBotInfoItem
import ChatMessageItem
import ChatMessageItemView
import ChatMessageTransitionNode
struct ChatTopVisibleMessageRange: Equatable {
var lowerBound: MessageIndex
@ -662,7 +663,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private var toLang: String?
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNode? = { nil }) {
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl? = { nil }) {
var tagMask = tagMask
if case .pinnedMessages = subject {
tagMask = .pinned
@ -1015,7 +1016,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private func beginChatHistoryTransitions(
selectedMessages: Signal<Set<MessageId>?, NoError>,
messageTransitionNode: @escaping () -> ChatMessageTransitionNode?
messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?
) {
let context = self.context
let chatLocation = self.chatLocation

View File

@ -14,6 +14,7 @@ import ChatMessageItem
import ChatMessageItemView
import ChatMessageStickerItemNode
import ChatMessageInstantVideoItemNode
import ChatMessageAnimatedStickerItemNode
final class ChatLoadingNode: ASDisplayNode {
private let backgroundNode: NavigationBackgroundNode

View File

@ -851,7 +851,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
transition.animateTransformScale(node: self, from: CGPoint(x: 0.85, y: 0.85), delay: delay)
}
func animateContentFromTextInputField(textInput: ChatMessageTransitionNode.Source.TextInput, transition: CombinedTransition) {
func animateContentFromTextInputField(textInput: ChatMessageTransitionNodeImpl.Source.TextInput, transition: CombinedTransition) {
let widthDifference = self.backgroundNode.frame.width - textInput.backgroundView.frame.width
let heightDifference = self.backgroundNode.frame.height - textInput.backgroundView.frame.height
@ -884,7 +884,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
}
}
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNode.ReplyPanel, transition: CombinedTransition) {
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNodeImpl.ReplyPanel, transition: CombinedTransition) {
if let replyInfoNode = self.replyInfoNode {
let localRect = self.mainContextSourceNode.contentNode.view.convert(sourceReplyPanel.relativeSourceRect, to: replyInfoNode.view)
let mappedPanel = ChatMessageReplyInfoNode.TransitionReplyPanel(

View File

@ -15,6 +15,7 @@ import ChatHistoryEntry
import ChatMessageItem
import ChatMessageItemView
import ChatMessageStickerItemNode
import ChatMessageAnimatedStickerItemNode
private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge {
if let story = media as? TelegramMediaStory, story.isMention {

View File

@ -16,6 +16,8 @@ import ReplyAccessoryPanelNode
import ChatMessageItemView
import ChatMessageStickerItemNode
import ChatMessageInstantVideoItemNode
import ChatMessageAnimatedStickerItemNode
import ChatMessageTransitionNode
private func convertAnimatingSourceRect(_ rect: CGRect, fromView: UIView, toView: UIView?) -> CGRect {
if let presentationLayer = fromView.layer.presentation() {
@ -100,7 +102,7 @@ private final class OverlayTransitionContainerController: ViewController, Standa
}
}
public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransitionProtocol {
public final class ChatMessageTransitionNodeImpl: ASDisplayNode, ChatMessageTransitionNode, ChatMessageTransitionProtocol {
static let animationDuration: Double = 0.3
static let verticalAnimationControlPoints: (Float, Float, Float, Float) = (0.19919472913616398, 0.010644531250000006, 0.27920937042459737, 0.91025390625)
@ -235,7 +237,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
case groupedMediaInput(GroupedMediaInput)
}
final class DecorationItemNode: ASDisplayNode {
final class DecorationItemNodeImpl: ASDisplayNode, ChatMessageTransitionNode.DecorationItemNode {
let itemNode: ChatMessageItemView
let contentView: UIView
private let getContentAreaInScreenSpace: () -> CGRect
@ -288,7 +290,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
private final class AnimatingItemNode: ASDisplayNode {
let itemNode: ChatMessageItemView
private let contextSourceNode: ContextExtractedContentContainingNode
private let source: ChatMessageTransitionNode.Source
private let source: ChatMessageTransitionNodeImpl.Source
private let getContentAreaInScreenSpace: () -> CGRect
private let scrollingContainer: ASDisplayNode
@ -300,7 +302,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
var animationEnded: (() -> Void)?
var updateAfterCompletion: Bool = false
init(itemNode: ChatMessageItemView, contextSourceNode: ContextExtractedContentContainingNode, source: ChatMessageTransitionNode.Source, getContentAreaInScreenSpace: @escaping () -> CGRect) {
init(itemNode: ChatMessageItemView, contextSourceNode: ContextExtractedContentContainingNode, source: ChatMessageTransitionNodeImpl.Source, getContentAreaInScreenSpace: @escaping () -> CGRect) {
self.itemNode = itemNode
self.getContentAreaInScreenSpace = getContentAreaInScreenSpace
@ -328,7 +330,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
}
func beginAnimation() {
let verticalDuration: Double = ChatMessageTransitionNode.animationDuration
let verticalDuration: Double = ChatMessageTransitionNodeImpl.animationDuration
let horizontalDuration: Double = verticalDuration
let delay: Double = 0.0
@ -367,7 +369,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
let sourceBackgroundAbsoluteRect = initialTextInput.backgroundView.frame.offsetBy(dx: sourceRect.minX, dy: sourceRect.minY)
let sourceAbsoluteRect = CGRect(origin: CGPoint(x: sourceBackgroundAbsoluteRect.minX, y: sourceBackgroundAbsoluteRect.maxY - self.contextSourceNode.contentRect.height), size: self.contextSourceNode.contentRect.size)
let textInput = ChatMessageTransitionNode.Source.TextInput(backgroundView: initialTextInput.backgroundView, contentView: initialTextInput.contentView, sourceRect: sourceRect, scrollOffset: initialTextInput.scrollOffset)
let textInput = ChatMessageTransitionNodeImpl.Source.TextInput(backgroundView: initialTextInput.backgroundView, contentView: initialTextInput.contentView, sourceRect: sourceRect, scrollOffset: initialTextInput.scrollOffset)
textInput.backgroundView.frame = CGRect(origin: CGPoint(x: 0.0, y: sourceAbsoluteRect.height - sourceBackgroundAbsoluteRect.height), size: textInput.backgroundView.bounds.size)
textInput.contentView.frame = textInput.contentView.frame.offsetBy(dx: 0.0, dy: sourceAbsoluteRect.height - sourceBackgroundAbsoluteRect.height)
@ -390,9 +392,9 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.itemNode.cancelInsertionAnimations()
let horizontalCurve = ChatMessageTransitionNode.horizontalAnimationCurve
let horizontalCurve = ChatMessageTransitionNodeImpl.horizontalAnimationCurve
let horizontalTransition: ContainedViewLayoutTransition = .animated(duration: horizontalDuration, curve: horizontalCurve)
let verticalCurve = ChatMessageTransitionNode.verticalAnimationCurve
let verticalCurve = ChatMessageTransitionNodeImpl.verticalAnimationCurve
let verticalTransition: ContainedViewLayoutTransition = .animated(duration: verticalDuration, curve: verticalCurve)
let combinedTransition = CombinedTransition(horizontal: horizontalTransition, vertical: verticalTransition)
@ -415,9 +417,27 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
}
} else if let itemNode = self.itemNode as? ChatMessageAnimatedStickerItemNode {
itemNode.animateContentFromTextInputField(textInput: textInput, transition: combinedTransition)
itemNode.animateContentFromTextInputField(
textInput: ChatMessageAnimatedStickerItemNode.AnimationTransitionTextInput(
backgroundView: textInput.backgroundView,
contentView: textInput.contentView,
sourceRect: textInput.sourceRect,
scrollOffset: textInput.scrollOffset
),
transition: combinedTransition
)
if let sourceReplyPanel = sourceReplyPanel {
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
itemNode.animateReplyPanel(
sourceReplyPanel: ChatMessageAnimatedStickerItemNode.AnimationTransitionReplyPanel(
titleNode: sourceReplyPanel.titleNode,
textNode: sourceReplyPanel.textNode,
lineNode: sourceReplyPanel.lineNode,
imageNode: sourceReplyPanel.imageNode,
relativeSourceRect: sourceReplyPanel.relativeSourceRect,
relativeTargetRect: sourceReplyPanel.relativeTargetRect
),
transition: combinedTransition
)
}
} else if let itemNode = self.itemNode as? ChatMessageStickerItemNode {
itemNode.animateContentFromTextInputField(
@ -479,15 +499,34 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
sourceReplyPanel = ReplyPanel(titleNode: replyPanel.titleNode, textNode: replyPanel.textNode, lineNode: replyPanel.lineNode, imageNode: replyPanel.imageNode, relativeSourceRect: replySourceAbsoluteFrame, relativeTargetRect: replySourceAbsoluteFrame.offsetBy(dx: 0.0, dy: replySourceAbsoluteFrame.height))
}
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
if let itemNode = self.itemNode as? ChatMessageAnimatedStickerItemNode {
itemNode.animateContentFromStickerGridItem(stickerSource: stickerSource, transition: combinedTransition)
itemNode.animateContentFromStickerGridItem(
stickerSource: ChatMessageAnimatedStickerItemNode.AnimationTransitionSticker(
imageNode: stickerSource.imageNode,
animationNode: stickerSource.animationNode,
placeholderNode: stickerSource.placeholderNode,
imageLayer: stickerSource.imageLayer,
relativeSourceRect: stickerSource.relativeSourceRect
),
transition: combinedTransition
)
if let sourceAnimationNode = stickerSource.animationNode {
itemNode.animationNode?.setFrameIndex(sourceAnimationNode.currentFrameIndex)
}
if let sourceReplyPanel = sourceReplyPanel {
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
itemNode.animateReplyPanel(
sourceReplyPanel: ChatMessageAnimatedStickerItemNode.AnimationTransitionReplyPanel(
titleNode: sourceReplyPanel.titleNode,
textNode: sourceReplyPanel.textNode,
lineNode: sourceReplyPanel.lineNode,
imageNode: sourceReplyPanel.imageNode,
relativeSourceRect: sourceReplyPanel.relativeSourceRect,
relativeTargetRect: sourceReplyPanel.relativeTargetRect
),
transition: combinedTransition
)
}
} else if let itemNode = self.itemNode as? ChatMessageStickerItemNode {
itemNode.animateContentFromStickerGridItem(
@ -517,15 +556,15 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -self.contextSourceNode.contentRect.minX, dy: -self.contextSourceNode.contentRect.minY)
self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.endAnimation()
})
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true)
switch stickerMediaInput {
case .inputPanel, .universal:
@ -544,7 +583,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
container.isHidden = true
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
if let contextContainer = itemNode.animateFromMicInput(micInputNode: snapshotView, transition: combinedTransition) {
@ -554,7 +593,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -contextContainer.contentRect.minX, dy: -contextContainer.contentRect.minY)
contextContainer.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self, weak contextContainer, weak container] _ in
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self, weak contextContainer, weak container] _ in
guard let strongSelf = self else {
return
}
@ -569,13 +608,13 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
strongSelf.endAnimation()
})
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true)
}
}
}
}
case let .videoMessage(videoMessage):
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
if let itemNode = self.itemNode as? ChatMessageInstantVideoItemNode {
itemNode.cancelInsertionAnimations()
@ -591,9 +630,9 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
videoMessage.view.frame = videoMessage.view.frame.offsetBy(dx: targetAbsoluteRect.midX - sourceAbsoluteRect.midX, dy: targetAbsoluteRect.midY - sourceAbsoluteRect.midY)
self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -self.contextSourceNode.contentRect.minX, dy: -self.contextSourceNode.contentRect.minY)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, completion: { [weak self] _ in
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, completion: { [weak self] _ in
guard let strongSelf = self else {
return
}
@ -618,7 +657,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
let sourceBackgroundAbsoluteRect = snapshotView.frame
let sourceAbsoluteRect = CGRect(origin: CGPoint(x: sourceBackgroundAbsoluteRect.midX - self.contextSourceNode.contentRect.size.width / 2.0, y: sourceBackgroundAbsoluteRect.midY - self.contextSourceNode.contentRect.size.height / 2.0), size: self.contextSourceNode.contentRect.size)
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
itemNode.animateContentFromMediaInput(snapshotView: snapshotView, transition: combinedTransition)
@ -631,8 +670,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
guard let strongSelf = self else {
return
}
@ -647,8 +686,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
snapshotView?.removeFromSuperview()
})
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
}
}
} else {
@ -669,7 +708,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.containerNode.addSubnode(self.contextSourceNode.contentNode)
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
var targetContentRects: [CGRect] = []
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
@ -709,8 +748,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
guard let strongSelf = self else {
return
}
@ -736,8 +775,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
index += 1
}
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
}
}
}
@ -838,7 +877,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
private var currentPendingItems: [Int64: (Source, () -> Void)] = [:]
private var animatingItemNodes: [AnimatingItemNode] = []
private var decorationItemNodes: [DecorationItemNode] = []
private var decorationItemNodes: [DecorationItemNodeImpl] = []
private var messageReactionContexts: [MessageReactionContext] = []
var hasScheduledTransitions: Bool {
@ -891,8 +930,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
self.listNode.setCurrentSendAnimationCorrelationIds(correlationIds)
}
func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode {
let decorationItemNode = DecorationItemNode(itemNode: itemNode, contentView: decorationView, getContentAreaInScreenSpace: self.getContentAreaInScreenSpace)
public func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode {
let decorationItemNode = DecorationItemNodeImpl(itemNode: itemNode, contentView: decorationView, getContentAreaInScreenSpace: self.getContentAreaInScreenSpace)
decorationItemNode.updateLayout(size: self.bounds.size)
self.decorationItemNodes.append(decorationItemNode)
@ -907,10 +946,12 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
return decorationItemNode
}
func remove(decorationNode: DecorationItemNode) {
public func remove(decorationNode: DecorationItemNode) {
self.decorationItemNodes.removeAll(where: { $0 === decorationNode })
decorationNode.removeFromSupernode()
decorationNode.overlayController?.dismiss()
if let decorationNode = decorationNode as? DecorationItemNodeImpl {
decorationNode.overlayController?.dismiss()
}
}
private func beginAnimation(itemNode: ChatMessageItemView, source: Source) {
@ -961,7 +1002,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
animatingItemNode.frame = self.bounds
animatingItemNode.beginAnimation()
self.onTransitionEvent(.animated(duration: ChatMessageTransitionNode.animationDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
self.onTransitionEvent(.animated(duration: ChatMessageTransitionNodeImpl.animationDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
}
}

View File

@ -4219,7 +4219,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
return nil
}
func makeSnapshotForTransition() -> ChatMessageTransitionNode.Source.TextInput? {
func makeSnapshotForTransition() -> ChatMessageTransitionNodeImpl.Source.TextInput? {
guard let backgroundImage = self.transparentTextInputBackgroundImage else {
return nil
}
@ -4242,7 +4242,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
contentView.frame = textInputNode.frame
return ChatMessageTransitionNode.Source.TextInput(
return ChatMessageTransitionNodeImpl.Source.TextInput(
backgroundView: backgroundView,
contentView: contentView,
sourceRect: self.view.convert(self.bounds, to: nil),

View File

@ -8,6 +8,7 @@ import StickerResources
import Emoji
import UniversalMediaPlayer
import ChatMessageInteractiveMediaNode
import ChatMessageAnimatedStickerItemNode
private final class PrefetchMediaContext {
let fetchDisposable = MetaDisposable()

View File

@ -8,7 +8,7 @@ import AccountContext
import ChatControllerInteraction
import ChatHistoryEntry
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNode?, allUpdated: Bool) -> ChatHistoryViewTransition {
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNodeImpl?, allUpdated: Bool) -> ChatHistoryViewTransition {
var mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)])
let allUpdated = allUpdated || (fromView?.associatedData != toView.associatedData)
if reverse {

View File

@ -1,3 +0,0 @@
module TelegramUIPrivate {
export *
}