mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			221 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			221 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Objective-C
		
	
| ////
 | |
| ////  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | |
| ////
 | |
| //
 | |
| //#import "ThreadViewHelper.h"
 | |
| //#import <SessionUtilitiesKit/AppContext.h>
 | |
| //#import <SessionMessagingKit/OWSPrimaryStorage.h>
 | |
| //#import <SessionMessagingKit/TSDatabaseView.h>
 | |
| //#import <SessionMessagingKit/TSThread.h>
 | |
| //#import <SessionMessagingKit/TSContactThread.h>
 | |
| //#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
 | |
| //#import <YapDatabase/YapDatabase.h>
 | |
| //#import <YapDatabase/YapDatabaseViewChange.h>
 | |
| //#import <YapDatabase/YapDatabaseViewConnection.h>
 | |
| //
 | |
| //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<TSThread *> *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
 |