Various improvements

This commit is contained in:
Ilya Laktyushin
2024-06-15 18:41:19 +04:00
parent 2150d65f78
commit 1ae20bd685
94 changed files with 3242 additions and 534 deletions

View File

@@ -180,6 +180,15 @@ open class NavigationController: UINavigationController, ContainableController,
}
}
private var _minimizedViewControllers: [ViewController] = []
open var minimizedViewControllers: [UIViewController] {
get {
return self._minimizedViewControllers.map { $0 as UIViewController }
} set(value) {
self.setMinimizedViewControllers(value, animated: false)
}
}
private var _viewControllersPromise = ValuePromise<[UIViewController]>()
public var viewControllersSignal: Signal<[UIViewController], NoError> {
return _viewControllersPromise.get()
@@ -466,7 +475,7 @@ open class NavigationController: UINavigationController, ContainableController,
transition.updateFrame(node: globalOverlayContainerParent, frame: CGRect(origin: CGPoint(), size: layout.size))
}
let navigationLayout = makeNavigationLayout(mode: self.mode, layout: layout, controllers: self._viewControllers)
let navigationLayout = makeNavigationLayout(mode: self.mode, layout: layout, controllers: self._viewControllers, minimizedControllers: self._minimizedViewControllers)
var transition = transition
var statusBarStyle: StatusBarStyle = .Ignore
@@ -488,8 +497,9 @@ open class NavigationController: UINavigationController, ContainableController,
let modalContainer: NavigationModalContainer
if let existingModalContainer = existingModalContainer {
modalContainer = existingModalContainer
modalContainer.isMinimized = navigationLayout.modal[i].isMinimized
} else {
modalContainer = NavigationModalContainer(theme: self.theme, isFlat: navigationLayout.modal[i].isFlat, controllerRemoved: { [weak self] controller in
modalContainer = NavigationModalContainer(theme: self.theme, isFlat: navigationLayout.modal[i].isFlat, isMinimized: navigationLayout.modal[i].isMinimized, controllerRemoved: { [weak self] controller in
self?.controllerRemoved(controller)
})
modalContainer.container.statusBarStyleUpdated = { [weak self] transition in
@@ -524,6 +534,32 @@ open class NavigationController: UINavigationController, ContainableController,
strongSelf.setViewControllers(controllers, animated: false)
strongSelf.ignoreInputHeight = false
}
modalContainer.minimizedRequestMaximize = { [weak self] in
guard let self else {
return
}
var controllers = self._viewControllers
for controller in self._minimizedViewControllers {
controllers.append(controller)
}
self._viewControllers = controllers
self._minimizedViewControllers = []
self.updateContainersNonReentrant(transition: .animated(duration: 0.5, curve: .spring))
}
modalContainer.minimizedRequestDismiss = { [weak self, weak modalContainer] animated in
guard let self, let modalContainer else {
return
}
let minimizedControllers = self.minimizedViewControllers.filter { controller in
return !modalContainer.container.controllers.contains(where: { $0 === controller })
}
if minimizedControllers.count != self.minimizedViewControllers.count {
self.setMinimizedViewControllers(minimizedControllers, animated: animated)
}
}
}
modalContainers.append(modalContainer)
}
@@ -695,6 +731,7 @@ open class NavigationController: UINavigationController, ContainableController,
var topVisibleModalContainerWithStatusBar: NavigationModalContainer?
var visibleModalCount = 0
var topModalIsFlat = false
var topModalIsMinimized = false
var topFlatModalHasProgress = false
let isLandscape = layout.orientation == .landscape
var hasVisibleStandaloneModal = false
@@ -754,13 +791,16 @@ open class NavigationController: UINavigationController, ContainableController,
}
if modalContainer.supernode != nil {
if !hasVisibleStandaloneModal && !isStandaloneModal && !modalContainer.isFlat {
if !hasVisibleStandaloneModal && !isStandaloneModal && !modalContainer.isFlat && !modalContainer.isMinimized {
visibleModalCount += 1
}
if isStandaloneModal {
hasVisibleStandaloneModal = true
visibleModalCount = 0
}
topModalIsMinimized = modalContainer.isMinimized
if previousModalContainer == nil {
topModalIsFlat = modalContainer.isFlat
@@ -825,15 +865,23 @@ open class NavigationController: UINavigationController, ContainableController,
if let rootContainer = self.rootContainer {
switch rootContainer {
case let .flat(flatContainer):
if previousModalContainer == nil {
flatContainer.keyboardViewManager = self.keyboardViewManager
flatContainer.canHaveKeyboardFocus = true
} else {
if let previousModalContainer, !previousModalContainer.isMinimized {
flatContainer.keyboardViewManager = nil
flatContainer.canHaveKeyboardFocus = false
} else {
flatContainer.keyboardViewManager = self.keyboardViewManager
flatContainer.canHaveKeyboardFocus = true
}
transition.updateFrame(node: flatContainer, frame: CGRect(origin: CGPoint(), size: layout.size))
flatContainer.update(layout: layout, canBeClosed: false, controllers: controllers, transition: transition)
var updatedSize = layout.size
var updatedIntrinsicInsets = layout.intrinsicInsets
if topModalIsMinimized && (layout.inputHeight ?? 0.0).isZero {
updatedSize.height -= 81.0
updatedIntrinsicInsets.bottom = 0.0
}
let updatedLayout = layout.withUpdatedSize(updatedSize).withUpdatedIntrinsicInsets(updatedIntrinsicInsets)
transition.updateFrame(node: flatContainer, frame: CGRect(origin: CGPoint(), size: updatedSize))
flatContainer.update(layout: updatedLayout, canBeClosed: false, controllers: controllers, transition: transition)
case let .split(splitContainer):
let flatContainer = NavigationContainer(isFlat: self.isFlat, controllerRemoved: { [weak self] controller in
self?.controllerRemoved(controller)
@@ -1384,6 +1432,11 @@ open class NavigationController: UINavigationController, ContainableController,
self.setViewControllers(controllers, animated: animated)
self.ignoreInputHeight = false
}
let minimizedControllers = self.minimizedViewControllers.filter({ $0 !== controller })
if minimizedControllers.count != self.minimizedViewControllers.count {
self.setMinimizedViewControllers(minimizedControllers, animated: animated)
}
}
public func replaceController(_ controller: ViewController, with other: ViewController, animated: Bool) {
@@ -1523,6 +1576,29 @@ open class NavigationController: UINavigationController, ContainableController,
self._viewControllersPromise.set(self.viewControllers)
}
private func setMinimizedViewControllers(_ viewControllers: [UIViewController], animated: Bool) {
self._viewControllers = self._viewControllers.filter { controller in
return !viewControllers.contains(controller)
}
self._minimizedViewControllers = viewControllers.map { controller in
let controller = controller as! ViewController
controller.navigation_setNavigationController(self)
return controller
}
if let layout = self.validLayout {
self.updateContainers(layout: layout, transition: animated ? .animated(duration: 0.5, curve: .spring) : .immediate, completion: { [weak self] in
self?.notifyAccessibilityScreenChanged()
})
}
}
public func minimizeViewController(_ viewController: UIViewController, animated: Bool) {
var controllers = self.minimizedViewControllers
controllers.append(viewController)
self.setMinimizedViewControllers(controllers, animated: animated)
}
public var _keepModalDismissProgress = false
public func presentOverlay(controller: ViewController, inGlobal: Bool = false, blockInteraction: Bool = false) {
let container = NavigationOverlayContainer(controller: controller, blocksInteractionUntilReady: blockInteraction, controllerRemoved: { [weak self] controller in
@@ -1786,5 +1862,8 @@ open class NavigationController: UINavigationController, ContainableController,
return
}
transition.updateTransform(node: container, transform: CGAffineTransformMakeTranslation(offset, 0.0))
if let minimizedModalContainer = self.modalContainers.first(where: { $0.isMinimized }) {
transition.updateTransform(node: minimizedModalContainer, transform: CGAffineTransformMakeTranslation(offset, 0.0))
}
}
}