//// //// Copyright (c) 2018 Open Whisper Systems. All rights reserved. //// // //#import "ThreadViewHelper.h" //#import //#import //#import //#import //#import //#import //#import //#import //#import // //NS_ASSUME_NONNULL_BEGIN // //@interface ThreadViewHelper () // //@property (nonatomic) YapDatabaseConnection *uiDatabaseConnection; //@property (nonatomic) YapDatabaseViewMappings *threadMappings; //@property (nonatomic) BOOL shouldObserveDBModifications; // //@end // //#pragma mark - // //@implementation ThreadViewHelper // //- (instancetype)init //{ // self = [super init]; // if (!self) { // return self; // } // // [self initializeMapping]; // // return self; //} // //- (void)dealloc //{ // [[NSNotificationCenter defaultCenter] removeObserver:self]; //} // //- (void)initializeMapping //{ // OWSAssertIsOnMainThread(); // // NSString *grouping = TSInboxGroup; // // self.threadMappings = // [[YapDatabaseViewMappings alloc] initWithGroups:@[ grouping ] view:TSThreadDatabaseViewExtensionName]; // [self.threadMappings setIsReversed:YES forGroup:grouping]; // // self.uiDatabaseConnection = [OWSPrimaryStorage.sharedManager newDatabaseConnection]; // [self.uiDatabaseConnection beginLongLivedReadTransaction]; // // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(applicationDidBecomeActive:) // name:OWSApplicationDidBecomeActiveNotification // object:nil]; // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(applicationWillResignActive:) // name:OWSApplicationWillResignActiveNotification // object:nil]; // // [self updateShouldObserveDBModifications]; //} // //- (void)applicationDidBecomeActive:(NSNotification *)notification //{ // [self updateShouldObserveDBModifications]; //} // //- (void)applicationWillResignActive:(NSNotification *)notification //{ // [self updateShouldObserveDBModifications]; //} // //- (void)updateShouldObserveDBModifications //{ // self.shouldObserveDBModifications = CurrentAppContext().isAppForegroundAndActive; //} // //// Don't observe database change notifications when the app is in the background. //// //// Instead, rebuild model state when app enters foreground. //- (void)setShouldObserveDBModifications:(BOOL)shouldObserveDBModifications //{ // if (_shouldObserveDBModifications == shouldObserveDBModifications) { // return; // } // // _shouldObserveDBModifications = shouldObserveDBModifications; // // if (shouldObserveDBModifications) { // [self.uiDatabaseConnection beginLongLivedReadTransaction]; // [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { // [self.threadMappings updateWithTransaction:transaction]; // }]; // [self updateThreads]; // [self.delegate threadListDidChange]; // // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(yapDatabaseModified:) // name:YapDatabaseModifiedNotification // object:OWSPrimaryStorage.sharedManager.dbNotificationObject]; // [[NSNotificationCenter defaultCenter] addObserver:self // selector:@selector(yapDatabaseModifiedExternally:) // name:YapDatabaseModifiedExternallyNotification // object:nil]; // } else { // [[NSNotificationCenter defaultCenter] removeObserver:self // name:YapDatabaseModifiedNotification // object:OWSPrimaryStorage.sharedManager.dbNotificationObject]; // [[NSNotificationCenter defaultCenter] removeObserver:self // name:YapDatabaseModifiedExternallyNotification // object:nil]; // } //} // //#pragma mark - Database // //- (YapDatabaseConnection *)uiDatabaseConnection //{ // OWSAssertIsOnMainThread(); // // return _uiDatabaseConnection; //} // //- (void)yapDatabaseModifiedExternally:(NSNotification *)notification //{ // OWSAssertIsOnMainThread(); // // OWSLogVerbose(@""); // // if (self.shouldObserveDBModifications) { // // External database modifications can't be converted into incremental updates, // // so rebuild everything. This is expensive and usually isn't necessary, but // // there's no alternative. // // // // We don't need to do this if we're not observing db modifications since we'll // // do it when we resume. // [self.uiDatabaseConnection beginLongLivedReadTransaction]; // [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { // [self.threadMappings updateWithTransaction:transaction]; // }]; // // [self updateThreads]; // [self.delegate threadListDidChange]; // } //} // //- (void)yapDatabaseModified:(NSNotification *)notification //{ // OWSAssertIsOnMainThread(); // // OWSLogVerbose(@""); // // NSArray *notifications = [self.uiDatabaseConnection beginLongLivedReadTransaction]; // // if (! // [[self.uiDatabaseConnection ext:TSMessageDatabaseViewExtensionName] hasChangesForNotifications:notifications]) { // [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { // [self.threadMappings updateWithTransaction:transaction]; // }]; // return; // } // // NSArray *sectionChanges = nil; // NSArray *rowChanges = nil; // [[self.uiDatabaseConnection ext:TSThreadDatabaseViewExtensionName] getSectionChanges:§ionChanges // rowChanges:&rowChanges // forNotifications:notifications // withMappings:self.threadMappings]; // // if (sectionChanges.count == 0 && rowChanges.count == 0) { // // Ignore irrelevant modifications. // return; // } // // [self updateThreads]; // // [self.delegate threadListDidChange]; //} // //- (void)updateThreads //{ // OWSAssertIsOnMainThread(); // // NSMutableArray *threads = [NSMutableArray new]; // [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { // NSUInteger numberOfSections = [self.threadMappings numberOfSections]; // OWSAssertDebug(numberOfSections == 1); // for (NSUInteger section = 0; section < numberOfSections; section++) { // NSUInteger numberOfItems = [self.threadMappings numberOfItemsInSection:section]; // for (NSUInteger item = 0; item < numberOfItems; item++) { // TSThread *thread = [[transaction extension:TSThreadDatabaseViewExtensionName] // objectAtIndexPath:[NSIndexPath indexPathForItem:(NSInteger)item inSection:(NSInteger)section] // withMappings:self.threadMappings]; // if (!thread.shouldBeVisible) { continue; } // if ([thread isKindOfClass:TSContactThread.class]) { // NSString *publicKey = ((TSContactThread *)thread).contactSessionID; // if ([[LKStorage.shared getContactWithSessionID:publicKey] name] == nil) { continue; } // [threads addObject:thread]; // } else { // [threads addObject:thread]; // } // } // } // }]; // // _threads = [threads copy]; //} // //@end // //NS_ASSUME_NONNULL_END