mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Monoforums
This commit is contained in:
@@ -133,6 +133,19 @@ class HistoryNodeContainer: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private final class PendingSwitchToChatLocation {
|
||||
let historyNode: ChatHistoryListNodeImpl
|
||||
let animationDirection: ChatControllerAnimateInnerChatSwitchDirection?
|
||||
|
||||
init(
|
||||
historyNode: ChatHistoryListNodeImpl,
|
||||
animationDirection: ChatControllerAnimateInnerChatSwitchDirection?
|
||||
) {
|
||||
self.historyNode = historyNode
|
||||
self.animationDirection = animationDirection
|
||||
}
|
||||
}
|
||||
|
||||
class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
let context: AccountContext
|
||||
private(set) var chatLocation: ChatLocation
|
||||
@@ -162,7 +175,10 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
var historyNode: ChatHistoryListNodeImpl
|
||||
var blurredHistoryNode: ASImageNode?
|
||||
let historyNodeContainer: HistoryNodeContainer
|
||||
let loadingNode: ChatLoadingNode
|
||||
private(set) var loadingNode: ChatLoadingNode
|
||||
|
||||
private var isLoadingValue: Bool = false
|
||||
private var isLoadingEarlier: Bool = false
|
||||
private(set) var loadingPlaceholderNode: ChatLoadingPlaceholderNode?
|
||||
|
||||
var alwaysShowSearchResultsAsList: Bool = false
|
||||
@@ -316,8 +332,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
|
||||
let adMessagesContext: AdMessagesHistoryContext?
|
||||
|
||||
private var isLoadingValue: Bool = false
|
||||
private var isLoadingEarlier: Bool = false
|
||||
private var pendingSwitchToChatLocation: PendingSwitchToChatLocation?
|
||||
|
||||
private func updateIsLoading(isLoading: Bool, earlier: Bool, animated: Bool) {
|
||||
var useLoadingPlaceholder = self.chatLocation.peerId?.namespace != Namespaces.Peer.CloudUser && self.chatLocation.peerId?.namespace != Namespaces.Peer.SecretChat
|
||||
if case let .replyThread(message) = self.chatLocation, message.peerId == self.context.account.peerId {
|
||||
@@ -351,10 +367,11 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
|
||||
loadingPlaceholderNode.setup(self.historyNode, updating: false)
|
||||
|
||||
if let (layout, navigationHeight) = self.validLayout {
|
||||
self.containerLayoutUpdated(layout, navigationBarHeight: navigationHeight, transition: .immediate, listViewTransaction: { _, _, _, _ in
|
||||
}, updateExtraNavigationBarBackgroundHeight: { _, _, _, _ in
|
||||
})
|
||||
let contentBounds = self.loadingNode.frame
|
||||
loadingPlaceholderNode.frame = contentBounds
|
||||
if let loadingPlaceholderNode = self.loadingPlaceholderNode, let validLayout = self.validLayout {
|
||||
loadingPlaceholderNode.updateLayout(size: contentBounds.size, insets: self.visibleAreaInset, metrics: validLayout.0.metrics, transition: .immediate)
|
||||
loadingPlaceholderNode.update(rect: contentBounds, within: contentBounds.size, transition: .immediate)
|
||||
}
|
||||
}
|
||||
loadingPlaceholderNode.alpha = 1.0
|
||||
@@ -371,12 +388,17 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
} else {
|
||||
if useLoadingPlaceholder {
|
||||
if let loadingPlaceholderNode = self.loadingPlaceholderNode {
|
||||
loadingPlaceholderNode.animateOut(self.historyNode, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.loadingPlaceholderNode?.removeFromSupernode()
|
||||
strongSelf.loadingPlaceholderNode = nil
|
||||
}
|
||||
})
|
||||
if animated {
|
||||
loadingPlaceholderNode.animateOut(self.historyNode, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.loadingPlaceholderNode?.removeFromSupernode()
|
||||
strongSelf.loadingPlaceholderNode = nil
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.loadingPlaceholderNode = nil
|
||||
loadingPlaceholderNode.removeFromSupernode()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.loadingNode.alpha = 0.0
|
||||
@@ -1803,18 +1825,6 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
wrappingInsets.top += statusBarHeight
|
||||
}
|
||||
}
|
||||
|
||||
var isSelectionEnabled = true
|
||||
if previewing {
|
||||
isSelectionEnabled = false
|
||||
} else if case .pinnedMessages = self.chatPresentationInterfaceState.subject {
|
||||
isSelectionEnabled = false
|
||||
} else if self.chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState != nil {
|
||||
isSelectionEnabled = false
|
||||
} else if case .customChatContents = self.chatLocation {
|
||||
isSelectionEnabled = false
|
||||
}
|
||||
self.historyNode.isSelectionGestureEnabled = isSelectionEnabled
|
||||
|
||||
transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 200.0)))
|
||||
self.titleAccessoryPanelContainer.hitTestExcludeInsets = UIEdgeInsets(top: 0.0, left: leftPanelSize?.width ?? 0.0, bottom: 0.0, right: 0.0)
|
||||
@@ -1908,13 +1918,154 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
transition.updateBounds(node: self.historyNodeContainer, bounds: contentBounds)
|
||||
transition.updatePosition(node: self.historyNodeContainer, position: contentBounds.center)
|
||||
|
||||
transition.updateBounds(node: self.historyNode, bounds: CGRect(origin: CGPoint(), size: contentBounds.size))
|
||||
transition.updatePosition(node: self.historyNode, position: CGPoint(x: contentBounds.size.width / 2.0, y: contentBounds.size.height / 2.0))
|
||||
if let pendingSwitchToChatLocation = self.pendingSwitchToChatLocation {
|
||||
self.pendingSwitchToChatLocation = nil
|
||||
|
||||
let previousHistoryNode = self.historyNode
|
||||
self.historyNode = pendingSwitchToChatLocation.historyNode
|
||||
|
||||
self.historyNode.position = previousHistoryNode.position
|
||||
self.historyNode.bounds = previousHistoryNode.bounds
|
||||
self.historyNode.transform = previousHistoryNode.transform
|
||||
|
||||
self.historyNode.messageTransitionNode = { [weak self] in
|
||||
guard let self else {
|
||||
return nil
|
||||
}
|
||||
return self.messageTransitionNode
|
||||
}
|
||||
|
||||
transition.updateBounds(node: self.historyNode, bounds: CGRect(origin: CGPoint(), size: contentBounds.size))
|
||||
transition.updatePosition(node: self.historyNode, position: CGPoint(x: contentBounds.size.width / 2.0, y: contentBounds.size.height / 2.0))
|
||||
|
||||
previousHistoryNode.supernode?.insertSubnode(self.historyNode, aboveSubnode: previousHistoryNode)
|
||||
|
||||
let messageTransitionNode = ChatMessageTransitionNodeImpl(listNode: self.historyNode, getContentAreaInScreenSpace: { [weak self] in
|
||||
guard let self else {
|
||||
return CGRect()
|
||||
}
|
||||
return self.view.convert(self.frameForVisibleArea(), to: nil)
|
||||
}, onTransitionEvent: { [weak self] transition in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if (self.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion {
|
||||
return
|
||||
}
|
||||
if self.context.sharedContext.energyUsageSettings.fullTranslucency {
|
||||
self.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
|
||||
}
|
||||
})
|
||||
|
||||
let previousMessageTransitionNode = self.messageTransitionNode
|
||||
self.messageTransitionNode = messageTransitionNode
|
||||
|
||||
messageTransitionNode.position = previousMessageTransitionNode.position
|
||||
messageTransitionNode.bounds = previousMessageTransitionNode.bounds
|
||||
messageTransitionNode.transform = previousMessageTransitionNode.transform
|
||||
|
||||
self.wrappingNode.contentNode.insertSubnode(self.messageTransitionNode, aboveSubnode: previousMessageTransitionNode)
|
||||
|
||||
self.emptyType = nil
|
||||
self.isLoadingValue = false
|
||||
self.isLoadingEarlier = false
|
||||
|
||||
let previousLoadingNode = self.loadingNode
|
||||
self.loadingNode = ChatLoadingNode(context: self.context, theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper, bubbleCorners: self.chatPresentationInterfaceState.bubbleCorners)
|
||||
self.loadingNode.frame = previousLoadingNode.frame
|
||||
self.loadingNode.isHidden = previousLoadingNode.isHidden
|
||||
self.loadingNode.alpha = previousLoadingNode.alpha
|
||||
previousLoadingNode.supernode?.insertSubnode(self.loadingNode, aboveSubnode: previousLoadingNode)
|
||||
|
||||
let previousLoadingPlaceholderNode = self.loadingPlaceholderNode
|
||||
self.loadingPlaceholderNode = nil
|
||||
|
||||
let previousEmptyNode = self.emptyNode
|
||||
self.emptyNode = nil
|
||||
|
||||
self.setupHistoryNode()
|
||||
self.historyNode.loadStateUpdated?(self.historyNode.loadState ?? .messages, false)
|
||||
|
||||
if let animationDirection = pendingSwitchToChatLocation.animationDirection {
|
||||
var offsetMultiplier = CGPoint()
|
||||
switch animationDirection {
|
||||
case .up:
|
||||
offsetMultiplier.y = -1.0
|
||||
case .down:
|
||||
offsetMultiplier.y = 1.0
|
||||
case .left:
|
||||
offsetMultiplier.x = -1.0
|
||||
case .right:
|
||||
offsetMultiplier.x = 1.0
|
||||
}
|
||||
|
||||
previousHistoryNode.clipsToBounds = true
|
||||
self.historyNode.clipsToBounds = true
|
||||
|
||||
transition.animatePosition(layer: self.historyNode.layer, from: CGPoint(x: offsetMultiplier.x * layout.size.width, y: offsetMultiplier.y * layout.size.height), to: CGPoint(), removeOnCompletion: true, additive: true, completion: { [weak self] _ in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.historyNode.clipsToBounds = false
|
||||
})
|
||||
transition.animatePosition(layer: previousHistoryNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier.x * layout.size.width, y: -offsetMultiplier.y * layout.size.height), removeOnCompletion: false, additive: true, completion: { [weak previousHistoryNode] _ in
|
||||
previousHistoryNode?.removeFromSupernode()
|
||||
})
|
||||
|
||||
transition.animatePosition(layer: self.messageTransitionNode.layer, from: CGPoint(x: offsetMultiplier.x * layout.size.width, y: offsetMultiplier.y * layout.size.height), to: CGPoint(), removeOnCompletion: true, additive: true)
|
||||
transition.animatePosition(layer: previousMessageTransitionNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier.x * layout.size.width, y: -offsetMultiplier.y * layout.size.height), removeOnCompletion: false, additive: true, completion: { [weak previousMessageTransitionNode] _ in
|
||||
previousMessageTransitionNode?.removeFromSupernode()
|
||||
})
|
||||
|
||||
transition.animatePosition(layer: self.loadingNode.layer, from: CGPoint(x: offsetMultiplier.x * layout.size.width, y: offsetMultiplier.y * layout.size.height), to: CGPoint(), removeOnCompletion: true, additive: true)
|
||||
transition.animatePosition(layer: previousLoadingNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier.x * layout.size.width, y: -offsetMultiplier.y * layout.size.height), removeOnCompletion: false, additive: true, completion: { [weak previousLoadingNode] _ in
|
||||
previousLoadingNode?.removeFromSupernode()
|
||||
})
|
||||
|
||||
if let loadingPlaceholderNode = self.loadingPlaceholderNode {
|
||||
transition.animatePosition(layer: loadingPlaceholderNode.layer, from: CGPoint(x: offsetMultiplier.x * layout.size.width, y: offsetMultiplier.y * layout.size.height), to: CGPoint(), removeOnCompletion: true, additive: true)
|
||||
}
|
||||
if let previousLoadingPlaceholderNode {
|
||||
transition.animatePosition(layer: previousLoadingPlaceholderNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier.x * layout.size.width, y: -offsetMultiplier.y * layout.size.height), removeOnCompletion: false, additive: true, completion: { [weak previousLoadingPlaceholderNode] _ in
|
||||
previousLoadingPlaceholderNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
|
||||
if let emptyNode = self.emptyNode {
|
||||
transition.animatePosition(layer: emptyNode.layer, from: CGPoint(x: offsetMultiplier.x * layout.size.width, y: offsetMultiplier.y * layout.size.height), to: CGPoint(), removeOnCompletion: true, additive: true)
|
||||
}
|
||||
if let previousEmptyNode {
|
||||
transition.animatePosition(layer: previousEmptyNode.layer, from: CGPoint(), to: CGPoint(x: -offsetMultiplier.x * layout.size.width, y: -offsetMultiplier.y * layout.size.height), removeOnCompletion: false, additive: true, completion: { [weak previousEmptyNode] _ in
|
||||
previousEmptyNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
previousHistoryNode.removeFromSupernode()
|
||||
previousMessageTransitionNode.removeFromSupernode()
|
||||
previousLoadingNode.removeFromSupernode()
|
||||
previousLoadingPlaceholderNode?.removeFromSupernode()
|
||||
previousEmptyNode?.removeFromSupernode()
|
||||
}
|
||||
} else {
|
||||
transition.updateBounds(node: self.historyNode, bounds: CGRect(origin: CGPoint(), size: contentBounds.size))
|
||||
transition.updatePosition(node: self.historyNode, position: CGPoint(x: contentBounds.size.width / 2.0, y: contentBounds.size.height / 2.0))
|
||||
}
|
||||
|
||||
if let blurredHistoryNode = self.blurredHistoryNode {
|
||||
transition.updateFrame(node: blurredHistoryNode, frame: contentBounds)
|
||||
}
|
||||
|
||||
//transition.updateFrame(node: self.historyScrollingArea, frame: contentBounds)
|
||||
|
||||
var isSelectionEnabled = true
|
||||
if previewing {
|
||||
isSelectionEnabled = false
|
||||
} else if case .pinnedMessages = self.chatPresentationInterfaceState.subject {
|
||||
isSelectionEnabled = false
|
||||
} else if self.chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState != nil {
|
||||
isSelectionEnabled = false
|
||||
} else if case .customChatContents = self.chatLocation {
|
||||
isSelectionEnabled = false
|
||||
}
|
||||
self.historyNode.isSelectionGestureEnabled = isSelectionEnabled
|
||||
|
||||
transition.updateFrame(node: self.loadingNode, frame: contentBounds)
|
||||
if let loadingPlaceholderNode = self.loadingPlaceholderNode {
|
||||
@@ -5078,9 +5229,27 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
return nil
|
||||
}
|
||||
)
|
||||
|
||||
historyNode.position = self.historyNode.position
|
||||
historyNode.bounds = self.historyNode.bounds
|
||||
historyNode.transform = self.historyNode.transform
|
||||
|
||||
if let currentListViewLayout = self.currentListViewLayout {
|
||||
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: currentListViewLayout.size, insets: currentListViewLayout.insets, scrollIndicatorInsets: currentListViewLayout.scrollIndicatorInsets, duration: 0.0, curve: .Default(duration: nil), ensureTopInsetForOverlayHighlightedItems: nil, customAnimationTransition: nil)
|
||||
historyNode.updateLayout(transition: .immediate, updateSizeAndInsets: updateSizeAndInsets, additionalScrollDistance: 0.0, scrollToTop: false, completion: {})
|
||||
}
|
||||
|
||||
return historyNode
|
||||
}
|
||||
|
||||
func prepareSwitchToChatLocation(historyNode: ChatHistoryListNodeImpl, animationDirection: ChatControllerAnimateInnerChatSwitchDirection?) {
|
||||
self.chatLocation = historyNode.chatLocation
|
||||
self.pendingSwitchToChatLocation = PendingSwitchToChatLocation(
|
||||
historyNode: historyNode,
|
||||
animationDirection: animationDirection
|
||||
)
|
||||
}
|
||||
|
||||
func updateChatLocation(chatLocation: ChatLocation, transition: ContainedViewLayoutTransition, tabSwitchDirection: ChatControllerAnimateInnerChatSwitchDirection?) {
|
||||
if chatLocation == self.chatLocation {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user