// // MBIMMessagesListOperation.m // kordophoned // // Created by James Magahern on 11/13/18. // Copyright © 2018 James Magahern. All rights reserved. // #import "MBIMMessagesListOperation.h" #import "MBIMHTTPUtilities.h" #import "IMMessageItem+Encoded.h" #import "MBIMErrorResponse.h" #import "IMCore_ClassDump.h" #define kDefaultMessagesLimit 75 @interface IMChat (MBIMSafeMessagesLoading) - (void)load:(NSUInteger)number messagesBeforeGUID:(NSString *)beforeMessageGUID; - (void)load:(NSUInteger)number messagesAfterGUID:(NSString *)afterMessageGUID; @end @implementation MBIMMessagesListOperation + (void)load { [super load]; } + (NSString *)endpointName { return @"messages"; } - (void)main { __block NSObject *response = nil; do { // Required parameters NSString *guid = [self valueForQueryItemWithName:@"guid"]; // Optional NSString *limitValue = [self valueForQueryItemWithName:@"limit"]; NSDate *beforeDate = nil; NSString *beforeDateValue = [self valueForQueryItemWithName:@"beforeDate"]; if (beforeDateValue) { beforeDate = [beforeDateValue ISO8601Date]; if (!beforeDate) { response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"Unable to decode ISO8601 beforeDate value"]; break; } } NSString *beforeMessageGUID = [self valueForQueryItemWithName:@"beforeMessageGUID"]; NSString *afterMessageGUID = [self valueForQueryItemWithName:@"afterMessageGUID"]; if (beforeMessageGUID && afterMessageGUID) { response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"Cannot provide both beforeMessageGUID and afterMessageGUID params."]; break; } if (!guid) { response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"No GUID provided."]; break; } __block NSMutableArray *messages = [NSMutableArray array]; dispatch_sync([[self class] sharedIMAccessQueue], ^{ IMChat *chat = [[IMChatRegistry sharedInstance] existingChatWithGUID:guid]; if (!chat) { MBIMLogInfo(@"Chat with guid: %@ not found", guid); response = [[HTTPErrorResponse alloc] initWithErrorCode:500]; } else { // Load messages // (Must be done on main queue for some reason) dispatch_sync(dispatch_get_main_queue(), ^{ NSUInteger limit = kDefaultMessagesLimit; if (limitValue) { limit = [limitValue integerValue]; } if (beforeMessageGUID) { [chat load:limit messagesBeforeGUID:beforeMessageGUID]; } else if (afterMessageGUID) { [chat load:limit messagesAfterGUID:afterMessageGUID]; } else { [chat loadMessagesBeforeDate:beforeDate limit:limit loadImmediately:YES]; } IMMessage *beforeMessage = beforeMessageGUID ? [chat messageForGUID:beforeMessageGUID] : nil; IMMessage *afterMessage = afterMessageGUID ? [chat messageForGUID:afterMessageGUID] : nil; [[chat chatItems] enumerateMessagesWithOptions:0 usingBlock:^(IMMessage *message, BOOL *stop) { BOOL includeMessage = YES; NSDate *messageDate = [message time]; if (beforeMessage && [[beforeMessage time] compare:messageDate] != NSOrderedDescending) { includeMessage = NO; } if (afterMessage && [[afterMessage time] compare:messageDate] != NSOrderedAscending) { includeMessage = NO; } if (includeMessage) { NSDictionary *messageDict = [message mbim_dictionaryRepresentation]; [messages addObject:messageDict]; } }]; }); } }); response = [MBIMJSONDataResponse responseWithJSONObject:messages]; } while (0); self.serverCompletionBlock(response); } @end @implementation IMChat (MBIMSafeMessagesLoading) - (id)_safe_loadMessagesBeforeAndAfterGUID:(NSString *)messagesGUID numberOfMessagesToLoadBeforeGUID:(NSUInteger)limitBefore numberOfMessagesToLoadAfterGUID:(NSUInteger)limitAfter loadImmediately:(BOOL)loadImmediately { if ([self respondsToSelector:@selector(loadMessagesBeforeAndAfterGUID: numberOfMessagesToLoadBeforeGUID: numberOfMessagesToLoadAfterGUID: loadImmediately:threadIdentifier:)]) { return [self loadMessagesBeforeAndAfterGUID:messagesGUID numberOfMessagesToLoadBeforeGUID:limitBefore numberOfMessagesToLoadAfterGUID:limitAfter loadImmediately:YES threadIdentifier:nil]; } else { return [self loadMessagesBeforeAndAfterGUID:messagesGUID numberOfMessagesToLoadBeforeGUID:limitBefore numberOfMessagesToLoadAfterGUID:limitAfter loadImmediately:YES]; } } - (void)load:(NSUInteger)number messagesBeforeGUID:(NSString *)beforeMessageGUID { [self _safe_loadMessagesBeforeAndAfterGUID:beforeMessageGUID numberOfMessagesToLoadBeforeGUID:number numberOfMessagesToLoadAfterGUID:0 loadImmediately:YES]; } - (void)load:(NSUInteger)number messagesAfterGUID:(NSString *)afterMessageGUID { [self _safe_loadMessagesBeforeAndAfterGUID:afterMessageGUID numberOfMessagesToLoadBeforeGUID:0 numberOfMessagesToLoadAfterGUID:number loadImmediately:YES]; } @end