diff --git a/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler+Extension.swift b/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler+Extension.swift index c0d2cd8..9ee8ff9 100644 --- a/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler+Extension.swift +++ b/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler+Extension.swift @@ -64,26 +64,14 @@ public extension MVMCoreAlertHandler { } } - /// Checks for existing same top alert objects and update it. - func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool { + /// Checks for existing top alert object of same type and updates it. Only happens for molecular top alerts. Returns true if we updated. + @objc func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool { + // ToDo: do pages and priority. for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations { guard topAlertObject.json != nil, operation.topAlertObject.type == topAlertObject.type else { continue } - guard !operation.isCancelled else { - // old is already cancelled, add new - operation.reAddAfterCancel = false - return false - } - guard operation.isExecuting else { - // not currently executing... cancel old, add new - operation.cancel() - return false - } - // update existing and view - // how to update dismiss time? - // how to update view? what if molecule is different? - - + operation.update(with: topAlertObject) + return true } return false } diff --git a/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler.m b/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler.m index 1e64663..1dab33b 100644 --- a/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler.m +++ b/MVMCore/MVMCore/AlertHandling/MVMCoreAlertHandler.m @@ -160,7 +160,8 @@ - (void)showTopAlertWithObject:(nullable MVMCoreTopAlertObject *)topAlertObject { - if (topAlertObject) { + // Check if we need to add a new operation. + if (topAlertObject && ![self checkAndUpdateExistingWith:topAlertObject]) { __block MVMCoreTopAlertOperation *alertOperation = [[MVMCoreTopAlertOperation alloc] initWithTopAlertObject:topAlertObject]; __weak typeof(self) weakSelf = self; diff --git a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.h b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.h index 82cba7d..6dadc89 100644 --- a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.h +++ b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.h @@ -21,6 +21,9 @@ - (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject; +/// Updates the operation with a new object +- (void)updateWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject; + // Pauses the operation. Temporarily removes any alert. - (void)pause; diff --git a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.m b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.m index ccf7545..baacb3c 100644 --- a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.m +++ b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertOperation.m @@ -27,6 +27,8 @@ @property (strong, nonatomic) dispatch_queue_t displayedQueue; @property (strong, nonatomic) dispatch_queue_t animatingQueue; +@property (nonatomic, strong) dispatch_source_t timerSource; + @end @implementation MVMCoreTopAlertOperation @@ -53,6 +55,16 @@ return self; } +- (void)updateWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject { + self.topAlertObject = topAlertObject; + self.queuePriority = [[MVMCoreObject sharedInstance].globalTopAlertDelegate priorityForTopAlertByObject:topAlertObject]; + if (self.isExecuting && !self.isCancelled && !self.isPaused) { + [self updateDismissTimer]; + UIView *topAlertView = [[MVMCoreObject sharedInstance].globalTopAlertDelegate getTopAlertView]; + [topAlertView updateTopAlertWith:topAlertObject]; + } +} + - (BOOL)isPaused { __block BOOL isPaused; dispatch_sync(self.pausedQueue, ^{ @@ -126,23 +138,8 @@ // Paused, dismiss for the time being if persistent. [self dismissAlertView:!self.topAlertObject.persistent forceful:YES]; - } else if (!self.topAlertObject.persistent) { - - // Set timer to dismiss top alert if it's not persistent (or it's survival mode and not short bar). - NSInteger dismissTime; - if (self.topAlertObject.topAlertDismissTime > 0) { - dismissTime = self.topAlertObject.topAlertDismissTime; - } else { - dismissTime = TopAlertDismissTime; - } - - __weak typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(dismissTime * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - if (weakSelf.isFinished || [weakSelf checkAndHandleForCancellation]) { - return; - } - [weakSelf dismissAlertView:YES forceful:NO]; - }); + } else { + [self updateDismissTimer]; } }]; } @@ -152,6 +149,37 @@ } } +/// Updates the timer to dismiss the top alert. +- (void)updateDismissTimer { + if (self.timerSource) { + dispatch_source_cancel(self.timerSource); + } + if (self.topAlertObject.persistent) { + return; + } + self.timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); + if (!self.timerSource) { + // Log error + return; + } + NSInteger dismissTime; + if (self.topAlertObject.topAlertDismissTime > 0) { + dismissTime = self.topAlertObject.topAlertDismissTime; + } else { + dismissTime = TopAlertDismissTime; + } + + __weak typeof(self) weakSelf = self; + dispatch_source_set_timer(self.timerSource, dispatch_time(DISPATCH_TIME_NOW, dismissTime * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, (1ull * NSEC_PER_SEC) / 10); + dispatch_source_set_event_handler(self.timerSource, ^{ + if (weakSelf.isFinished || [weakSelf checkAndHandleForCancellation]) { + return; + } + [weakSelf dismissAlertView:YES forceful:NO]; + }); + dispatch_resume(self.timerSource); +} + - (void)cancel { [super cancel]; @@ -167,7 +195,9 @@ } - (void)dismissAlertView:(BOOL)andFinish forceful:(BOOL)forceful { - + if (self.timerSource) { + dispatch_source_cancel(self.timerSource); + } if (self.isDisplayed && !self.isAnimating) { // Dismisses. diff --git a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertViewProtocol.h b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertViewProtocol.h index f667037..2778971 100644 --- a/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertViewProtocol.h +++ b/MVMCore/MVMCore/AlertHandling/MVMCoreTopAlertViewProtocol.h @@ -22,4 +22,7 @@ // Collapses the notification if it has a short top message. Otherwise removes notification. - (void)collapseNotification; +/// Updates the existing top alert with the new object +- (void)updateTopAlertWith:(nullable MVMCoreTopAlertObject *)topAlertObject; + @end