new timers

top alert update function
This commit is contained in:
Pfeil, Scott Robert 2020-10-15 16:36:29 -04:00
parent e9abe2121a
commit d7ea41cbcb
5 changed files with 61 additions and 36 deletions

View File

@ -64,26 +64,14 @@ public extension MVMCoreAlertHandler {
} }
} }
/// Checks for existing same top alert objects and update it. /// Checks for existing top alert object of same type and updates it. Only happens for molecular top alerts. Returns true if we updated.
func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool { @objc func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool {
// ToDo: do pages and priority.
for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations { for case let operation as MVMCoreTopAlertOperation in topAlertQueue.operations {
guard topAlertObject.json != nil, guard topAlertObject.json != nil,
operation.topAlertObject.type == topAlertObject.type else { continue } operation.topAlertObject.type == topAlertObject.type else { continue }
guard !operation.isCancelled else { operation.update(with: topAlertObject)
// old is already cancelled, add new return true
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?
} }
return false return false
} }

View File

@ -160,7 +160,8 @@
- (void)showTopAlertWithObject:(nullable MVMCoreTopAlertObject *)topAlertObject { - (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]; __block MVMCoreTopAlertOperation *alertOperation = [[MVMCoreTopAlertOperation alloc] initWithTopAlertObject:topAlertObject];
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;

View File

@ -21,6 +21,9 @@
- (nullable instancetype)initWithTopAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject; - (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. // Pauses the operation. Temporarily removes any alert.
- (void)pause; - (void)pause;

View File

@ -27,6 +27,8 @@
@property (strong, nonatomic) dispatch_queue_t displayedQueue; @property (strong, nonatomic) dispatch_queue_t displayedQueue;
@property (strong, nonatomic) dispatch_queue_t animatingQueue; @property (strong, nonatomic) dispatch_queue_t animatingQueue;
@property (nonatomic, strong) dispatch_source_t timerSource;
@end @end
@implementation MVMCoreTopAlertOperation @implementation MVMCoreTopAlertOperation
@ -53,6 +55,16 @@
return self; 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 <MVMCoreTopAlertViewProtocol>*topAlertView = [[MVMCoreObject sharedInstance].globalTopAlertDelegate getTopAlertView];
[topAlertView updateTopAlertWith:topAlertObject];
}
}
- (BOOL)isPaused { - (BOOL)isPaused {
__block BOOL isPaused; __block BOOL isPaused;
dispatch_sync(self.pausedQueue, ^{ dispatch_sync(self.pausedQueue, ^{
@ -126,9 +138,30 @@
// Paused, dismiss for the time being if persistent. // Paused, dismiss for the time being if persistent.
[self dismissAlertView:!self.topAlertObject.persistent forceful:YES]; [self dismissAlertView:!self.topAlertObject.persistent forceful:YES];
} else if (!self.topAlertObject.persistent) { } else {
[self updateDismissTimer];
}
}];
}
} else {
[self pause];
}
}
}
// Set timer to dismiss top alert if it's not persistent (or it's survival mode and not short bar). /// 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; NSInteger dismissTime;
if (self.topAlertObject.topAlertDismissTime > 0) { if (self.topAlertObject.topAlertDismissTime > 0) {
dismissTime = self.topAlertObject.topAlertDismissTime; dismissTime = self.topAlertObject.topAlertDismissTime;
@ -137,19 +170,14 @@
} }
__weak typeof(self) weakSelf = self; __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), ^{ 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]) { if (weakSelf.isFinished || [weakSelf checkAndHandleForCancellation]) {
return; return;
} }
[weakSelf dismissAlertView:YES forceful:NO]; [weakSelf dismissAlertView:YES forceful:NO];
}); });
} dispatch_resume(self.timerSource);
}];
}
} else {
[self pause];
}
}
} }
- (void)cancel { - (void)cancel {
@ -167,7 +195,9 @@
} }
- (void)dismissAlertView:(BOOL)andFinish forceful:(BOOL)forceful { - (void)dismissAlertView:(BOOL)andFinish forceful:(BOOL)forceful {
if (self.timerSource) {
dispatch_source_cancel(self.timerSource);
}
if (self.isDisplayed && !self.isAnimating) { if (self.isDisplayed && !self.isAnimating) {
// Dismisses. // Dismisses.

View File

@ -22,4 +22,7 @@
// Collapses the notification if it has a short top message. Otherwise removes notification. // Collapses the notification if it has a short top message. Otherwise removes notification.
- (void)collapseNotification; - (void)collapseNotification;
/// Updates the existing top alert with the new object
- (void)updateTopAlertWith:(nullable MVMCoreTopAlertObject *)topAlertObject;
@end @end