mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
[WIP] Inline forum improvements
This commit is contained in:
parent
0afe69c627
commit
c36e158519
@ -746,7 +746,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
if strongSelf.navigationItem.leftBarButtonItem?.accessibilityLabel != leftBarButtonItem.accessibilityLabel {
|
if strongSelf.navigationItem.leftBarButtonItem?.accessibilityLabel != leftBarButtonItem.accessibilityLabel {
|
||||||
strongSelf.navigationItem.setLeftBarButton(leftBarButtonItem, animated: true)
|
strongSelf.navigationItem.setLeftBarButton(leftBarButtonItem, animated: true)
|
||||||
}
|
}
|
||||||
} else if strongSelf.chatListDisplayNode.inlineStackContainerNode != nil {
|
} else if strongSelf.chatListDisplayNode.inlineStackContainerTransitionFraction != 0.0 {
|
||||||
} else {
|
} else {
|
||||||
let editItem: UIBarButtonItem
|
let editItem: UIBarButtonItem
|
||||||
if stateAndFilterId.state.editing {
|
if stateAndFilterId.state.editing {
|
||||||
@ -1280,7 +1280,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
editItem = self.moreBarButtonItem
|
editItem = self.moreBarButtonItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.chatListDisplayNode.inlineStackContainerNode != nil {
|
if self.chatListDisplayNode.inlineStackContainerTransitionFraction != 0.0 {
|
||||||
self.backNavigationItem?.title = self.presentationData.strings.Common_Back
|
self.backNavigationItem?.title = self.presentationData.strings.Common_Back
|
||||||
} else if case .chatList(.root) = self.location {
|
} else if case .chatList(.root) = self.location {
|
||||||
self.navigationItem.leftBarButtonItem = editItem
|
self.navigationItem.leftBarButtonItem = editItem
|
||||||
@ -2483,6 +2483,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.navigationBar?.secondaryContentNodeDisplayFraction = 1.0 - self.chatListDisplayNode.inlineStackContainerTransitionFraction
|
||||||
|
|
||||||
|
if let inlineStackContainerNode = self.chatListDisplayNode.inlineStackContainerNode {
|
||||||
|
let _ = inlineStackContainerNode
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
super.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
|
||||||
let wasInVoiceOver = self.validLayout?.inVoiceOver ?? false
|
let wasInVoiceOver = self.validLayout?.inVoiceOver ?? false
|
||||||
@ -2503,9 +2510,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
tabContainerOffset += layout.statusBarHeight ?? 0.0
|
tabContainerOffset += layout.statusBarHeight ?? 0.0
|
||||||
tabContainerOffset += 44.0 + 20.0
|
tabContainerOffset += 44.0 + 20.0
|
||||||
}
|
}
|
||||||
|
tabContainerOffset += self.chatListDisplayNode.inlineStackContainerTransitionFraction * NavigationBar.defaultSecondaryContentHeight
|
||||||
|
|
||||||
let navigationBarHeight = self.navigationBar?.frame.maxY ?? 0.0
|
let navigationBarHeight = self.navigationBar?.frame.maxY ?? 0.0
|
||||||
|
|
||||||
|
transition.updateAlpha(node: self.tabContainerNode, alpha: 1.0 - self.chatListDisplayNode.inlineStackContainerTransitionFraction)
|
||||||
|
|
||||||
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight - self.additionalNavigationBarHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
|
transition.updateFrame(node: self.tabContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight - self.additionalNavigationBarHeight - 46.0 + tabContainerOffset), size: CGSize(width: layout.size.width, height: 46.0)))
|
||||||
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, filtersLimit: self.tabContainerData?.2, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
self.tabContainerNode.update(size: CGSize(width: layout.size.width, height: 46.0), sideInset: layout.safeInsets.left, filters: self.tabContainerData?.0 ?? [], selectedFilter: self.chatListDisplayNode.containerNode.currentItemFilter, isReordering: self.chatListDisplayNode.isReorderingFilters || (self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing && !self.chatListDisplayNode.didBeginSelectingChatsWhileEditing), isEditing: self.chatListDisplayNode.containerNode.currentItemNode.currentState.editing, canReorderAllChats: self.isPremium, filtersLimit: self.tabContainerData?.2, transitionFraction: self.chatListDisplayNode.containerNode.transitionFraction, presentationData: self.presentationData, transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
|
|||||||
private var shimmerNodeOffset: CGFloat = 0.0
|
private var shimmerNodeOffset: CGFloat = 0.0
|
||||||
let listNode: ChatListNode
|
let listNode: ChatListNode
|
||||||
|
|
||||||
private var validLayout: (CGSize, UIEdgeInsets, CGFloat, ChatListControllerLocation?)?
|
private var validLayout: (CGSize, UIEdgeInsets, CGFloat, CGFloat, ChatListControllerLocation?, CGFloat)?
|
||||||
|
|
||||||
init(context: AccountContext, location: ChatListControllerLocation, filter: ChatListFilter?, previewing: Bool, isInlineMode: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, becameEmpty: @escaping (ChatListFilter?) -> Void, emptyAction: @escaping (ChatListFilter?) -> Void, secondaryEmptyAction: @escaping () -> Void) {
|
init(context: AccountContext, location: ChatListControllerLocation, filter: ChatListFilter?, previewing: Bool, isInlineMode: Bool, controlsHistoryPreload: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, becameEmpty: @escaping (ChatListFilter?) -> Void, emptyAction: @escaping (ChatListFilter?) -> Void, secondaryEmptyAction: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@ -375,7 +375,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
|
|||||||
})
|
})
|
||||||
strongSelf.emptyNode = emptyNode
|
strongSelf.emptyNode = emptyNode
|
||||||
strongSelf.addSubnode(emptyNode)
|
strongSelf.addSubnode(emptyNode)
|
||||||
if let (size, insets, _, _) = strongSelf.validLayout {
|
if let (size, insets, _, _, _, _) = strongSelf.validLayout {
|
||||||
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: size.width, height: size.height - insets.top - insets.bottom))
|
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: size.width, height: size.height - insets.top - insets.bottom))
|
||||||
emptyNode.frame = emptyNodeFrame
|
emptyNode.frame = emptyNodeFrame
|
||||||
emptyNode.updateLayout(size: emptyNodeFrame.size, transition: .immediate)
|
emptyNode.updateLayout(size: emptyNodeFrame.size, transition: .immediate)
|
||||||
@ -401,7 +401,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
|
|||||||
let emptyShimmerEffectNode = ChatListShimmerNode()
|
let emptyShimmerEffectNode = ChatListShimmerNode()
|
||||||
strongSelf.emptyShimmerEffectNode = emptyShimmerEffectNode
|
strongSelf.emptyShimmerEffectNode = emptyShimmerEffectNode
|
||||||
strongSelf.insertSubnode(emptyShimmerEffectNode, belowSubnode: strongSelf.listNode)
|
strongSelf.insertSubnode(emptyShimmerEffectNode, belowSubnode: strongSelf.listNode)
|
||||||
if let (size, insets, _, _) = strongSelf.validLayout, let offset = strongSelf.floatingHeaderOffset {
|
if let (size, insets, _, _, _, _) = strongSelf.validLayout, let offset = strongSelf.floatingHeaderOffset {
|
||||||
strongSelf.layoutEmptyShimmerEffectNode(node: emptyShimmerEffectNode, size: size, insets: insets, verticalOffset: offset + strongSelf.shimmerNodeOffset, transition: .immediate)
|
strongSelf.layoutEmptyShimmerEffectNode(node: emptyShimmerEffectNode, size: size, insets: insets, verticalOffset: offset + strongSelf.shimmerNodeOffset, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,7 +421,7 @@ private final class ChatListContainerItemNode: ASDisplayNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.floatingHeaderOffset = offset
|
strongSelf.floatingHeaderOffset = offset
|
||||||
if let (size, insets, _, _) = strongSelf.validLayout, let emptyShimmerEffectNode = strongSelf.emptyShimmerEffectNode {
|
if let (size, insets, _, _, _, _) = strongSelf.validLayout, let emptyShimmerEffectNode = strongSelf.emptyShimmerEffectNode {
|
||||||
strongSelf.layoutEmptyShimmerEffectNode(node: emptyShimmerEffectNode, size: size, insets: insets, verticalOffset: offset + strongSelf.shimmerNodeOffset, transition: transition)
|
strongSelf.layoutEmptyShimmerEffectNode(node: emptyShimmerEffectNode, size: size, insets: insets, verticalOffset: offset + strongSelf.shimmerNodeOffset, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,14 +444,14 @@ private final class ChatListContainerItemNode: ASDisplayNode {
|
|||||||
self.emptyNode?.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings)
|
self.emptyNode?.updateThemeAndStrings(theme: presentationData.theme, strings: presentationData.strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, insets: UIEdgeInsets, visualNavigationHeight: CGFloat, inlineNavigationLocation: ChatListControllerLocation?, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, insets: UIEdgeInsets, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
self.validLayout = (size, insets, visualNavigationHeight, inlineNavigationLocation)
|
self.validLayout = (size, insets, visualNavigationHeight, originalNavigationHeight, inlineNavigationLocation, inlineNavigationTransitionFraction)
|
||||||
|
|
||||||
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
||||||
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: size, insets: insets, duration: duration, curve: curve)
|
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: size, insets: insets, duration: duration, curve: curve)
|
||||||
|
|
||||||
transition.updateFrame(node: self.listNode, frame: CGRect(origin: CGPoint(), size: size))
|
transition.updateFrame(node: self.listNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
self.listNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: visualNavigationHeight, inlineNavigationLocation: inlineNavigationLocation)
|
self.listNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: visualNavigationHeight, originalTopInset: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction)
|
||||||
|
|
||||||
if let emptyNode = self.emptyNode {
|
if let emptyNode = self.emptyNode {
|
||||||
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: size.width, height: size.height - insets.top - insets.bottom))
|
let emptyNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: size.width, height: size.height - insets.top - insets.bottom))
|
||||||
@ -487,7 +487,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
private(set) var transitionFraction: CGFloat = 0.0
|
private(set) var transitionFraction: CGFloat = 0.0
|
||||||
private var transitionFractionOffset: CGFloat = 0.0
|
private var transitionFractionOffset: CGFloat = 0.0
|
||||||
private var disableItemNodeOperationsWhileAnimating: Bool = false
|
private var disableItemNodeOperationsWhileAnimating: Bool = false
|
||||||
private var validLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?)?
|
private var validLayout: (layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat)?
|
||||||
|
|
||||||
private var enableAdjacentFilterLoading: Bool = false
|
private var enableAdjacentFilterLoading: Bool = false
|
||||||
|
|
||||||
@ -744,7 +744,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
self.onFilterSwitch?()
|
self.onFilterSwitch?()
|
||||||
|
|
||||||
self.transitionFractionOffset = 0.0
|
self.transitionFractionOffset = 0.0
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout, let itemNode = self.itemNodes[self.selectedId] {
|
if let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout, let itemNode = self.itemNodes[self.selectedId] {
|
||||||
for (id, itemNode) in self.itemNodes {
|
for (id, itemNode) in self.itemNodes {
|
||||||
if id != selectedId {
|
if id != selectedId {
|
||||||
itemNode.emptyNode?.restartAnimation()
|
itemNode.emptyNode?.restartAnimation()
|
||||||
@ -757,13 +757,13 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
for (_, itemNode) in self.itemNodes {
|
for (_, itemNode) in self.itemNodes {
|
||||||
itemNode.layer.removeAllAnimations()
|
itemNode.layer.removeAllAnimations()
|
||||||
}
|
}
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, .immediate, true)
|
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, .immediate, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .changed:
|
case .changed:
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout, let selectedIndex = self.availableFilters.firstIndex(where: { $0.id == self.selectedId }) {
|
if let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout, let selectedIndex = self.availableFilters.firstIndex(where: { $0.id == self.selectedId }) {
|
||||||
let translation = recognizer.translation(in: self.view)
|
let translation = recognizer.translation(in: self.view)
|
||||||
var transitionFraction = translation.x / layout.size.width
|
var transitionFraction = translation.x / layout.size.width
|
||||||
|
|
||||||
@ -800,11 +800,11 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, .immediate, false)
|
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, .immediate, false)
|
||||||
}
|
}
|
||||||
case .cancelled, .ended:
|
case .cancelled, .ended:
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout, let selectedIndex = self.availableFilters.firstIndex(where: { $0.id == self.selectedId }) {
|
if let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout, let selectedIndex = self.availableFilters.firstIndex(where: { $0.id == self.selectedId }) {
|
||||||
let translation = recognizer.translation(in: self.view)
|
let translation = recognizer.translation(in: self.view)
|
||||||
let velocity = recognizer.velocity(in: self.view)
|
let velocity = recognizer.velocity(in: self.view)
|
||||||
var directionIsToRight: Bool?
|
var directionIsToRight: Bool?
|
||||||
@ -843,12 +843,12 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
self.transitionFraction = 0.0
|
self.transitionFraction = 0.0
|
||||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.45, curve: .spring)
|
let transition: ContainedViewLayoutTransition = .animated(duration: 0.45, curve: .spring)
|
||||||
self.disableItemNodeOperationsWhileAnimating = true
|
self.disableItemNodeOperationsWhileAnimating = true
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: transition)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: transition)
|
||||||
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, transition, false)
|
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, transition, false)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.disableItemNodeOperationsWhileAnimating = false
|
self.disableItemNodeOperationsWhileAnimating = false
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout {
|
if let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout {
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -864,7 +864,13 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
func updatePresentationData(_ presentationData: PresentationData) {
|
func updatePresentationData(_ presentationData: PresentationData) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
|
|
||||||
self.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
if let validLayout = self.validLayout {
|
||||||
|
if let _ = validLayout.inlineNavigationLocation {
|
||||||
|
self.backgroundColor = self.presentationData.theme.chatList.backgroundColor.mixedWith(self.presentationData.theme.chatList.pinnedItemBackgroundColor, alpha: validLayout.inlineNavigationTransitionFraction)
|
||||||
|
} else {
|
||||||
|
self.backgroundColor = self.presentationData.theme.chatList.backgroundColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.leftSeparatorLayer.backgroundColor = self.presentationData.theme.rootController.navigationBar.separatorColor.cgColor
|
self.leftSeparatorLayer.backgroundColor = self.presentationData.theme.rootController.navigationBar.separatorColor.cgColor
|
||||||
|
|
||||||
@ -922,8 +928,8 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
strongSelf.availableFilters = availableFilters
|
strongSelf.availableFilters = availableFilters
|
||||||
strongSelf.filtersLimit = limit
|
strongSelf.filtersLimit = limit
|
||||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = strongSelf.validLayout {
|
if let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = strongSelf.validLayout {
|
||||||
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !availableFilters.contains(where: { $0.id == self.selectedId }) {
|
if !availableFilters.contains(where: { $0.id == self.selectedId }) {
|
||||||
@ -940,8 +946,8 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
if value != self.enableAdjacentFilterLoading {
|
if value != self.enableAdjacentFilterLoading {
|
||||||
self.enableAdjacentFilterLoading = value
|
self.enableAdjacentFilterLoading = value
|
||||||
|
|
||||||
if self.enableAdjacentFilterLoading, let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout {
|
if self.enableAdjacentFilterLoading, let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout {
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -950,7 +956,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
self.onFilterSwitch?()
|
self.onFilterSwitch?()
|
||||||
if id != self.selectedId, let index = self.availableFilters.firstIndex(where: { $0.id == id }) {
|
if id != self.selectedId, let index = self.availableFilters.firstIndex(where: { $0.id == id }) {
|
||||||
if let itemNode = self.itemNodes[id] {
|
if let itemNode = self.itemNodes[id] {
|
||||||
guard let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = self.validLayout else {
|
guard let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = self.validLayout else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.selectedId = id
|
self.selectedId = id
|
||||||
@ -959,7 +965,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
self.applyItemNodeAsCurrent(id: id, itemNode: itemNode)
|
self.applyItemNodeAsCurrent(id: id, itemNode: itemNode)
|
||||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
||||||
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: transition)
|
self.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: transition)
|
||||||
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, transition, false)
|
self.currentItemFilterUpdated?(self.currentItemFilter, self.transitionFraction, transition, false)
|
||||||
itemNode.emptyNode?.restartAnimation()
|
itemNode.emptyNode?.restartAnimation()
|
||||||
completion?()
|
completion?()
|
||||||
@ -989,7 +995,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
strongSelf.pendingItemNode = nil
|
strongSelf.pendingItemNode = nil
|
||||||
|
|
||||||
guard let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation) = strongSelf.validLayout else {
|
guard let (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction) = strongSelf.validLayout else {
|
||||||
strongSelf.itemNodes[id] = itemNode
|
strongSelf.itemNodes[id] = itemNode
|
||||||
strongSelf.addSubnode(itemNode)
|
strongSelf.addSubnode(itemNode)
|
||||||
|
|
||||||
@ -1038,7 +1044,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: -offset, y: 0.0))
|
transition.animatePositionAdditive(node: itemNode, offset: CGPoint(x: -offset, y: 0.0))
|
||||||
|
|
||||||
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
|
|
||||||
strongSelf.selectedId = id
|
strongSelf.selectedId = id
|
||||||
if let currentItemNode = strongSelf.currentItemNodeValue {
|
if let currentItemNode = strongSelf.currentItemNodeValue {
|
||||||
@ -1046,7 +1052,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
strongSelf.applyItemNodeAsCurrent(id: id, itemNode: itemNode)
|
strongSelf.applyItemNodeAsCurrent(id: id, itemNode: itemNode)
|
||||||
|
|
||||||
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, transition: .immediate)
|
strongSelf.update(layout: layout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: insets, isReorderingFilters: isReorderingFilters, isEditing: isEditing, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: .immediate)
|
||||||
|
|
||||||
strongSelf.currentItemFilterUpdated?(strongSelf.currentItemFilter, strongSelf.transitionFraction, transition, false)
|
strongSelf.currentItemFilterUpdated?(strongSelf.currentItemFilter, strongSelf.transitionFraction, transition, false)
|
||||||
}
|
}
|
||||||
@ -1057,14 +1063,20 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, transition: ContainedViewLayoutTransition) {
|
func update(layout: ContainerViewLayout, navigationBarHeight: CGFloat, visualNavigationHeight: CGFloat, originalNavigationHeight: CGFloat, cleanNavigationBarHeight: CGFloat, insets: UIEdgeInsets, isReorderingFilters: Bool, isEditing: Bool, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
self.validLayout = (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation)
|
self.validLayout = (layout, navigationBarHeight, visualNavigationHeight, originalNavigationHeight, cleanNavigationBarHeight, insets, isReorderingFilters, isEditing, inlineNavigationLocation, inlineNavigationTransitionFraction)
|
||||||
|
|
||||||
self._validLayoutReady.set(.single(true))
|
self._validLayoutReady.set(.single(true))
|
||||||
|
|
||||||
transition.updateAlpha(node: self, alpha: isReorderingFilters ? 0.5 : 1.0)
|
transition.updateAlpha(node: self, alpha: isReorderingFilters ? 0.5 : 1.0)
|
||||||
self.isUserInteractionEnabled = !isReorderingFilters
|
self.isUserInteractionEnabled = !isReorderingFilters
|
||||||
|
|
||||||
|
if let _ = inlineNavigationLocation {
|
||||||
|
transition.updateBackgroundColor(node: self, color: self.presentationData.theme.chatList.backgroundColor.mixedWith(self.presentationData.theme.chatList.pinnedItemBackgroundColor, alpha: inlineNavigationTransitionFraction))
|
||||||
|
} else {
|
||||||
|
transition.updateBackgroundColor(node: self, color: self.presentationData.theme.chatList.backgroundColor)
|
||||||
|
}
|
||||||
|
|
||||||
self.panRecognizer?.isEnabled = !isEditing
|
self.panRecognizer?.isEnabled = !isEditing
|
||||||
|
|
||||||
transition.updateFrame(layer: self.leftSeparatorLayer, frame: CGRect(origin: CGPoint(x: -UIScreenPixel, y: 0.0), size: CGSize(width: UIScreenPixel, height: layout.size.height)))
|
transition.updateFrame(layer: self.leftSeparatorLayer, frame: CGRect(origin: CGPoint(x: -UIScreenPixel, y: 0.0), size: CGSize(width: UIScreenPixel, height: layout.size.height)))
|
||||||
@ -1113,7 +1125,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
nodeTransition.updateFrame(node: itemNode, frame: itemFrame, completion: { _ in
|
nodeTransition.updateFrame(node: itemNode, frame: itemFrame, completion: { _ in
|
||||||
})
|
})
|
||||||
|
|
||||||
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, transition: nodeTransition)
|
itemNode.updateLayout(size: layout.size, insets: insets, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: originalNavigationHeight, inlineNavigationLocation: inlineNavigationLocation, inlineNavigationTransitionFraction: inlineNavigationTransitionFraction, transition: nodeTransition)
|
||||||
|
|
||||||
if wasAdded, case .animated = transition {
|
if wasAdded, case .animated = transition {
|
||||||
animateSlidingIds.append(id)
|
animateSlidingIds.append(id)
|
||||||
@ -1138,7 +1150,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ChatListControllerNode: ASDisplayNode {
|
final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let location: ChatListControllerLocation
|
private let location: ChatListControllerLocation
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
@ -1146,7 +1158,11 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
private let animationRenderer: MultiAnimationRenderer
|
private let animationRenderer: MultiAnimationRenderer
|
||||||
|
|
||||||
let containerNode: ChatListContainerNode
|
let containerNode: ChatListContainerNode
|
||||||
|
|
||||||
|
private(set) var inlineStackContainerTransitionFraction: CGFloat = 0.0
|
||||||
private(set) var inlineStackContainerNode: ChatListContainerNode?
|
private(set) var inlineStackContainerNode: ChatListContainerNode?
|
||||||
|
private var inlineContentPanRecognizer: InteractiveTransitionGestureRecognizer?
|
||||||
|
|
||||||
private var tapRecognizer: UITapGestureRecognizer?
|
private var tapRecognizer: UITapGestureRecognizer?
|
||||||
var navigationBar: NavigationBar?
|
var navigationBar: NavigationBar?
|
||||||
weak var controller: ChatListControllerImpl?
|
weak var controller: ChatListControllerImpl?
|
||||||
@ -1247,6 +1263,19 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
strongSelf.controller?.dismissAllUndoControllers()
|
strongSelf.controller?.dismissAllUndoControllers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inlineContentPanRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.inlineContentPanGesture(_:)), allowedDirections: { [weak self] _ in
|
||||||
|
guard let strongSelf = self, strongSelf.inlineStackContainerNode != nil else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
let directions: InteractiveTransitionGestureRecognizerDirections = [.leftCenter, .rightCenter]
|
||||||
|
return directions
|
||||||
|
}, edgeWidth: .widthMultiplier(factor: 1.0 / 6.0, min: 22.0, max: 80.0))
|
||||||
|
inlineContentPanRecognizer.delegate = self
|
||||||
|
inlineContentPanRecognizer.delaysTouchesBegan = false
|
||||||
|
inlineContentPanRecognizer.cancelsTouchesInView = true
|
||||||
|
self.inlineContentPanRecognizer = inlineContentPanRecognizer
|
||||||
|
self.view.addGestureRecognizer(inlineContentPanRecognizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
@ -1264,6 +1293,69 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
|
if let _ = otherGestureRecognizer as? InteractiveTransitionGestureRecognizer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let _ = otherGestureRecognizer as? UIPanGestureRecognizer {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func inlineContentPanGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||||
|
switch recognizer.state {
|
||||||
|
case .began:
|
||||||
|
break
|
||||||
|
case .changed:
|
||||||
|
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
||||||
|
let translation = recognizer.translation(in: self.view)
|
||||||
|
var transitionFraction = translation.x / inlineStackContainerNode.bounds.width
|
||||||
|
transitionFraction = 1.0 - max(0.0, min(1.0, transitionFraction))
|
||||||
|
self.inlineStackContainerTransitionFraction = transitionFraction
|
||||||
|
self.controller?.requestLayout(transition: .immediate)
|
||||||
|
}
|
||||||
|
case .cancelled, .ended:
|
||||||
|
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
||||||
|
let translation = recognizer.translation(in: self.view)
|
||||||
|
let velocity = recognizer.velocity(in: self.view)
|
||||||
|
var directionIsToRight: Bool?
|
||||||
|
if abs(velocity.x) > 10.0 {
|
||||||
|
if translation.x > 0.0 {
|
||||||
|
if velocity.x <= 0.0 {
|
||||||
|
directionIsToRight = nil
|
||||||
|
} else {
|
||||||
|
directionIsToRight = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if velocity.x >= 0.0 {
|
||||||
|
directionIsToRight = nil
|
||||||
|
} else {
|
||||||
|
directionIsToRight = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if abs(translation.x) > inlineStackContainerNode.bounds.width / 2.0 {
|
||||||
|
directionIsToRight = translation.x > inlineStackContainerNode.bounds.width / 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let directionIsToRight = directionIsToRight, directionIsToRight {
|
||||||
|
self.setInlineChatList(location: nil)
|
||||||
|
} else {
|
||||||
|
self.inlineStackContainerTransitionFraction = 1.0
|
||||||
|
self.controller?.requestLayout(transition: .animated(duration: 0.4, curve: .spring))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updatePresentationData(_ presentationData: PresentationData) {
|
func updatePresentationData(_ presentationData: PresentationData) {
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
|
|
||||||
@ -1342,12 +1434,12 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
var mainNavigationBarHeight = navigationBarHeight
|
var mainNavigationBarHeight = navigationBarHeight
|
||||||
var cleanMainNavigationBarHeight = cleanNavigationBarHeight
|
var cleanMainNavigationBarHeight = cleanNavigationBarHeight
|
||||||
var mainInsets = insets
|
var mainInsets = insets
|
||||||
if self.inlineStackContainerNode != nil {
|
if self.inlineStackContainerNode != nil && "".isEmpty {
|
||||||
mainNavigationBarHeight = visualNavigationHeight
|
mainNavigationBarHeight = visualNavigationHeight
|
||||||
cleanMainNavigationBarHeight = visualNavigationHeight
|
cleanMainNavigationBarHeight = visualNavigationHeight
|
||||||
mainInsets.top = visualNavigationHeight
|
mainInsets.top = visualNavigationHeight
|
||||||
}
|
}
|
||||||
self.containerNode.update(layout: layout, navigationBarHeight: mainNavigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanMainNavigationBarHeight, insets: mainInsets, isReorderingFilters: self.isReorderingFilters, isEditing: self.isEditing, inlineNavigationLocation: self.inlineStackContainerNode?.location, transition: transition)
|
self.containerNode.update(layout: layout, navigationBarHeight: mainNavigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: navigationBarHeight, cleanNavigationBarHeight: cleanMainNavigationBarHeight, insets: mainInsets, isReorderingFilters: self.isReorderingFilters, isEditing: self.isEditing, inlineNavigationLocation: self.inlineStackContainerNode?.location, inlineNavigationTransitionFraction: self.inlineStackContainerTransitionFraction, transition: transition)
|
||||||
|
|
||||||
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
||||||
var inlineStackContainerNodeTransition = transition
|
var inlineStackContainerNodeTransition = transition
|
||||||
@ -1359,7 +1451,9 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let inlineSideInset: CGFloat = layout.safeInsets.left + 72.0
|
let inlineSideInset: CGFloat = layout.safeInsets.left + 72.0
|
||||||
inlineStackContainerNodeTransition.updateFrame(node: inlineStackContainerNode, frame: CGRect(origin: CGPoint(x: inlineSideInset, y: 0.0), size: layout.size))
|
var inlineStackFrame = CGRect(origin: CGPoint(x: inlineSideInset, y: 0.0), size: CGSize(width: layout.size.width - inlineSideInset, height: layout.size.height))
|
||||||
|
inlineStackFrame.origin.x += (1.0 - self.inlineStackContainerTransitionFraction) * inlineStackFrame.width
|
||||||
|
inlineStackContainerNodeTransition.updateFrame(node: inlineStackContainerNode, frame: inlineStackFrame)
|
||||||
var inlineLayout = layout
|
var inlineLayout = layout
|
||||||
inlineLayout.size.width -= inlineSideInset
|
inlineLayout.size.width -= inlineSideInset
|
||||||
inlineLayout.safeInsets.left = 0.0
|
inlineLayout.safeInsets.left = 0.0
|
||||||
@ -1369,7 +1463,7 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
var inlineInsets = insets
|
var inlineInsets = insets
|
||||||
inlineInsets.left = 0.0
|
inlineInsets.left = 0.0
|
||||||
|
|
||||||
inlineStackContainerNode.update(layout: inlineLayout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: inlineInsets, isReorderingFilters: self.isReorderingFilters, isEditing: self.isEditing, inlineNavigationLocation: nil, transition: inlineStackContainerNodeTransition)
|
inlineStackContainerNode.update(layout: inlineLayout, navigationBarHeight: navigationBarHeight, visualNavigationHeight: visualNavigationHeight, originalNavigationHeight: navigationBarHeight, cleanNavigationBarHeight: cleanNavigationBarHeight, insets: inlineInsets, isReorderingFilters: self.isReorderingFilters, isEditing: self.isEditing, inlineNavigationLocation: nil, inlineNavigationTransitionFraction: 0.0, transition: inlineStackContainerNodeTransition)
|
||||||
|
|
||||||
if animateIn {
|
if animateIn {
|
||||||
transition.animatePosition(node: inlineStackContainerNode, from: CGPoint(x: inlineStackContainerNode.position.x + inlineStackContainerNode.bounds.width + UIScreenPixel, y: inlineStackContainerNode.position.y))
|
transition.animatePosition(node: inlineStackContainerNode, from: CGPoint(x: inlineStackContainerNode.position.x + inlineStackContainerNode.bounds.width + UIScreenPixel, y: inlineStackContainerNode.position.y))
|
||||||
@ -1561,8 +1655,9 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
let previousInlineStackContainerNode = self.inlineStackContainerNode
|
let previousInlineStackContainerNode = self.inlineStackContainerNode
|
||||||
|
|
||||||
self.inlineStackContainerNode = inlineStackContainerNode
|
self.inlineStackContainerNode = inlineStackContainerNode
|
||||||
|
self.inlineStackContainerTransitionFraction = 1.0
|
||||||
|
|
||||||
if let containerLayout = self.containerLayout {
|
if let _ = self.containerLayout {
|
||||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
||||||
|
|
||||||
if let previousInlineStackContainerNode {
|
if let previousInlineStackContainerNode {
|
||||||
@ -1571,7 +1666,7 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.containerLayoutUpdated(containerLayout.layout, navigationBarHeight: containerLayout.navigationBarHeight, visualNavigationHeight: containerLayout.visualNavigationHeight, cleanNavigationBarHeight: containerLayout.cleanNavigationBarHeight, transition: transition)
|
self.controller?.requestLayout(transition: transition)
|
||||||
} else {
|
} else {
|
||||||
previousInlineStackContainerNode?.removeFromSupernode()
|
previousInlineStackContainerNode?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
@ -1579,16 +1674,18 @@ final class ChatListControllerNode: ASDisplayNode {
|
|||||||
} else {
|
} else {
|
||||||
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
if let inlineStackContainerNode = self.inlineStackContainerNode {
|
||||||
self.inlineStackContainerNode = nil
|
self.inlineStackContainerNode = nil
|
||||||
|
self.inlineStackContainerTransitionFraction = 0.0
|
||||||
|
|
||||||
self.containerNode.contentScrollingEnded = self.contentScrollingEnded
|
self.containerNode.contentScrollingEnded = self.contentScrollingEnded
|
||||||
|
|
||||||
if let containerLayout = self.containerLayout {
|
if let _ = self.containerLayout {
|
||||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring)
|
||||||
self.containerLayoutUpdated(containerLayout.layout, navigationBarHeight: containerLayout.navigationBarHeight, visualNavigationHeight: containerLayout.visualNavigationHeight, cleanNavigationBarHeight: containerLayout.cleanNavigationBarHeight, transition: transition)
|
|
||||||
|
|
||||||
transition.updatePosition(node: inlineStackContainerNode, position: CGPoint(x: inlineStackContainerNode.position.x + inlineStackContainerNode.bounds.width + UIScreenPixel, y: inlineStackContainerNode.position.y), completion: { [weak inlineStackContainerNode] _ in
|
transition.updatePosition(node: inlineStackContainerNode, position: CGPoint(x: inlineStackContainerNode.position.x + inlineStackContainerNode.bounds.width + UIScreenPixel, y: inlineStackContainerNode.position.y), completion: { [weak inlineStackContainerNode] _ in
|
||||||
inlineStackContainerNode?.removeFromSupernode()
|
inlineStackContainerNode?.removeFromSupernode()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.controller?.requestLayout(transition: transition)
|
||||||
} else {
|
} else {
|
||||||
inlineStackContainerNode.removeFromSupernode()
|
inlineStackContainerNode.removeFromSupernode()
|
||||||
}
|
}
|
||||||
|
@ -2349,26 +2349,28 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
strongSelf.contextContainer.position = contextContainerFrame.center
|
strongSelf.contextContainer.position = contextContainerFrame.center
|
||||||
transition.updateBounds(node: strongSelf.contextContainer, bounds: contextContainerFrame.offsetBy(dx: -strongSelf.revealOffset, dy: 0.0))
|
transition.updateBounds(node: strongSelf.contextContainer, bounds: contextContainerFrame.offsetBy(dx: -strongSelf.revealOffset, dy: 0.0))
|
||||||
|
|
||||||
if item.interaction.inlineNavigationLocation != nil {
|
var mainContentFrame: CGRect
|
||||||
let mainContentFrame = CGRect(origin: CGPoint(x: params.leftInset + 72.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height))
|
var mainContentBoundsOffset: CGFloat
|
||||||
transition.updatePosition(node: strongSelf.mainContentContainerNode, position: mainContentFrame.center)
|
var mainContentAlpha: CGFloat = 1.0
|
||||||
|
|
||||||
|
if case .chatList = item.chatListLocation {
|
||||||
|
mainContentFrame = CGRect(origin: CGPoint(x: params.leftInset + 72.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height))
|
||||||
|
mainContentBoundsOffset = mainContentFrame.origin.x
|
||||||
|
|
||||||
transition.updateBounds(node: strongSelf.mainContentContainerNode, bounds: CGRect(origin: CGPoint(x: mainContentFrame.size.width, y: 0.0), size: mainContentFrame.size))
|
if let inlineNavigationLocation = item.interaction.inlineNavigationLocation {
|
||||||
transition.updateAlpha(node: strongSelf.mainContentContainerNode, alpha: 0.0)
|
mainContentAlpha = 1.0 - inlineNavigationLocation.progress
|
||||||
} else if case .chatList = item.chatListLocation {
|
mainContentBoundsOffset += (mainContentFrame.width - mainContentFrame.minX) * inlineNavigationLocation.progress
|
||||||
let mainContentFrame = CGRect(origin: CGPoint(x: params.leftInset + 72.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height))
|
}
|
||||||
transition.updatePosition(node: strongSelf.mainContentContainerNode, position: mainContentFrame.center)
|
|
||||||
|
|
||||||
transition.updateBounds(node: strongSelf.mainContentContainerNode, bounds: CGRect(origin: CGPoint(x: mainContentFrame.origin.x, y: 0.0), size: mainContentFrame.size))
|
|
||||||
transition.updateAlpha(node: strongSelf.mainContentContainerNode, alpha: 1.0)
|
|
||||||
} else {
|
} else {
|
||||||
let mainContentFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height))
|
mainContentFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height))
|
||||||
transition.updatePosition(node: strongSelf.mainContentContainerNode, position: mainContentFrame.center)
|
mainContentBoundsOffset = 0.0
|
||||||
|
|
||||||
transition.updateBounds(node: strongSelf.mainContentContainerNode, bounds: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: mainContentFrame.size))
|
|
||||||
transition.updateAlpha(node: strongSelf.mainContentContainerNode, alpha: 1.0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transition.updatePosition(node: strongSelf.mainContentContainerNode, position: mainContentFrame.center)
|
||||||
|
|
||||||
|
transition.updateBounds(node: strongSelf.mainContentContainerNode, bounds: CGRect(origin: CGPoint(x: mainContentBoundsOffset, y: 0.0), size: mainContentFrame.size))
|
||||||
|
transition.updateAlpha(node: strongSelf.mainContentContainerNode, alpha: mainContentAlpha)
|
||||||
|
|
||||||
var crossfadeContent = false
|
var crossfadeContent = false
|
||||||
if let selectableControlSizeAndApply = selectableControlSizeAndApply {
|
if let selectableControlSizeAndApply = selectableControlSizeAndApply {
|
||||||
let selectableControlSize = CGSize(width: selectableControlSizeAndApply.0, height: layout.contentSize.height)
|
let selectableControlSize = CGSize(width: selectableControlSizeAndApply.0, height: layout.contentSize.height)
|
||||||
@ -2441,9 +2443,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
let avatarFrame = CGRect(origin: CGPoint(x: leftInset - avatarLeftInset + editingOffset + 10.0 + revealOffset, y: floor((itemHeight - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter))
|
let avatarFrame = CGRect(origin: CGPoint(x: leftInset - avatarLeftInset + editingOffset + 10.0 + revealOffset, y: floor((itemHeight - avatarDiameter) / 2.0)), size: CGSize(width: avatarDiameter, height: avatarDiameter))
|
||||||
var avatarScaleOffset: CGFloat = 0.0
|
var avatarScaleOffset: CGFloat = 0.0
|
||||||
var avatarScale: CGFloat = 1.0
|
var avatarScale: CGFloat = 1.0
|
||||||
if item.interaction.inlineNavigationLocation != nil {
|
if let inlineNavigationLocation = item.interaction.inlineNavigationLocation {
|
||||||
avatarScale = 54.0 / avatarFrame.width
|
let targetAvatarScale: CGFloat = 54.0 / avatarFrame.width
|
||||||
avatarScaleOffset = -(avatarFrame.width - avatarFrame.width * avatarScale) * 0.5
|
avatarScale = targetAvatarScale * inlineNavigationLocation.progress + 1.0 * (1.0 - inlineNavigationLocation.progress)
|
||||||
|
|
||||||
|
let targetAvatarScaleOffset: CGFloat = -(avatarFrame.width - avatarFrame.width * avatarScale) * 0.5
|
||||||
|
avatarScaleOffset = targetAvatarScaleOffset * inlineNavigationLocation.progress
|
||||||
}
|
}
|
||||||
transition.updatePosition(node: strongSelf.avatarNode, position: avatarFrame.center.offsetBy(dx: avatarScaleOffset, dy: 0.0))
|
transition.updatePosition(node: strongSelf.avatarNode, position: avatarFrame.center.offsetBy(dx: avatarScaleOffset, dy: 0.0))
|
||||||
transition.updateBounds(node: strongSelf.avatarNode, bounds: CGRect(origin: CGPoint(), size: avatarFrame.size))
|
transition.updateBounds(node: strongSelf.avatarNode, bounds: CGRect(origin: CGPoint(), size: avatarFrame.size))
|
||||||
@ -2470,7 +2475,8 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
inlineNavigationMarkLayer.backgroundColor = item.presentationData.theme.list.itemAccentColor.cgColor
|
inlineNavigationMarkLayer.backgroundColor = item.presentationData.theme.list.itemAccentColor.cgColor
|
||||||
let markHeight: CGFloat = 50.0
|
let markHeight: CGFloat = 50.0
|
||||||
let markFrame = CGRect(origin: CGPoint(x: -4.0, y: avatarFrame.midY - markHeight * 0.5), size: CGSize(width: 8.0, height: markHeight))
|
var markFrame = CGRect(origin: CGPoint(x: -4.0, y: avatarFrame.midY - markHeight * 0.5), size: CGSize(width: 8.0, height: markHeight))
|
||||||
|
markFrame.origin.x -= (1.0 - inlineNavigationLocation.progress) * markFrame.width * 0.5
|
||||||
if animateIn {
|
if animateIn {
|
||||||
inlineNavigationMarkLayer.frame = markFrame
|
inlineNavigationMarkLayer.frame = markFrame
|
||||||
transition.animatePositionAdditive(layer: inlineNavigationMarkLayer, offset: CGPoint(x: -markFrame.width * 0.5, y: 0.0))
|
transition.animatePositionAdditive(layer: inlineNavigationMarkLayer, offset: CGPoint(x: -markFrame.width * 0.5, y: 0.0))
|
||||||
@ -2979,15 +2985,16 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: strongSelf.separatorNode, frame: CGRect(origin: CGPoint(x: separatorInset, y: layoutOffset + itemHeight - separatorHeight), size: CGSize(width: params.width - separatorInset, height: separatorHeight)))
|
transition.updateFrame(node: strongSelf.separatorNode, frame: CGRect(origin: CGPoint(x: separatorInset, y: layoutOffset + itemHeight - separatorHeight), size: CGSize(width: params.width - separatorInset, height: separatorHeight)))
|
||||||
transition.updateAlpha(node: strongSelf.separatorNode, alpha: item.interaction.inlineNavigationLocation != nil ? 0.0 : 1.0)
|
if let inlineNavigationLocation = item.interaction.inlineNavigationLocation {
|
||||||
|
transition.updateAlpha(node: strongSelf.separatorNode, alpha: 1.0 - inlineNavigationLocation.progress)
|
||||||
|
} else {
|
||||||
|
transition.updateAlpha(node: strongSelf.separatorNode, alpha: 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: itemHeight)))
|
transition.updateFrame(node: strongSelf.backgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.contentSize.width, height: itemHeight)))
|
||||||
let backgroundColor: UIColor
|
let backgroundColor: UIColor
|
||||||
let highlightedBackgroundColor: UIColor
|
let highlightedBackgroundColor: UIColor
|
||||||
if item.interaction.inlineNavigationLocation != nil {
|
if item.selected {
|
||||||
backgroundColor = theme.pinnedItemBackgroundColor
|
|
||||||
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
|
|
||||||
} else if item.selected {
|
|
||||||
backgroundColor = theme.itemSelectedBackgroundColor
|
backgroundColor = theme.itemSelectedBackgroundColor
|
||||||
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
|
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
|
||||||
} else if isPinned {
|
} else if isPinned {
|
||||||
@ -3002,11 +3009,19 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
backgroundColor = theme.itemBackgroundColor
|
backgroundColor = theme.itemBackgroundColor
|
||||||
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
|
highlightedBackgroundColor = theme.itemHighlightedBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if animated {
|
if animated {
|
||||||
transition.updateBackgroundColor(node: strongSelf.backgroundNode, color: backgroundColor)
|
transition.updateBackgroundColor(node: strongSelf.backgroundNode, color: backgroundColor)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.backgroundNode.backgroundColor = backgroundColor
|
strongSelf.backgroundNode.backgroundColor = backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let inlineNavigationLocation = item.interaction.inlineNavigationLocation {
|
||||||
|
transition.updateAlpha(node: strongSelf.backgroundNode, alpha: 1.0 - inlineNavigationLocation.progress)
|
||||||
|
} else {
|
||||||
|
transition.updateAlpha(node: strongSelf.backgroundNode, alpha: 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
strongSelf.highlightedBackgroundNode.backgroundColor = highlightedBackgroundColor
|
strongSelf.highlightedBackgroundNode.backgroundColor = highlightedBackgroundColor
|
||||||
let topNegativeInset: CGFloat = 0.0
|
let topNegativeInset: CGFloat = 0.0
|
||||||
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: layoutOffset - separatorHeight - topNegativeInset), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height + separatorHeight + topNegativeInset))
|
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: layoutOffset - separatorHeight - topNegativeInset), size: CGSize(width: layout.contentSize.width, height: layout.contentSize.height + separatorHeight + topNegativeInset))
|
||||||
|
@ -889,6 +889,7 @@ public final class ChatListNode: ListView {
|
|||||||
public var reachedSelectionLimit: ((Int32) -> Void)?
|
public var reachedSelectionLimit: ((Int32) -> Void)?
|
||||||
|
|
||||||
private var visibleTopInset: CGFloat?
|
private var visibleTopInset: CGFloat?
|
||||||
|
private var originalTopInset: CGFloat?
|
||||||
|
|
||||||
public init(context: AccountContext, location: ChatListControllerLocation, chatListFilter: ChatListFilter? = nil, previewing: Bool, fillPreloadItems: Bool, mode: ChatListNodeMode, theme: PresentationTheme, fontSize: PresentationFontSize, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, disableAnimations: Bool, isInlineMode: Bool) {
|
public init(context: AccountContext, location: ChatListControllerLocation, chatListFilter: ChatListFilter? = nil, previewing: Bool, fillPreloadItems: Bool, mode: ChatListNodeMode, theme: PresentationTheme, fontSize: PresentationFontSize, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, disableAnimations: Bool, isInlineMode: Bool) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@ -1965,7 +1966,7 @@ public final class ChatListNode: ListView {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
self.visibleContentOffsetChanged = { [weak self] offset in
|
self.visibleContentOffsetChanged = { [weak self] offset, transition in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2375,27 +2376,54 @@ public final class ChatListNode: ListView {
|
|||||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: scrollToItem, updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })*/
|
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: scrollToItem, updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateLayout(transition: ContainedViewLayoutTransition, updateSizeAndInsets: ListViewUpdateSizeAndInsets, visibleTopInset: CGFloat, inlineNavigationLocation: ChatListControllerLocation?) {
|
public func updateLayout(transition: ContainedViewLayoutTransition, updateSizeAndInsets: ListViewUpdateSizeAndInsets, visibleTopInset: CGFloat, originalTopInset: CGFloat, inlineNavigationLocation: ChatListControllerLocation?, inlineNavigationTransitionFraction: CGFloat) {
|
||||||
self.visibleTopInset = visibleTopInset
|
|
||||||
|
|
||||||
self.visualInsets = UIEdgeInsets(top: visibleTopInset, left: 0.0, bottom: 0.0, right: 0.0)
|
|
||||||
|
|
||||||
var highlightedLocation: ChatListHighlightedLocation?
|
var highlightedLocation: ChatListHighlightedLocation?
|
||||||
if case let .forum(peerId) = inlineNavigationLocation {
|
if case let .forum(peerId) = inlineNavigationLocation {
|
||||||
highlightedLocation = ChatListHighlightedLocation(location: .peer(id: peerId), progress: 1.0)
|
highlightedLocation = ChatListHighlightedLocation(location: .peer(id: peerId), progress: inlineNavigationTransitionFraction)
|
||||||
}
|
}
|
||||||
|
var navigationLocationPresenceUpdated = false
|
||||||
|
if (self.interaction?.inlineNavigationLocation == nil) != (highlightedLocation == nil) {
|
||||||
|
navigationLocationPresenceUpdated = true
|
||||||
|
}
|
||||||
|
|
||||||
var navigationLocationUpdated = false
|
var navigationLocationUpdated = false
|
||||||
if self.interaction?.inlineNavigationLocation != highlightedLocation {
|
if self.interaction?.inlineNavigationLocation != highlightedLocation {
|
||||||
self.interaction?.inlineNavigationLocation = highlightedLocation
|
self.interaction?.inlineNavigationLocation = highlightedLocation
|
||||||
navigationLocationUpdated = true
|
navigationLocationUpdated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let insetDelta: CGFloat = 0.0
|
||||||
|
if navigationLocationPresenceUpdated {
|
||||||
|
let targetTopInset: CGFloat
|
||||||
|
if highlightedLocation != nil {
|
||||||
|
targetTopInset = self.visibleTopInset ?? self.insets.top
|
||||||
|
} else {
|
||||||
|
targetTopInset = self.originalTopInset ?? self.insets.top
|
||||||
|
}
|
||||||
|
let immediateInsetDelta = self.insets.top - targetTopInset
|
||||||
|
|
||||||
|
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, additionalScrollDistance: immediateInsetDelta, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: self.visibleSize, insets: UIEdgeInsets(top: targetTopInset, left: self.insets.left, bottom: self.insets.bottom, right: self.insets.right), duration: 0.0, curve: .Default(duration: 0.0)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||||
|
}
|
||||||
|
|
||||||
|
self.visualInsets = UIEdgeInsets(top: visibleTopInset, left: 0.0, bottom: 0.0, right: 0.0)
|
||||||
|
|
||||||
|
self.visibleTopInset = visibleTopInset
|
||||||
|
self.originalTopInset = originalTopInset
|
||||||
|
|
||||||
|
var additionalScrollDistance: CGFloat = 0.0
|
||||||
|
|
||||||
var options: ListViewDeleteAndInsertOptions = [.Synchronous, .LowLatency]
|
var options: ListViewDeleteAndInsertOptions = [.Synchronous, .LowLatency]
|
||||||
if navigationLocationUpdated {
|
if navigationLocationUpdated {
|
||||||
options.insert(.ForceUpdate)
|
options.insert(.ForceUpdate)
|
||||||
options.insert(.AnimateInsertion)
|
|
||||||
|
if transition.isAnimated {
|
||||||
|
options.insert(.AnimateInsertion)
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalScrollDistance += insetDelta
|
||||||
}
|
}
|
||||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: options, scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: options, scrollToItem: nil, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||||
|
|
||||||
if !self.dequeuedInitialTransitionOnLayout {
|
if !self.dequeuedInitialTransitionOnLayout {
|
||||||
self.dequeuedInitialTransitionOnLayout = true
|
self.dequeuedInitialTransitionOnLayout = true
|
||||||
|
@ -2914,11 +2914,11 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
} else if self.snapToBottomInsetUntilFirstInteraction {
|
} else if self.snapToBottomInsetUntilFirstInteraction {
|
||||||
offsetFix = -updateSizeAndInsets.insets.bottom + self.insets.bottom
|
offsetFix = -updateSizeAndInsets.insets.bottom + self.insets.bottom
|
||||||
} else {
|
} else {
|
||||||
if let visualInsets = self.visualInsets, animated, (visualInsets.top == updateSizeAndInsets.insets.top || visualInsets.top == self.insets.top) {
|
/*if let visualInsets = self.visualInsets, animated, (visualInsets.top == updateSizeAndInsets.insets.top || visualInsets.top == self.insets.top) {
|
||||||
offsetFix = 0.0
|
offsetFix = 0.0
|
||||||
} else {
|
} else {*/
|
||||||
offsetFix = updateSizeAndInsets.insets.top - self.insets.top
|
offsetFix = updateSizeAndInsets.insets.top - self.insets.top
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetFix += additionalScrollDistance
|
offsetFix += additionalScrollDistance
|
||||||
|
@ -489,6 +489,7 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
|
|
||||||
public private(set) var contentNode: NavigationBarContentNode?
|
public private(set) var contentNode: NavigationBarContentNode?
|
||||||
public private(set) var secondaryContentNode: ASDisplayNode?
|
public private(set) var secondaryContentNode: ASDisplayNode?
|
||||||
|
public var secondaryContentNodeDisplayFraction: CGFloat = 1.0
|
||||||
|
|
||||||
private var itemTitleListenerKey: Int?
|
private var itemTitleListenerKey: Int?
|
||||||
private var itemTitleViewListenerKey: Int?
|
private var itemTitleViewListenerKey: Int?
|
||||||
@ -1200,7 +1201,7 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
self.backgroundNode.update(size: backgroundFrame.size, transition: transition)
|
self.backgroundNode.update(size: backgroundFrame.size, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
let apparentAdditionalHeight: CGFloat = self.secondaryContentNode != nil ? NavigationBar.defaultSecondaryContentHeight : 0.0
|
let apparentAdditionalHeight: CGFloat = self.secondaryContentNode != nil ? (NavigationBar.defaultSecondaryContentHeight * self.secondaryContentNodeDisplayFraction) : 0.0
|
||||||
|
|
||||||
let leftButtonInset: CGFloat = leftInset + 16.0
|
let leftButtonInset: CGFloat = leftInset + 16.0
|
||||||
let backButtonInset: CGFloat = leftInset + 27.0
|
let backButtonInset: CGFloat = leftInset + 27.0
|
||||||
@ -1218,11 +1219,11 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
case .expansion:
|
case .expansion:
|
||||||
expansionHeight = contentNode.height
|
expansionHeight = contentNode.height
|
||||||
|
|
||||||
let additionalExpansionHeight: CGFloat = self.secondaryContentNode != nil && appearsHidden ? NavigationBar.defaultSecondaryContentHeight : 0.0
|
let additionalExpansionHeight: CGFloat = self.secondaryContentNode != nil && appearsHidden ? (NavigationBar.defaultSecondaryContentHeight * self.secondaryContentNodeDisplayFraction) : 0.0
|
||||||
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - (appearsHidden ? 0.0 : additionalContentHeight) - expansionHeight - apparentAdditionalHeight - additionalExpansionHeight), size: CGSize(width: size.width, height: expansionHeight))
|
contentNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - (appearsHidden ? 0.0 : additionalContentHeight) - expansionHeight - apparentAdditionalHeight - additionalExpansionHeight), size: CGSize(width: size.width, height: expansionHeight))
|
||||||
if appearsHidden {
|
if appearsHidden {
|
||||||
if self.secondaryContentNode != nil {
|
if self.secondaryContentNode != nil {
|
||||||
contentNodeFrame.origin.y += NavigationBar.defaultSecondaryContentHeight
|
contentNodeFrame.origin.y += NavigationBar.defaultSecondaryContentHeight * self.secondaryContentNodeDisplayFraction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1545,7 +1546,7 @@ open class NavigationBar: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let _ = self.secondaryContentNode {
|
if let _ = self.secondaryContentNode {
|
||||||
result += NavigationBar.defaultSecondaryContentHeight
|
result += NavigationBar.defaultSecondaryContentHeight * self.secondaryContentNodeDisplayFraction
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -279,7 +279,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
|
|||||||
combinedInsets.right += layout.safeInsets.right
|
combinedInsets.right += layout.safeInsets.right
|
||||||
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
||||||
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: layout.size, insets: combinedInsets, headerInsets: headerInsets, duration: duration, curve: curve)
|
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: layout.size, insets: combinedInsets, headerInsets: headerInsets, duration: duration, curve: curve)
|
||||||
chatsNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: updateSizeAndInsets.insets.top, inlineNavigationLocation: nil)
|
chatsNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: updateSizeAndInsets.insets.top, originalTopInset: updateSizeAndInsets.insets.top, inlineNavigationLocation: nil, inlineNavigationTransitionFraction: 0.0)
|
||||||
}
|
}
|
||||||
self.contentNode.node.frame = CGRect(origin: CGPoint(), size: layout.size)
|
self.contentNode.node.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||||||
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
|
||||||
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: layout.size, insets: insets, headerInsets: headerInsets, duration: duration, curve: curve)
|
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: layout.size, insets: insets, headerInsets: headerInsets, duration: duration, curve: curve)
|
||||||
|
|
||||||
self.chatListNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: updateSizeAndInsets.insets.top, inlineNavigationLocation: nil)
|
self.chatListNode.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, visibleTopInset: updateSizeAndInsets.insets.top, originalTopInset: updateSizeAndInsets.insets.top, inlineNavigationLocation: nil, inlineNavigationTransitionFraction: 0.0)
|
||||||
|
|
||||||
if let contactListNode = self.contactListNode {
|
if let contactListNode = self.contactListNode {
|
||||||
contactListNode.bounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height)
|
contactListNode.bounds = CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: layout.size.height)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user