diff --git a/submodules/Display/Source/Navigation/MinimizedContainer.swift b/submodules/Display/Source/Navigation/MinimizedContainer.swift index 3642a85063..129a9e7b1e 100644 --- a/submodules/Display/Source/Navigation/MinimizedContainer.swift +++ b/submodules/Display/Source/Navigation/MinimizedContainer.swift @@ -6,7 +6,9 @@ public protocol MinimizedContainer: ASDisplayNode { var controllers: [MinimizableController] { get } var isExpanded: Bool { get } - var willMaximize: (() -> Void)? { get set } + var willMaximize: ((MinimizedContainer) -> Void)? { get set } + var willDismiss: ((MinimizedContainer) -> Void)? { get set } + var didDismiss: ((MinimizedContainer) -> Void)? { get set } var statusBarStyle: StatusBarStyle { get } var statusBarStyleUpdated: (() -> Void)? { get set } diff --git a/submodules/Display/Source/Navigation/NavigationController.swift b/submodules/Display/Source/Navigation/NavigationController.swift index dd7c033a3a..60c371dd67 100644 --- a/submodules/Display/Source/Navigation/NavigationController.swift +++ b/submodules/Display/Source/Navigation/NavigationController.swift @@ -153,13 +153,23 @@ open class NavigationController: UINavigationController, ContainableController, open var minimizedContainer: MinimizedContainer? { didSet { self.minimizedContainer?.navigationController = self - self.minimizedContainer?.willMaximize = { [weak self] in + self.minimizedContainer?.willMaximize = { [weak self] _ in guard let self else { return } self.isMaximizing = true self.updateContainersNonReentrant(transition: .animated(duration: 0.4, curve: .spring)) } + self.minimizedContainer?.willDismiss = { [weak self] _ in + guard let self else { + return + } + self.minimizedContainer = nil + self.updateContainersNonReentrant(transition: .animated(duration: 0.4, curve: .spring)) + } + self.minimizedContainer?.didDismiss = { minimizedContainer in + minimizedContainer.removeFromSupernode() + } self.minimizedContainer?.statusBarStyleUpdated = { [weak self] in guard let self else { return diff --git a/submodules/TelegramUI/Components/MinimizedContainer/Sources/MinimizedContainer.swift b/submodules/TelegramUI/Components/MinimizedContainer/Sources/MinimizedContainer.swift index 800eff84f3..b316bf2f11 100644 --- a/submodules/TelegramUI/Components/MinimizedContainer/Sources/MinimizedContainer.swift +++ b/submodules/TelegramUI/Components/MinimizedContainer/Sources/MinimizedContainer.swift @@ -10,6 +10,7 @@ import UIKitRuntimeUtils private let minimizedNavigationHeight: CGFloat = 44.0 private let minimizedTopMargin: CGFloat = 3.0 +private let maximizeLastStandingController = false final class ScrollViewImpl: UIScrollView { var shouldPassthrough: () -> Bool = { return false } @@ -112,7 +113,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll self.snapshotContainerView.isUserInteractionEnabled = false super.init() - + self.clipsToBounds = true self.cornerRadius = 10.0 applySmoothRoundedCorners(self.layer) @@ -308,7 +309,9 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll private var presentationDataDisposable: Disposable? public private(set) var isExpanded: Bool = false - public var willMaximize: (() -> Void)? + public var willMaximize: ((MinimizedContainer) -> Void)? + public var willDismiss: ((MinimizedContainer) -> Void)? + public var didDismiss: ((MinimizedContainer) -> Void)? public private(set) var statusBarStyle: StatusBarStyle = .White public var statusBarStyleUpdated: (() -> Void)? @@ -500,10 +503,13 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll self.currentTransition = .dismiss(itemId: itemId) self.items.removeAll(where: { $0.id == itemId }) - if self.items.count == 1 { + if self.items.count == 1, maximizeLastStandingController { self.isExpanded = false - self.willMaximize?() + self.willMaximize?(self) needsLayout = false + } else if self.items.count == 0 { + self.willDismiss?(self) + self.isExpanded = false } } if let item = self.items.first(where: { $0.id == itemId }), !item.controller.shouldDismissImmediately() { @@ -768,7 +774,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll if let currentTransition = self.currentTransition { if currentTransition.matches(item: item) { continue - } else if case .dismiss = currentTransition, self.items.count == 1 { + } else if case .dismiss = currentTransition, self.items.count == 1 && maximizeLastStandingController { continue } } @@ -798,10 +804,13 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll self.currentTransition = .dismiss(itemId: item.id) self.items.removeAll(where: { $0.id == item.id }) - if self.items.count == 1 { + if self.items.count == 1, maximizeLastStandingController { self.isExpanded = false - self.willMaximize?() + self.willMaximize?(self) needsLayout = false + } else if self.items.count == 0 { + self.isExpanded = false + self.willDismiss?(self) } if needsLayout { self.requestUpdate(transition: .animated(duration: 0.4, curve: .spring)) @@ -1106,7 +1115,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll guard let dismissedItemNode = self.itemNodes[itemId] else { return } - if self.items.count == 1 { + if self.items.count == 1, maximizeLastStandingController { if let itemNode = self.itemNodes.first(where: { $0.0 != itemId })?.value, let navigationController = self.navigationController { itemNode.item.beforeMaximize(navigationController, { [weak self] in guard let self else { @@ -1146,6 +1155,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll } transition.updatePosition(node: dismissedItemNode, position: CGPoint(x: -layout.size.width, y: dismissedItemNode.position.y)) } else { + let isLast = self.items.isEmpty transition.updatePosition(node: dismissedItemNode, position: CGPoint(x: -layout.size.width, y: dismissedItemNode.position.y), completion: { _ in self.isApplyingTransition = false if self.currentTransition == currentTransition { @@ -1155,7 +1165,15 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll self.itemNodes[itemId] = nil dismissedItemNode.removeFromSupernode() + + if isLast { + self.didDismiss?(self) + } }) + if isLast { + let dismissOffset = collapsedHeight(layout: layout) + transition.updatePosition(layer: self.bottomEdgeView.layer, position: self.bottomEdgeView.layer.position.offsetBy(dx: 0.0, dy: dismissOffset)) + } } case .dismissAll: let dismissOffset = collapsedHeight(layout: layout) diff --git a/submodules/TelegramUI/Components/MinimizedContainer/Sources/Utils.swift b/submodules/TelegramUI/Components/MinimizedContainer/Sources/Utils.swift index ee5f726e16..c90bad1ee5 100644 --- a/submodules/TelegramUI/Components/MinimizedContainer/Sources/Utils.swift +++ b/submodules/TelegramUI/Components/MinimizedContainer/Sources/Utils.swift @@ -113,7 +113,10 @@ func interitemSpacing(itemCount: Int, boundingSize: CGSize, insets: UIEdgeInsets func frameForIndex(index: Int, size: CGSize, insets: UIEdgeInsets, itemCount: Int, boundingSize: CGSize) -> CGRect { let spacing = interitemSpacing(itemCount: itemCount, boundingSize: boundingSize, insets: insets) - let y = additionalInsetTop + insets.top + spacing * CGFloat(index) + var y = additionalInsetTop + insets.top + spacing * CGFloat(index) + if itemCount == 1 { + y += 72.0 + } let origin = CGPoint(x: insets.left, y: y) return CGRect(origin: origin, size: CGSize(width: size.width - insets.left - insets.right, height: size.height))