diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift index a2a8f665..760e92c9 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift @@ -9,22 +9,20 @@ import Foundation public extension MVMCoreAlertHandler { - + /// Re-evaluates the queue operations @objc func reevaluteQueue() { - var higherPriorityOperationIsReady = false + var highestReadyOperation: MVMCoreTopAlertOperation? var executingOperation: MVMCoreTopAlertOperation? - let pageType = (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType - let sortedOperations = topAlertQueue.operations.sorted { $0.queuePriority.rawValue > $1.queuePriority.rawValue } - for case let operation as MVMCoreTopAlertOperation in sortedOperations { + for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations { guard !operation.isCancelled, !operation.isFinished else { continue } - updatePageReadiness(for: operation, with: pageType) + if operation.isReady, + highestReadyOperation == nil || operation.queuePriority.rawValue > highestReadyOperation!.queuePriority.rawValue { + highestReadyOperation = operation + } if operation.isExecuting { executingOperation = operation - } else if operation.isReady, - executingOperation == nil { - higherPriorityOperationIsReady = true } } guard let currentOperation = executingOperation else { return } @@ -37,34 +35,30 @@ public extension MVMCoreAlertHandler { } // If the highest priority operation is not executing, and the executing operation is persistent, cancel it. - if higherPriorityOperationIsReady, + if let newOperation = highestReadyOperation, + currentOperation != newOperation, currentOperation.topAlertObject.persistent { currentOperation.reAddAfterCancel = true currentOperation.cancel() } } - /// Registers with the notification center to know when pages change. - @objc func registerWithNotificationCenter() { - NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil) + /// Registers to know when pages change. + @objc func registerForPageChanges() { + MVMCoreNavigationHandler.shared()?.addDelegate(self) } - - /// Updates the operation isDisplayable based on the page type. - private func updatePageReadiness(for topOperation: MVMCoreTopAlertOperation, with pageType: String?) { - guard let pages = topOperation.topAlertObject.json?.optionalArrayForKey("pages") as? [String], - pages.count != 0 else { - topOperation.isDisplayable = true - return +} + +extension MVMCoreAlertHandler: MVMCorePresentationDelegateProtocol { + // Update displayable for each top alert operation when page type changes, in top queue priority order. + public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { + guard navigationController == MVMCoreUISplitViewController.main()?.navigationController else { return } + let pageType = (viewController as? MVMCoreViewControllerProtocol)?.pageType + let sortedOperations = topAlertQueue.operations.sorted { $0.queuePriority.rawValue > $1.queuePriority.rawValue } + for case let operation as MVMCoreTopAlertOperation in sortedOperations { + operation.updateDisplayable(byPageType: pageType) } - guard let pageType = pageType else { - topOperation.isDisplayable = false - return - } - topOperation.isDisplayable = pages.contains(pageType) - } - - /// When a detail page changes, check top alerts. - @objc private func viewControllerChanged(notification: Notification) { reevaluteQueue() } } + diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler.m b/MVMCoreUI/Alerts/MVMCoreAlertHandler.m index f65a1db0..8b4b02c7 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler.m +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler.m @@ -42,7 +42,7 @@ self.popupAlertQueue.maxConcurrentOperationCount = 1; self.topAlertQueue = [[NSOperationQueue alloc] init]; self.topAlertQueue.maxConcurrentOperationCount = 1; - [self registerWithNotificationCenter]; + [self registerForPageChanges]; } return self; } @@ -172,6 +172,9 @@ alertOperation = nil; }]; + NSString *currentPageType = ((UIViewController *)[[MVMCoreUISplitViewController mainSplitViewController] getCurrentDetailViewController]).pageType; + [alertOperation updateDisplayableByPageType:currentPageType]; + [self.topAlertQueue addOperation:alertOperation]; [self reevaluteQueue]; } diff --git a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h index 16f2ab8d..af00d789 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h @@ -27,6 +27,9 @@ /// Updates the operation with a new object - (void)updateWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject; +/// Updates the operation isDisplayable based on the page type. +- (void)updateDisplayableByPageType:(nullable NSString *)pageType; + // Pauses the operation. Temporarily removes any alert. - (void)pause; diff --git a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m index a59248ab..7a57f989 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m @@ -71,6 +71,19 @@ } } +- (void)updateDisplayableByPageType:(nullable NSString *)pageType { + NSArray *pages = [self.topAlertObject.json array:@"pages"]; + if (pages.count == 0) { + self.displayable = YES; + return; + } + if (pageType.length == 0) { + self.displayable = NO; + return; + } + self.displayable = [pages containsObject:pageType]; +} + - (BOOL)isPaused { __block BOOL isPaused; dispatch_sync(self.pausedQueue, ^{ diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift index cb53b18a..a0b128b2 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift @@ -68,6 +68,8 @@ public extension MVMCoreUITopAlertView { guard topAlertObject.json != nil, operation.topAlertObject.type == topAlertObject.type else { continue } operation.update(with: topAlertObject) + let pageType = (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType + operation.updateDisplayable(byPageType: pageType) MVMCoreAlertHandler.shared()?.reevaluteQueue() return true }