From 9e8580e24063b0f318348f237fa3b4501540a125 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Mon, 26 Oct 2020 18:37:26 +0530 Subject: [PATCH 1/8] 22352(iOS - List star rating) initial commit. --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../List/ListStarRating.swift | 73 +++++++++++++++++++ .../List/ListStarRatingModel.swift | 52 +++++++++++++ .../Strings/en.lproj/Localizable.strings | 1 + .../Strings/es-MX.lproj/Localizable.strings | 1 + .../Strings/es.lproj/Localizable.strings | 1 + 7 files changed, 137 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 4b0faceb..5668f73a 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -235,6 +235,8 @@ AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */; }; AA7F32AB246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */; }; AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */; }; + AA7F47732541AD560015A2C1 /* ListStarRatingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F47722541AD560015A2C1 /* ListStarRatingModel.swift */; }; + AA7F47762541AD6A0015A2C1 /* ListStarRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7F47752541AD6A0015A2C1 /* ListStarRating.swift */; }; AA85236C244435A20059CC1E /* RadioSwatchCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */; }; AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */; }; AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */; }; @@ -747,6 +749,8 @@ AA71AD3F24A32FE700ACA76F /* HeadersH2Link.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2Link.swift; sourceTree = ""; }; AA7F32AA246C0F7900C965BA /* ListLeftVariableRadioButtonAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinksModel.swift; sourceTree = ""; }; AA7F32AC246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAllTextAndLinks.swift; sourceTree = ""; }; + AA7F47722541AD560015A2C1 /* ListStarRatingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStarRatingModel.swift; sourceTree = ""; }; + AA7F47752541AD6A0015A2C1 /* ListStarRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStarRating.swift; sourceTree = ""; }; AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchCollectionViewCell.swift; sourceTree = ""; }; AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinksModel.swift; sourceTree = ""; }; AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconAllTextLinks.swift; sourceTree = ""; }; @@ -1474,6 +1478,8 @@ D22B38EB23F4E0AE00490EF6 /* LeftVariable */, AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */, AAB7EDF0246ADA2A00E54929 /* ListProgressBarThin.swift */, + AA7F47722541AD560015A2C1 /* ListStarRatingModel.swift */, + AA7F47752541AD6A0015A2C1 /* ListStarRating.swift */, ); path = List; sourceTree = ""; @@ -2535,6 +2541,8 @@ 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */, D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */, 8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */, + AA7F47732541AD560015A2C1 /* ListStarRatingModel.swift in Sources */, + AA7F47762541AD6A0015A2C1 /* ListStarRating.swift in Sources */, 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */, BB55B51D244482C1002001AD /* ListRightVariablePriceChangeBodyText.swift in Sources */, 017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 8a5b737a..6a66a005 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -201,6 +201,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnSpeedTest.self, viewModelClass: ListThreeColumnSpeedTestModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListStarRating.self, viewModelClass: ListStarRatingModel.self) // MARK:- Designed Section Dividers MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift new file mode 100644 index 00000000..b1ca1ac4 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift @@ -0,0 +1,73 @@ +// +// ListStarRating.swift +// MVMCoreUI +// +// Created by Lekshmi S on 22/10/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +@objcMembers open class ListStarRating: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + public let stars = Stars() + public var reviewsCount = Label(fontStyle: .RegularBodySmall) + + //----------------------------------------------------- + // MARK: - Properties + //----------------------------------------------------- + public var stack: Stack + + //----------------------------------------------------- + // MARK: - Initializers + //----------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: stars, model: StackItemModel(horizontalAlignment: .fill)), + (view: reviewsCount, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal, spacing: 8) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //----------------------------------------------------- + // MARK: - Lifecycle + //----------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + //---------------------------------------------------- + // MARK: - Molecule + //---------------------------------------------------- + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + + guard let model = model as? ListStarRatingModel else { return } + stars.set(with: model.stars, delegateObject, additionalData) + reviewsCount.set(with: model.reviewsCount, delegateObject, additionalData) + updateAccessibilityLabel() + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 90 + } + + // MARK: - Accessibility + func updateAccessibilityLabel() { + isAccessibilityElement = true + var message = "" + if let starsLabel = stars.accessibilityLabel { + message += starsLabel + ", " + } + + if let reviewsCountLabelText = reviewsCount.text, let reviewText = MVMCoreUIUtility.hardcodedString(withKey: "review_text") { + message += reviewsCountLabelText + reviewText + } + accessibilityLabel = message + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift new file mode 100644 index 00000000..6838f0b0 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift @@ -0,0 +1,52 @@ +// +// ListStarRatingModel.swift +// MVMCoreUI +// +// Created by Lekshmi S on 22/10/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +open class ListStarRatingModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "listStarRating" + public var stars: StarsModel + public var reviewsCount: LabelModel + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(stars: StarsModel, reviewsCount: LabelModel) { + self.stars = stars + self.reviewsCount = reviewsCount + super.init() + } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { + case moleculeName + case stars + case reviewsCount + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + stars = try typeContainer.decode(StarsModel.self, forKey: .stars) + reviewsCount = try typeContainer.decode(LabelModel.self, forKey: .reviewsCount) + try super.init(from: decoder) + } + + open override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(stars, forKey: .stars) + try container.encode(reviewsCount, forKey: .reviewsCount) + } +} diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index f14fe02e..ba70fc2b 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -92,3 +92,4 @@ "star" = "Star"; "star_percent" = "%d percent progress"; "stars_filled" = "%.1f out of %d stars"; +"review_text" = " reviews"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings index 4d14292c..b279ccdb 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings @@ -70,3 +70,4 @@ "star" = "Estrella"; "star_percent" = "%@ porcentaje de progreso"; "stars_filled" = "%.1f de %d estrellas"; +"review_text" = " críticas"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings index 585e2c1a..0c441812 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings @@ -75,3 +75,4 @@ "star" = "Estrella"; "star_percent" = "%@ porcentaje de progreso"; "stars_filled" = "%.1f de %d estrellas"; +"review_text" = " críticas"; From 46e0c6281f151a8e65caea214af2101baa78d267 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 27 Oct 2020 12:33:56 +0530 Subject: [PATCH 2/8] Code changes after review. --- .../List/ListStarRating.swift | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift index b1ca1ac4..2e1ec8cb 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift @@ -12,26 +12,12 @@ //----------------------------------------------------- public let stars = Stars() public var reviewsCount = Label(fontStyle: .RegularBodySmall) + public lazy var stack: Stack = { + return Stack.createStack(with: [(view: stars, model: StackItemModel(horizontalAlignment: .fill)), + (view: reviewsCount, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal, spacing: Padding.Two) + }() - //----------------------------------------------------- - // MARK: - Properties - //----------------------------------------------------- - public var stack: Stack - - //----------------------------------------------------- - // MARK: - Initializers - //----------------------------------------------------- - public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - stack = Stack.createStack(with: [(view: stars, model: StackItemModel(horizontalAlignment: .fill)), - (view: reviewsCount, model: StackItemModel(horizontalAlignment: .leading))], - axis: .horizontal, spacing: 8) - super.init(style: style, reuseIdentifier: reuseIdentifier) - } - - public required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - //----------------------------------------------------- // MARK: - Lifecycle //----------------------------------------------------- @@ -41,6 +27,11 @@ stack.restack() } + open override func updateView(_ size: CGFloat) { + super.updateView(size) + stack.updateView(size) + } + //---------------------------------------------------- // MARK: - Molecule //---------------------------------------------------- From bc6c23cd914784dd754802d507597e2edd5b9b36 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Mon, 2 Nov 2020 18:29:15 +0530 Subject: [PATCH 3/8] Removed redundant method call. --- .../Molecules/DesignedComponents/List/ListStarRating.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift index 2e1ec8cb..1e904c8a 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift @@ -29,7 +29,6 @@ open override func updateView(_ size: CGFloat) { super.updateView(size) - stack.updateView(size) } //---------------------------------------------------- From 271167d50d6c8b94ec377f403260007fbc6fcee8 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 2 Nov 2020 14:41:23 -0500 Subject: [PATCH 4/8] Move to ready logic instead of page dependency --- .../MVMCoreAlertHandler+Extension.swift | 112 ++++++------------ MVMCoreUI/Alerts/MVMCoreAlertHandler.h | 3 - MVMCoreUI/Alerts/MVMCoreAlertHandler.m | 15 +-- MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h | 3 + MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m | 27 +++++ .../MVMCoreUITopAlertView+Extension.swift | 43 +------ 6 files changed, 71 insertions(+), 132 deletions(-) diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift index 309ea8f5..364ee6cb 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift @@ -8,88 +8,50 @@ import Foundation -// Temporary, until we can move page checking logic into isReady of topAlertOperation. -@objcMembers public class NotificationPagesOperation: Operation { - public let pages: [String] - - public init(with pages: [String]) { - self.pages = pages - } - - public override var isReady: Bool { - get { - return super.isReady && isCancelled - } - } -} - -// TODO: Move this type of logic into isReady for the top alert operation... then can remove this dependency operation. public extension MVMCoreAlertHandler { - /// Adds a page type dependency to the operation - @objc func addPagesDependency(to operation: MVMCoreTopAlertOperation) { - // This notification may only show for certain pages. - guard let pages = operation.topAlertObject.json?.optionalArrayForKey("pages") as? [String], - pages.count > 0 else { return } - let pagesOperation = NotificationPagesOperation(with: pages) - pageOperations.addOperation(pagesOperation) - operation.addDependency(pagesOperation) - } - - /// Updates the pages requirement for the operation - @objc func updatePages(for operation: MVMCoreTopAlertOperation, with topAlertObject: MVMCoreTopAlertObject) { - // Add new dependencies, remove old. - let previousPages = operation.dependencies.filter { $0 as? NotificationPagesOperation != nil } - addPagesDependency(to: operation) - for pageOperation in previousPages { - pageOperation.cancel() - operation.removeDependency(pageOperation) - } - } - - /// Handles page dependencies for all top alerts with the new pageType - @objc func handleAllPagesDependency(for pageType: String?) { - var currentOperation: MVMCoreTopAlertOperation? = nil - for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations { - // Handle the currently executing opration last to avoid race conditions. - guard !operation.isExecuting else { - currentOperation = operation - continue - } - handlePageDependency(for: operation, with: pageType) - } - if let operation = currentOperation { - handlePageDependency(for: operation, with: pageType) - } - } - - /// Updates the operation based on the page type and its dependencies. - @objc func handlePageDependency(for operation: MVMCoreTopAlertOperation, with pageType: String?) { - guard !operation.isCancelled else { return } - - if let pages = operation.topAlertObject.json?.optionalArrayForKey("pages") as? [String], - pages.count > 0, - (pageType == nil || !pages.contains(pageType!)) { - if let dependency = operation.dependencies.first(where: { $0.isFinished && ($0 as? NotificationPagesOperation)?.pages == pages }) { - // Re-add the dependency if it was previously cancelled. - let pagesOperation = NotificationPagesOperation(with: pages) - pageOperations.addOperation(pagesOperation) - operation.addDependency(pagesOperation) - operation.removeDependency(dependency) + /// Re-evaluates the queue operations + @objc func reevaluteQueue() { + var highestReadyOperation: MVMCoreTopAlertOperation? + var executingOperation: MVMCoreTopAlertOperation? + let sortedOperations = topAlertQueue.operations.sorted { $0.queuePriority.rawValue > $1.queuePriority.rawValue } + for case let operation as MVMCoreTopAlertOperation in sortedOperations { + guard !operation.isCancelled, + !operation.isFinished else { continue } + operation.refreshReady() + if operation.isReady, + highestReadyOperation == nil { + highestReadyOperation = operation } if operation.isExecuting { - // If the current running operation should not show on the current page, cancel it. If it's persistent, re-add it - operation.reAddAfterCancel = operation.topAlertObject.persistent - operation.cancel() + executingOperation = operation } } + guard let currentOperation = executingOperation else { return } - // Cancel any dependency if it contains the current page. - guard let pageType = pageType else { return } - for case let operation as NotificationPagesOperation in operation.dependencies { - if operation.pages.contains(pageType) { - operation.cancel() - } + // Cancel the executing operation if it is no longer ready to run. Re-add for later if it is persistent. + guard currentOperation.isReady else { + currentOperation.reAddAfterCancel = currentOperation.topAlertObject.persistent + currentOperation.cancel() + return + } + + // If the highest priority operation is not executing, and the executing operation is persistent, cancel it. + 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) + } + + /// When a detail page changes, check top alerts. + @objc private func viewControllerChanged(notification: Notification) { + reevaluteQueue() + } } diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler.h b/MVMCoreUI/Alerts/MVMCoreAlertHandler.h index f3b30efd..522c5740 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler.h +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler.h @@ -23,9 +23,6 @@ // An operation queue for top alerts @property (nonnull, strong, nonatomic) NSOperationQueue *topAlertQueue; -/// Stores any page dependencies for top alerts -@property (nonnull, strong, nonatomic) NSOperationQueue *pageOperations; - /// Returns the shared instance of this singleton + (nullable instancetype)sharedAlertHandler; diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler.m b/MVMCoreUI/Alerts/MVMCoreAlertHandler.m index 4e7be1f7..f65a1db0 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler.m +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler.m @@ -14,7 +14,7 @@ #import #import #import -#import +#import @interface MVMCoreAlertHandler () @@ -42,7 +42,7 @@ self.popupAlertQueue.maxConcurrentOperationCount = 1; self.topAlertQueue = [[NSOperationQueue alloc] init]; self.topAlertQueue.maxConcurrentOperationCount = 1; - self.pageOperations = [[NSOperationQueue alloc] init]; + [self registerWithNotificationCenter]; } return self; } @@ -173,16 +173,7 @@ }]; [self.topAlertQueue addOperation:alertOperation]; - - // If the current running operation is persistent and has a lower queue priority then the added operation, cancel it and re-add it. - for (MVMCoreTopAlertOperation *operation in self.topAlertQueue.operations) { - - if (operation.isExecuting && !operation.isCancelled && operation.topAlertObject.persistent && operation.queuePriority < alertOperation.queuePriority && alertOperation.isReady) { - operation.reAddAfterCancel = YES; - [operation cancel]; - break; - } - } + [self reevaluteQueue]; } - (void)showTopAlertWithObject:(nullable MVMCoreTopAlertObject *)topAlertObject { diff --git a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h index 73acec1e..86831e89 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h @@ -30,4 +30,7 @@ // Unpauses the operation, resuming any alert. - (void)unpause; +// NSOperationQueue uses KVO, this forces it to aknowledge changes +- (void)refreshReady; + @end diff --git a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m index bcf9515a..f721734a 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m @@ -10,6 +10,7 @@ #import "MVMCoreTopAlertObject.h" #import "MVMCoreAlertHandler.h" #import +#import @interface MVMCoreTopAlertOperation () { __block BOOL _paused; @@ -108,6 +109,27 @@ }); } +// Ensure the current page is supported for this top alert. +- (BOOL)isReady { + BOOL isReady = [super isReady]; + if (self.isCancelled || self.isFinished) { + return isReady; + } + + NSArray *pages = [self.topAlertObject.json array:@"pages"]; + if (pages.count == 0) { + return isReady; + } + + UIViewController *detailViewController = [[MVMCoreUISplitViewController mainSplitViewController] getCurrentDetailViewController]; + if (![detailViewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { + return isReady; + } + + NSString *pageType = ((UIViewController *)detailViewController).pageType; + return isReady && [pages containsObject:pageType]; +} + - (void)main { // Always check for cancellation before launching the task. @@ -232,6 +254,11 @@ } } +- (void)refreshReady { + [self willChangeValueForKey:@"isReady"]; + [self didChangeValueForKey:@"isReady"]; +} + #pragma mark - Delegate functions - (void)topAlertViewBeginAnimation { diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift index 9bceb57a..cb53b18a 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift @@ -18,7 +18,6 @@ public extension MVMCoreUITopAlertView { /// Registers with the notification center to know when json is updated. @objc func registerWithNotificationCenter() { NotificationCenter.default.addObserver(self, selector: #selector(responseJSONUpdated(notification:)), name: NSNotification.Name(rawValue: NotificationResponseLoaded), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil) } private func getDelegateObject() -> MVMCoreUIDelegateObject { @@ -42,42 +41,6 @@ public extension MVMCoreUITopAlertView { showTopAlert(with: model) } - /// When a detail page changes, check top alerts. - @objc private func viewControllerChanged(notification: Notification) { - guard let controller = MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol else { return } - MVMCoreAlertHandler.shared()?.handleAllPagesDependency(for: controller.pageType) - reevalutePriority() - } - - /// Re-evaluates the queue priority - private func reevalutePriority() { - guard let operations = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return } - var highestReadyOperation: Operation? - var executingOperation: Operation? - for operation in operations { - guard !operation.isCancelled, - !operation.isFinished else { - continue - } - if operation.isReady, - highestReadyOperation == nil || operation.queuePriority.rawValue > highestReadyOperation!.queuePriority.rawValue { - highestReadyOperation = operation - } - if operation.isExecuting { - executingOperation = operation - } - } - - // If the highest priority operation is not executing, and the executing operation is persistent, cancel it. - if let newOperation = highestReadyOperation, - let currentOperation = executingOperation as? MVMCoreTopAlertOperation, - currentOperation != newOperation, - currentOperation.topAlertObject.persistent { - currentOperation.reAddAfterCancel = true - currentOperation.cancel() - } - } - /// Decodes the json into a TopNotificationModel private func decodeTopNotification(with json: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?) -> TopNotificationModel? { do { @@ -95,8 +58,6 @@ public extension MVMCoreUITopAlertView { let object = model.createTopAlertObject() guard !checkAndUpdateExisting(with: object), let operation = MVMCoreTopAlertOperation(topAlertObject: object) else { return } - MVMCoreAlertHandler.shared()?.addPagesDependency(to: operation) - MVMCoreAlertHandler.shared()?.handlePageDependency(for: operation, with: (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType) MVMCoreAlertHandler.shared()?.add(operation) } @@ -107,9 +68,7 @@ public extension MVMCoreUITopAlertView { guard topAlertObject.json != nil, operation.topAlertObject.type == topAlertObject.type else { continue } operation.update(with: topAlertObject) - MVMCoreAlertHandler.shared()?.updatePages(for: operation, with: topAlertObject) - MVMCoreAlertHandler.shared()?.handlePageDependency(for: operation, with: (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType) - reevalutePriority() + MVMCoreAlertHandler.shared()?.reevaluteQueue() return true } return false From 987c178c35739a6eed0ed372e1fbbd2419879bb6 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 2 Nov 2020 19:03:23 -0500 Subject: [PATCH 5/8] Review changes for kvo cleanliness --- .../MVMCoreAlertHandler+Extension.swift | 29 +++++++--- MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h | 6 +-- MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m | 54 +++++++++++-------- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift index 364ee6cb..a2a8f665 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift @@ -12,19 +12,19 @@ public extension MVMCoreAlertHandler { /// Re-evaluates the queue operations @objc func reevaluteQueue() { - var highestReadyOperation: MVMCoreTopAlertOperation? + var higherPriorityOperationIsReady = false 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 { guard !operation.isCancelled, !operation.isFinished else { continue } - operation.refreshReady() - if operation.isReady, - highestReadyOperation == nil { - highestReadyOperation = operation - } + updatePageReadiness(for: operation, with: pageType) if operation.isExecuting { executingOperation = operation + } else if operation.isReady, + executingOperation == nil { + higherPriorityOperationIsReady = true } } guard let currentOperation = executingOperation else { return } @@ -37,8 +37,7 @@ public extension MVMCoreAlertHandler { } // If the highest priority operation is not executing, and the executing operation is persistent, cancel it. - if let newOperation = highestReadyOperation, - currentOperation != newOperation, + if higherPriorityOperationIsReady, currentOperation.topAlertObject.persistent { currentOperation.reAddAfterCancel = true currentOperation.cancel() @@ -50,6 +49,20 @@ public extension MVMCoreAlertHandler { NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil) } + /// 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 + } + 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/TopAlert/MVMCoreTopAlertOperation.h b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h index 86831e89..16f2ab8d 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h @@ -15,6 +15,9 @@ @property (readonly, getter=isPaused) BOOL paused; +/// A bool for if this top alert can be displayed. It is only ready if true. +@property (nonatomic, getter=isDisplayable) BOOL displayable; + @property (nonatomic) BOOL reAddAfterCancel; @property (nonnull, nonatomic, strong) MVMCoreTopAlertObject *topAlertObject; @@ -30,7 +33,4 @@ // Unpauses the operation, resuming any alert. - (void)unpause; -// NSOperationQueue uses KVO, this forces it to aknowledge changes -- (void)refreshReady; - @end diff --git a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m index f721734a..a59248ab 100644 --- a/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m +++ b/MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m @@ -16,6 +16,7 @@ __block BOOL _paused; __block BOOL _displayed; __block BOOL _animating; + __block BOOL _displayable; } @property (readwrite, getter=isPaused) BOOL paused; @@ -26,6 +27,7 @@ @property (strong, nonatomic) dispatch_queue_t pausedQueue; @property (strong, nonatomic) dispatch_queue_t displayedQueue; @property (strong, nonatomic) dispatch_queue_t animatingQueue; +@property (strong, nonatomic) dispatch_queue_t displayableQueue; @property (nonatomic, strong) dispatch_source_t timerSource; @@ -40,6 +42,8 @@ self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT); self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT); self.animatingQueue = dispatch_queue_create("animating", DISPATCH_QUEUE_CONCURRENT); + self.displayableQueue = dispatch_queue_create("displayable", DISPATCH_QUEUE_CONCURRENT); + self.displayable = YES; } return self; } @@ -109,25 +113,35 @@ }); } -// Ensure the current page is supported for this top alert. + +- (BOOL)isDisplayable { + __block BOOL isDisplayable; + dispatch_sync(self.displayableQueue, ^{ + isDisplayable = self->_displayable; + }); + return isDisplayable; +} + +- (void)setDisplayable:(BOOL)displayable { + if (displayable != self.isDisplayable) { + BOOL isReady = [super isReady]; + if (isReady) { + [self willChangeValueForKey:@"isReady"]; + } + dispatch_barrier_async(self.displayableQueue, ^{ + self->_displayable = displayable; + }); + if (isReady) { + [self didChangeValueForKey:@"isReady"]; + } + } +} + - (BOOL)isReady { - BOOL isReady = [super isReady]; - if (self.isCancelled || self.isFinished) { - return isReady; + if (self.isCancelled) { + return [super isReady]; } - - NSArray *pages = [self.topAlertObject.json array:@"pages"]; - if (pages.count == 0) { - return isReady; - } - - UIViewController *detailViewController = [[MVMCoreUISplitViewController mainSplitViewController] getCurrentDetailViewController]; - if (![detailViewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { - return isReady; - } - - NSString *pageType = ((UIViewController *)detailViewController).pageType; - return isReady && [pages containsObject:pageType]; + return [super isReady] && self.isDisplayable; } - (void)main { @@ -254,11 +268,6 @@ } } -- (void)refreshReady { - [self willChangeValueForKey:@"isReady"]; - [self didChangeValueForKey:@"isReady"]; -} - #pragma mark - Delegate functions - (void)topAlertViewBeginAnimation { @@ -278,6 +287,7 @@ copyObject.topAlertObject = self.topAlertObject; copyObject.paused = self.paused; copyObject.reAddAfterCancel = self.reAddAfterCancel; + copyObject.displayable = self.isDisplayable; copyObject.queuePriority = self.queuePriority; for (NSOperation *dependency in self.dependencies) { [copyObject addDependency:dependency]; From b90d761f251f32c92de1b73f38788853c8519493 Mon Sep 17 00:00:00 2001 From: Lekshmi S Date: Tue, 3 Nov 2020 11:07:35 +0530 Subject: [PATCH 6/8] Moved molecule to Miscellaneous group. --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++-- .../List/{ => Miscellaneous}/ListStarRating.swift | 4 ---- .../List/{ => Miscellaneous}/ListStarRatingModel.swift | 0 3 files changed, 2 insertions(+), 6 deletions(-) rename MVMCoreUI/Atomic/Molecules/DesignedComponents/List/{ => Miscellaneous}/ListStarRating.swift (96%) rename MVMCoreUI/Atomic/Molecules/DesignedComponents/List/{ => Miscellaneous}/ListStarRatingModel.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 7fd14012..3cc6f842 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1363,6 +1363,8 @@ children = ( AAE96FA125341F6A0037A989 /* ListStoreLocatorModel.swift */, AAE96FA425341F7D0037A989 /* ListStoreLocator.swift */, + AA7F47722541AD560015A2C1 /* ListStarRatingModel.swift */, + AA7F47752541AD6A0015A2C1 /* ListStarRating.swift */, ); path = Miscellaneous; sourceTree = ""; @@ -1547,8 +1549,6 @@ D22B38EB23F4E0AE00490EF6 /* LeftVariable */, AAB7EDEE246ADA1600E54929 /* ListProgressBarThinModel.swift */, AAB7EDF0246ADA2A00E54929 /* ListProgressBarThin.swift */, - AA7F47722541AD560015A2C1 /* ListStarRatingModel.swift */, - AA7F47752541AD6A0015A2C1 /* ListStarRating.swift */, ); path = List; sourceTree = ""; diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStarRating.swift similarity index 96% rename from MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift rename to MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStarRating.swift index 1e904c8a..b4bcf03d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRating.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStarRating.swift @@ -27,10 +27,6 @@ stack.restack() } - open override func updateView(_ size: CGFloat) { - super.updateView(size) - } - //---------------------------------------------------- // MARK: - Molecule //---------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStarRatingModel.swift similarity index 100% rename from MVMCoreUI/Atomic/Molecules/DesignedComponents/List/ListStarRatingModel.swift rename to MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStarRatingModel.swift From 4a47ec13c1bbe142919d9782fea0661c72cdd900 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 3 Nov 2020 15:55:43 -0500 Subject: [PATCH 7/8] Review Changes --- .../MVMCoreAlertHandler+Extension.swift | 52 ++++++++----------- MVMCoreUI/Alerts/MVMCoreAlertHandler.m | 5 +- MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.h | 3 ++ MVMCoreUI/TopAlert/MVMCoreTopAlertOperation.m | 13 +++++ .../MVMCoreUITopAlertView+Extension.swift | 2 + 5 files changed, 45 insertions(+), 30 deletions(-) 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 } From 6ce04350ad290d5ef88904bbbfc60aadd58437bc Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 3 Nov 2020 17:24:41 -0500 Subject: [PATCH 8/8] update for review --- MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift index 760e92c9..b0158e2d 100644 --- a/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift +++ b/MVMCoreUI/Alerts/MVMCoreAlertHandler+Extension.swift @@ -54,9 +54,12 @@ extension MVMCoreAlertHandler: MVMCorePresentationDelegateProtocol { 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) + topAlertQueue.operations.compactMap { + $0 as? MVMCoreTopAlertOperation + }.sorted { + $0.queuePriority.rawValue > $1.queuePriority.rawValue + }.forEach { + $0.updateDisplayable(byPageType: pageType) } reevaluteQueue() }