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.
		
		
		
		
		
			
		
			
	
	
		
			211 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Matlab
		
	
		
		
			
		
	
	
			211 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Matlab
		
	
| 
								 
											5 years ago
										 
									 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#import "OWSMediaGalleryFinder.h"
							 | 
						||
| 
								 | 
							
								#import "OWSStorage.h"
							 | 
						||
| 
								 | 
							
								#import "TSAttachmentStream.h"
							 | 
						||
| 
								 | 
							
								#import "TSMessage.h"
							 | 
						||
| 
								 | 
							
								#import "TSThread.h"
							 | 
						||
| 
								 | 
							
								#import <YapDatabase/YapDatabaseAutoView.h>
							 | 
						||
| 
								 | 
							
								#import <YapDatabase/YapDatabaseTransaction.h>
							 | 
						||
| 
								 | 
							
								#import <YapDatabase/YapDatabaseViewTypes.h>
							 | 
						||
| 
								 | 
							
								#import <YapDatabase/YapWhitelistBlacklist.h>
							 | 
						||
| 
								 | 
							
								#import <SessionProtocolKit/SessionProtocolKit.h>
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								#import "TSAttachment.h"
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								NS_ASSUME_NONNULL_BEGIN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static NSString *const OWSMediaGalleryFinderExtensionName = @"OWSMediaGalleryFinderExtensionName";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@interface OWSMediaGalleryFinder ()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@property (nonatomic, readonly) TSThread *thread;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@implementation OWSMediaGalleryFinder
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (instancetype)initWithThread:(TSThread *)thread
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    self = [super init];
							 | 
						||
| 
								 | 
							
								    if (!self) {
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _thread = thread;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return self;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma mark - Public Finder Methods
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (NSUInteger)mediaCountWithTransaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self galleryExtensionWithTransaction:transaction] numberOfItemsInGroup:self.mediaGroup];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (nullable NSNumber *)mediaIndexForAttachment:(TSAttachment *)attachment
							 | 
						||
| 
								 | 
							
								                                   transaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    NSString *groupId;
							 | 
						||
| 
								 | 
							
								    NSUInteger index;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOL wasFound = [[self galleryExtensionWithTransaction:transaction] getGroup:&groupId
							 | 
						||
| 
								 | 
							
								                                                                           index:&index
							 | 
						||
| 
								 | 
							
								                                                                          forKey:attachment.uniqueId
							 | 
						||
| 
								 | 
							
								                                                                    inCollection:[TSAttachment collection]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!wasFound) {
							 | 
						||
| 
								 | 
							
								        return nil;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return @(index);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (nullable TSAttachment *)oldestMediaAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self galleryExtensionWithTransaction:transaction] firstObjectInGroup:self.mediaGroup];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (nullable TSAttachment *)mostRecentMediaAttachmentWithTransaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self galleryExtensionWithTransaction:transaction] lastObjectInGroup:self.mediaGroup];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (void)enumerateMediaAttachmentsWithRange:(NSRange)range
							 | 
						||
| 
								 | 
							
								                               transaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								                                     block:(void (^)(TSAttachment *))attachmentBlock
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    [[self galleryExtensionWithTransaction:transaction]
							 | 
						||
| 
								 | 
							
								        enumerateKeysAndObjectsInGroup:self.mediaGroup
							 | 
						||
| 
								 | 
							
								                           withOptions:0
							 | 
						||
| 
								 | 
							
								                                 range:range
							 | 
						||
| 
								 | 
							
								                            usingBlock:^(NSString *_Nonnull collection,
							 | 
						||
| 
								 | 
							
								                                NSString *_Nonnull key,
							 | 
						||
| 
								 | 
							
								                                id _Nonnull object,
							 | 
						||
| 
								 | 
							
								                                NSUInteger index,
							 | 
						||
| 
								 | 
							
								                                BOOL *_Nonnull stop) {
							 | 
						||
| 
								 | 
							
								                                attachmentBlock((TSAttachment *)object);
							 | 
						||
| 
								 | 
							
								                            }];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (BOOL)hasMediaChangesInNotifications:(NSArray<NSNotification *> *)notifications
							 | 
						||
| 
								 | 
							
								                          dbConnection:(YapDatabaseConnection *)dbConnection
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    YapDatabaseAutoViewConnection *extConnection = [dbConnection ext:OWSMediaGalleryFinderExtensionName];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return [extConnection hasChangesForGroup:self.mediaGroup inNotifications:notifications];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma mark - Util
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (YapDatabaseAutoViewTransaction *)galleryExtensionWithTransaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    YapDatabaseAutoViewTransaction *extension = [transaction extension:OWSMediaGalleryFinderExtensionName];
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								    return extension;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (NSString *)mediaGroupWithThreadId:(NSString *)threadId
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [NSString stringWithFormat:@"%@-media", threadId];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (NSString *)mediaGroup
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self class] mediaGroupWithThreadId:self.thread.uniqueId];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma mark - Extension registration
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (NSString *)databaseExtensionName
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return OWSMediaGalleryFinderExtensionName;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (void)asyncRegisterDatabaseExtensionsWithPrimaryStorage:(OWSStorage *)storage
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    [storage asyncRegisterExtension:[self mediaGalleryDatabaseExtension]
							 | 
						||
| 
								 | 
							
								                           withName:OWSMediaGalleryFinderExtensionName];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (YapDatabaseAutoView *)mediaGalleryDatabaseExtension
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    YapDatabaseViewSorting *sorting =
							 | 
						||
| 
								 | 
							
								        [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *_Nonnull transaction,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull group,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull collection1,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull key1,
							 | 
						||
| 
								 | 
							
								            id _Nonnull object1,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull collection2,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull key2,
							 | 
						||
| 
								 | 
							
								            id _Nonnull object2) {
							 | 
						||
| 
								 | 
							
								            if (![object1 isKindOfClass:[TSAttachment class]]) {
							 | 
						||
| 
								 | 
							
								                return NSOrderedSame;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            TSAttachment *attachment1 = (TSAttachment *)object1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (![object2 isKindOfClass:[TSAttachment class]]) {
							 | 
						||
| 
								 | 
							
								                return NSOrderedSame;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            TSAttachment *attachment2 = (TSAttachment *)object2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TSMessage *_Nullable message1 = [attachment1 fetchAlbumMessageWithTransaction:transaction];
							 | 
						||
| 
								 | 
							
								            TSMessage *_Nullable message2 = [attachment2 fetchAlbumMessageWithTransaction:transaction];
							 | 
						||
| 
								 | 
							
								            if (message1 == nil || message2 == nil) {
							 | 
						||
| 
								 | 
							
								                return NSOrderedSame;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ([message1.uniqueId isEqualToString:message2.uniqueId]) {
							 | 
						||
| 
								 | 
							
								                NSUInteger index1 = [message1.attachmentIds indexOfObject:attachment1.uniqueId];
							 | 
						||
| 
								 | 
							
								                NSUInteger index2 = [message1.attachmentIds indexOfObject:attachment2.uniqueId];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (index1 == NSNotFound || index2 == NSNotFound) {
							 | 
						||
| 
								 | 
							
								                    return NSOrderedSame;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                return [@(index1) compare:@(index2)];
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                return [message1 compareForSorting:message2];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    YapDatabaseViewGrouping *grouping =
							 | 
						||
| 
								 | 
							
								        [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull collection,
							 | 
						||
| 
								 | 
							
								            NSString *_Nonnull key,
							 | 
						||
| 
								 | 
							
								            id _Nonnull object) {
							 | 
						||
| 
								 | 
							
								            // Don't include nil or not yet downloaded attachments.
							 | 
						||
| 
								 | 
							
								            if (![object isKindOfClass:[TSAttachmentStream class]]) {
							 | 
						||
| 
								 | 
							
								                return nil;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TSAttachmentStream *attachment = (TSAttachmentStream *)object;
							 | 
						||
| 
								 | 
							
								            if (attachment.albumMessageId == nil) {
							 | 
						||
| 
								 | 
							
								                return nil;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!attachment.isValidVisualMedia) {
							 | 
						||
| 
								 | 
							
								                return nil;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TSMessage *message = [attachment fetchAlbumMessageWithTransaction:transaction];
							 | 
						||
| 
								 | 
							
								            if (message == nil) {
							 | 
						||
| 
								 | 
							
								                return nil;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return [self mediaGroupWithThreadId:message.uniqueThreadId];
							 | 
						||
| 
								 | 
							
								        }];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    YapDatabaseViewOptions *options = [YapDatabaseViewOptions new];
							 | 
						||
| 
								 | 
							
								    options.allowedCollections =
							 | 
						||
| 
								 | 
							
								        [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:TSAttachment.collection]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return [[YapDatabaseAutoView alloc] initWithGrouping:grouping sorting:sorting versionTag:@"4" options:options];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								NS_ASSUME_NONNULL_END
							 |